Giới thiệu
Nâng cấp game engine giữa chừng dự án là một trong những quyết định thường nhật đáng sợ nhất trong phát triển game. Phiên bản Godot mới có thể sửa đúng cái lỗi đang chặn bạn — nhưng cũng có thể âm thầm làm hỏng một scene mà bạn đã dồn sáu tháng công sức vào đó. Chính vì vậy, các nhà phát triển giàu kinh nghiệm trong cộng đồng Godot coi việc nâng cấp phiên bản là một quyết định về rủi ro, chứ không phải một công việc thường lệ.
Hướng dẫn này không cổ vũ kiểu "lúc nào cũng nên nâng cấp". Đây là một checklist quản lý rủi ro cho việc chuyển đổi giữa các phiên bản Godot 4.x: cách quyết định có nên nâng cấp hay không, cách chuẩn bị để có thể rút lui an toàn, những gì được biết là sẽ hỏng giữa các phiên bản, và — quan trọng nhất — cách thực sự xác minh rằng không có gì bị hỏng.
Có nên nâng cấp hay không?
Trước khi động vào bất cứ thứ gì, hãy trả lời câu hỏi này một cách trung thực. Nâng cấp có chi phí thật (công sức chuyển đổi + kiểm thử lại), nên lợi ích cũng phải thật tương xứng.
Nên nâng cấp nếu…
- Một lỗi đã được sửa ở bản mới đang chặn bạn. Nếu vấn đề của bạn đã được khắc phục trong bản phát hành mới hơn, nâng cấp thường rẻ hơn là mãi mãi phải dùng cách vòng tránh.
- Một tính năng mới mang lại lợi ích thực chất cho game của bạn. Không phải kiểu "nghe có vẻ hay" — mà là thứ giúp bạn tiết kiệm thời gian phát triển thật sự hoặc mở khóa một thiết kế bạn cần.
- Lộ trình phát triển của bạn còn dài. Nếu dự án sẽ kéo dài nhiều năm, các bước nhảy nhỏ và thường xuyên (mỗi lần một phiên bản minor) an toàn hơn nhiều so với một cú nhảy khổng lồ ở cuối. Khoảng cách chỉ ngày càng lớn thêm.
Đừng nâng cấp nếu…
- Bạn sắp phát hành. Vài tuần trước khi ra mắt là thời điểm tồi tệ nhất để đưa vào các thay đổi ở cấp engine. Phát hành trước, nâng cấp sau.
- Bạn cần C# + xuất bản Web. Xuất bản Web cho dự án C# vẫn chưa khả dụng trong Godot 4.x (được theo dõi tại godot#70796). Nếu bạn đang dựa vào tính năng này ở 3.x, chuyển sang 4.x sẽ khiến bạn mất nó.
- Bạn nhắm đến phần cứng cũ. Godot 3.x chạy được trên GPU thuộc thế hệ OpenGL 2; renderer Compatibility của Godot 4 yêu cầu OpenGL 3.3 / WebGL 2. Nếu người chơi của bạn dùng máy cũ, 3.x thực sự có thể là engine phù hợp.
- Các addon quan trọng chưa được cập nhật. Nếu một plugin mà dự án của bạn phụ thuộc chưa hỗ trợ phiên bản mới, bạn sẽ phải gánh thêm vấn đề chuyển đổi của nó bên cạnh vấn đề của chính mình.
Nguyên tắc chung: nâng cấp khi một lợi ích cụ thể vượt trội chi phí cụ thể mà bạn đã ước lượng — chứ không phải chỉ vì có phiên bản mới ra đời.
Trước khi nâng cấp — Checklist chuẩn bị
Mỗi bước ở đây tồn tại để nếu việc nâng cấp thất bại, bạn chỉ mất một buổi chiều, chứ không phải cả dự án.
- Commit toàn bộ và tạo một branch dành riêng cho việc nâng cấp. Đừng bao giờ nâng cấp trên bản sao duy nhất của dự án. Một branch riêng (hoặc một bản sao đầy đủ của thư mục nếu bạn không dùng git) nghĩa là việc quay lui chỉ tốn một lệnh, chứ không phải một chiến dịch cứu hộ.
- Ghi lại chính xác phiên bản hiện tại của bạn (ví dụ: bản build 4.x.y nào, bản thường hay bản .NET). Bạn sẽ cần thông tin này nếu phải quay lại hoặc gửi báo cáo lỗi.
- Giữ lại file thực thi của editor cũ. Các phiên bản Godot có thể cài song song — editor chỉ là một file thực thi duy nhất, nên giữ cả hai chẳng tốn kém gì và cho phép bạn mở branch cũ bằng editor cũ bất cứ lúc nào.
-
Liệt kê các addon và kiểm tra phiên bản được hỗ trợ của từng cái. Rà soát thư mục
addons/, ghi lại nguồn gốc của từng addon, và xác nhận trên repo hoặc trang Asset Library của nó rằng nó hỗ trợ phiên bản đích. - Đọc ghi chú nâng cấp chính thức cho mọi phiên bản bạn nhảy qua. Các hướng dẫn chuyển đổi chính thức được viết theo từng phiên bản — nếu bạn đi từ 4.2 lên 4.4, hãy đọc cả ghi chú của 4.3 lẫn 4.4.
- Lưu lại bằng chứng về "trạng thái tốt đã biết". Chụp ảnh màn hình các scene quan trọng, quay một đoạn gameplay ngắn, hoặc — tốt nhất — viết các kịch bản kiểm thử tự động (sẽ nói kỹ hơn ở phần kiểm thử bên dưới). Sau khi nâng cấp, câu hỏi "trông và hoạt động có giống như cũ không?" chỉ trả lời được nếu bạn đã ghi lại từ trước "như cũ" nghĩa là gì.
Quy trình nâng cấp
- Mở bản sao trên branch bằng editor mới. Là branch nâng cấp, không phải main. Editor mới sẽ đề nghị chuyển đổi/nhập lại — hãy chấp nhận.
-
Để nó nhập lại tài nguyên. Thư mục
.godotđược tạo lại từ đầu. Lần nhập đầu tiên có thể mất một lúc trên các dự án lớn, và những cảnh báo in ra trong lượt đầu đó thường vô hại. - Kiểm tra panel Output và Debugger để tìm các lỗi mới. So sánh với các lỗi đã có từ trước (bạn có ghi chú lại chúng chứ?). Các lỗi mới chính là danh sách việc cần làm của đợt chuyển đổi.
- Chơi thử các luồng quan trọng nhất. Bắt đầu game mới, tải một bản lưu, chạy vòng lặp gameplay cốt lõi, mở các menu chính. Lỗi ở editor là phần dễ — hành vi lúc chạy game mới là nơi các lỗi hồi quy ẩn nấp.
- Chạy các kịch bản kiểm thử của bạn (những kịch bản đã chuẩn bị trước khi nâng cấp) và so sánh với đường cơ sở.
-
Xem diff của working tree trong git trước khi commit. Editor ghi đè lại các file trong quá trình chuyển đổi:
project.godotnhận các giá trị cấu hình mới, các file.tscnđược lưu lại, và các file.uidmới có thể xuất hiện. Hãy xem kỹ diff để biết chính xác những gì đã thay đổi — rồi commit tất cả thành một commit chuyển đổi duy nhất, được đặt tên rõ ràng.
Những điểm dễ hỏng đã biết giữa các phiên bản 4.x
Các phiên bản minor của Godot 4 phần lớn tương thích lẫn nhau, nhưng chữ "phần lớn" trong câu đó không hề vô nghĩa. Dưới đây là những thay đổi dễ gây rắc rối nhất, dựa trên ghi chú chính thức và báo cáo từ cộng đồng.
4.2 → 4.3: TileMap bị khai tử, nhường chỗ cho TileMapLayer
Godot 4.3 đã đánh dấu node TileMap là lỗi thời, thay bằng TileMapLayer — mỗi layer là một node riêng thay vì nhiều layer bên trong một node. Các TileMap hiện có vẫn hoạt động, nhưng code mới và dự án mới nên dùng TileMapLayer. Editor có sẵn công cụ tách: chọn TileMap của bạn, mở panel TileMap ở phía dưới, nhấp vào biểu tượng hộp công cụ ở góc trên bên phải, rồi chọn "Extract TileMap layers as individual TileMapLayer nodes".
Cạm bẫy được cộng đồng báo cáo: có những báo cáo về việc các bit va chạm của physics layer trong TileSet bị đặt lại về mặc định sau khi chuyển sang TileMapLayer. Không phải ai cũng gặp, nhưng kiểu hỏng này rất khó chịu (mọi thứ ngừng va chạm, mà không có bất kỳ thông báo nào). Hãy kiểm tra rõ ràng va chạm của các tile sau khi chuyển đổi.
4.3 → 4.4: file .uid và các bổ sung cho GDScript
-
Godot 4.4 thêm các file đồng hành
.uidbên cạnh script và shader. Hãy commit chúng vào hệ thống quản lý phiên bản — xóa chúng có thể làm hỏng các tham chiếuuid://ở bất cứ đâu chúng được dùng (ghi chú nâng cấp chính thức của 4.4 đề cập các thay đổi liên quan như đường dẫn của@export_filechuyển thànhuid://). Trông chúng như rác; nhưng không phải rác. - Typed Dictionary và các bổ sung GDScript khác đều tương thích ngược — code cũ của bạn vẫn chạy. Nhưng những addon áp dụng các tính năng mới sẽ ngừng hoạt động trên phiên bản cũ hơn, nên hành vi của addon có thể khác nhau giữa hai bên của bước nhảy.
Tổng quát: những thay đổi tinh vi giữa bất kỳ phiên bản minor nào
Các điều chỉnh về rendering giữa các phiên bản minor có thể thay đổi tinh vi diện mạo game của bạn — ánh sáng, khử răng cưa, snapping 2D. Các cuộc thảo luận trong cộng đồng cũng ghi nhận những lỗi hồi quy chỉ xảy ra ở scene cụ thể, không tái hiện được trong dự án mới: một scene hoạt động sai sau khi nâng cấp, nhưng dựng lại đúng scene đó trong một dự án sạch thì lại chạy tốt. Nếu có gì đó hỏng một cách khó hiểu, hãy thử trình tự cô lập sau: đóng editor, xóa thư mục .godot, mở lại và để mọi thứ được nhập lại; nếu vấn đề vẫn còn, hãy tái hiện scene đó trong một dự án sạch để xác định thủ phạm là trạng thái tích tụ của dự án hay một thay đổi thực sự trong engine.
3.x → 4.x là một câu chuyện hoàn toàn khác
Mọi thứ bên trên đều nói về các bước nhảy giữa 4.x. Chuyển từ Godot 3 lên Godot 4 là một hạng mục hoàn toàn khác: cú pháp GDScript đã thay đổi, nhiều node bị đổi tên, còn TileMap, vật lý và rendering được làm lại từ gốc — và hầu hết addon cần phiên bản 4.x riêng. Với các dự án 3.x lớn, chi phí chuyển đổi có thể tiệm cận chi phí làm lại từ đầu, và việc có đáng hay không thực sự là quyết định của từng dự án. Cuộc chuyển đổi đó xứng đáng có (và đã có) tài liệu riêng; bài viết này sẽ không giả vờ bao quát nó.
Kiểm thử sau khi nâng cấp — nút thắt thực sự
Đây là phần nói thẳng: lý do số một khiến các nhà phát triển né việc nâng cấp không phải bản thân quá trình chuyển đổi — mà là việc xác minh "không có gì bị hỏng" bằng tay quá tốn kém. Một lượt kiểm thử hồi quy thủ công đầy đủ trên một game cỡ trung có thể ngốn trọn ngày cuối tuần. Và một lỗi runtime bị người chơi phát hiện sau khi phát hành còn tệ hơn nhiều so với bất kỳ lỗi editor nào, vì lúc đó nó đã là vấn đề về uy tín, chứ không còn là một mục trong danh sách việc cần làm.
Kiểm thử khói thủ công tối thiểu
- Bắt đầu game mới từ màn hình tiêu đề
- Tải một file lưu hiện có
- Chơi vòng lặp gameplay cốt lõi trong vài phút
- Kiểm tra UI ở từng độ phân giải và chế độ cửa sổ bạn hỗ trợ
Tự động hóa việc so sánh trước/sau
Kiểm thử thủ công không mở rộng theo quy mô được, và nó không thể cho bạn biết một sprite đã lệch hai pixel. Đây chính xác là lý do Godot QA ra đời — một test runner mã nguồn mở, miễn phí, giấy phép MIT dành cho Godot. Quy trình làm việc của nó khớp hoàn hảo với việc nâng cấp phiên bản:
- Trước khi nâng cấp, viết (hoặc ghi lại) các file scenario JSON bao phủ những luồng quan trọng nhất, và chụp ảnh màn hình đường cơ sở trên phiên bản cũ.
- Sau khi nâng cấp, chạy chính xác các kịch bản đó cộng thêm phép so sánh pixel với đường cơ sở trên phiên bản mới.
- Các phép thử thất bại chỉ đích danh lỗi hồi quy trong vài phút, thay vì cả ngày cuối tuần chơi lại bằng tay.
Một kịch bản chỉ là một danh sách JSON gồm các bước — đầu vào, chờ, kiểm chứng, ảnh chụp màn hình:
{
"name": "core_loop_smoke",
"steps": [
{"type": "wait", "seconds": 1.0},
{"type": "input", "action": "ui_accept", "pressed": true},
{"type": "wait", "seconds": 0.5},
{"type": "assert", "node_path": "/root/Main/Player",
"property": "health", "expected": 100, "operator": "eq"},
{"type": "input", "action": "move_right", "pressed": true},
{"type": "wait", "seconds": 2.0},
{"type": "input", "action": "move_right", "pressed": false},
{"type": "assert", "node_path": "/root/Main/Player",
"property": "position:x", "expected": 100.0, "operator": "gt"},
{"type": "screenshot", "name": "after_move"}
]
}
Định dạng kịch bản này cũng chính là định dạng mà công cụ run_test_scenario của Godot MCP Pro sử dụng, nên một trợ lý AI kết nối với editor của bạn có thể viết các kịch bản này thay bạn.
Nếu có gì đó bị hỏng
- Chia đôi theo phiên bản. Nếu bạn đã nhảy qua nhiều phiên bản minor cùng lúc, hãy thử nâng cấp lại từng phiên bản minor một để tìm chính xác nơi mọi thứ hỏng. Điều đó thu hẹp phạm vi tìm kiếm từ "tất cả" xuống còn một changelog duy nhất.
-
Xóa thư mục
.godotvà để dự án nhập lại tài nguyên. Cache import cũ là nguyên nhân của một tỷ lệ đáng ngạc nhiên các hiện tượng kỳ quặc sau nâng cấp. - Tìm kiếm nguyên văn thông báo lỗi của bạn trong GitHub issues của engine. Nếu đó là một lỗi hồi quy thật, thường đã có người báo cáo — đôi khi kèm cả cách vòng tránh.
- Kiểm tra xem thủ phạm có phải là một addon không. Tắt các addon trong Project Settings rồi kiểm thử lại. Nếu vấn đề biến mất, thủ phạm là addon — hãy tìm bản cập nhật của nó trước khi đổ lỗi cho engine.
- Chấp nhận rằng ở lại phiên bản cũ cũng là một kết quả hợp lệ. Nếu chi phí sửa chữa vượt quá lợi ích của việc nâng cấp, hãy hủy branch, giữ nguyên hiện trạng, và đặt lời nhắc để thử lại khi bản phát hành tiếp theo ra mắt. Đó không phải thất bại — đó là cơ chế quản lý rủi ro đang phát huy tác dụng.
Khi giữ nguyên hiện trạng là lựa chọn đúng
Có những dự án đơn giản là không nên nâng cấp, và điều đó đáng được nói thẳng: game đã phát hành hoặc sắp phát hành, dự án C# cần xuất bản web, game nhắm đến phần cứng cũ, và các dự án chạy trên bản build engine tùy chỉnh đã bị sửa đổi nhiều. Trong tất cả những trường hợp này, phiên bản bạn đang dùng vẫn đang làm tốt việc của nó. Nâng cấp là một công cụ, không phải một đức tính — mục tiêu là một game hoàn thiện, chứ không phải một engine mới tinh.
Câu hỏi thường gặp
Sau khi nâng cấp có thể hạ cấp không?
Không, không có cách nào đáng tin cậy. Một khi editor mới đã lưu lại các scene và tài nguyên của bạn, chúng không còn tương thích ngược với các editor cũ hơn. Con đường an toàn duy nhất để quay lại là khôi phục từ hệ thống quản lý phiên bản — đó chính xác là lý do branch nâng cấp tồn tại.
Có nên bỏ qua nhiều phiên bản cùng lúc không?
Các bước nhảy nhỏ an toàn hơn. Ghi chú nâng cấp chính thức được viết theo từng phiên bản, nên mỗi bước nhảy đều có một checklist đã biết — một cú nhảy qua nhiều phiên bản chồng tất cả chúng lên nhau cùng lúc, khiến việc xác định thay đổi nào làm hỏng thứ gì trở nên khó khăn hơn.
Phiên bản minor có thực sự làm hỏng thứ gì không?
Hiếm, nhưng có. Hầu hết dự án nhảy qua các phiên bản minor mà không gặp trục trặc, nhưng vẫn tồn tại các trường hợp biên do cộng đồng báo cáo — bit va chạm bị đặt lại, lỗi hồi quy rendering ở scene cụ thể. Đó chính là lý do các bài kiểm thử đường cơ sở trước khi nâng cấp lại quan trọng: chúng biến câu hỏi "có gì hỏng không?" từ một cảm giác thành một phép đo.
Checklist này có áp dụng cho 3.x → 4.x không?
Bản thân checklist thì có — tạo branch, giữ file thực thi cũ, lưu đường cơ sở, kiểm thử sau đó. Còn danh sách các điểm dễ hỏng thì không: cuộc chuyển đổi từ 3 lên 4 lớn hơn rất nhiều (cú pháp GDScript, node bị đổi tên, các hệ thống được làm lại) và có tài liệu chính thức chuyên biệt riêng.