0

Godot 4 và AI: Tại sao code do AI viết hay hỏng âm thầm

Nếu bạn đang dùng ChatGPT, Cursor hoặc Claude để viết GDScript trong Godot 4, có thể bạn đã gặp một vấn đề mà ít tutorial nói đến: code AI viết ra trông đúng, biên dịch được, chạy được, nhưng game lại hoạt động sai mà không có lỗi nào hiện ra. Đây là kiểu bug khó debug nhất.

Báo cáo Sonarsource State of Code 2026 cho biết 60% lỗi trong code do AI sinh ra là "lỗi âm thầm" (silent failures) — code biên dịch được, trông như đúng, nhưng cho kết quả sai trong production. Với Godot, "production" là lần đầu bạn nhấn F5.

Tôi đã làm việc với code Godot do AI sinh ra trong khoảng 8 tháng. Dưới đây là 5 pattern lỗi mà tôi gặp đi gặp lại.

1. Signal connect tới node đã bị freed

# AI hay viết
func setup_enemy(enemy):
    enemy.died.connect(_on_enemy_died)

Code này trông đúng. Nhưng nếu node gọi setup_enemy() bị queue_free() trước khi enemy chết, signal sẽ emit nhưng callback không chạy. Godot không báo lỗi. Bạn chỉ thấy "score không tăng" hoặc "animation không play".

Cách phòng tránh: dùng is_instance_valid() guard, hoặc disconnect tường minh trong _exit_tree().

2. AnimationTree parameter path sai chính tả

anim_tree.set("parameters/playback/state", "run")

Path đúng chỉ là parameters/playback, và state phải đổi qua method travel(). AI thường copy path từ project khác hoặc đoán, và nếu sai chính tả thì set() không báo lỗi gì cả — animation chỉ đơn giản là không chạy.

Cách phòng tránh: assert(anim_tree.get("parameters/playback") != null) lúc khởi động.

3. Autoload chưa register nhưng code đã reference

AudioManager.play("hit")

Nếu AudioManager chưa được thêm vào project settings (Autoload tab), bạn sẽ gặp NIL reference khi code đến đó. AI không kiểm tra project.godot, nó giả định autoload đã tồn tại.

4. load("res://...") với path hardcoded

AI thường viết load("res://scenes/Player.tscn") dựa trên cấu trúc folder của project nó học đầu tiên. Nếu project của bạn đặt Player ở res://entities/, load() trả về null mà không báo lỗi.

Cách phòng tránh: dùng @export var player_scene: PackedScene để inject scene từ Inspector.

5. Tween chain hỏng khi gọi liên tục

func attack():
    var tween = create_tween()
    tween.tween_property(self, "modulate", Color.RED, 0.1)
    tween.tween_property(self, "modulate", Color.WHITE, 0.1)

Nếu attack() được gọi nhanh liên tiếp (player spam button), nhiều tween chạy đồng thời và đè lên nhau. Animation sẽ "giật giật" mà không có lỗi.

Cách phòng tránh: tween.kill() ở đầu, hoặc dùng set trực tiếp thay vì tween.

Tại sao AI không tự sửa được

Tất cả 5 pattern đều có một điểm chung: chỉ phát hiện được khi chạy code thực tế trong Godot. Phân tích tĩnh không thấy được, đọc source code cũng không thấy.

Stack Overflow Developer Survey 2025 cho biết niềm tin của developer vào AI giảm từ 40% xuống 29%, và 66% developer than phiền về code AI "gần đúng nhưng không hoàn toàn đúng". Godot là môi trường mà vấn đề này nặng nhất.

Giải pháp thực tế

Ba điều giúp được:

Luôn nhấn F5 sau khi paste code AI. Đừng commit khi chưa run scene. Output panel của Godot sẽ hiện ra hầu hết lỗi âm thầm trong vài giây.

Thêm is_connected(), is_instance_valid(), assert() guard vào code AI. Đây là defensive pattern rẻ nhất bạn có thể làm.

Dùng AI tool tích hợp với engine khi có thể. Một số tool mới (ví dụ Ziva chuyên cho Godot) cho phép agent chạy scene và observe output. Cùng một model nhưng có khả năng test code mà nó vừa viết, nên detect được lỗi runtime ngay khi xuất hiện.

Kết luận

Code AI viết "trông như chạy được" và "thực sự chạy đúng" là hai chuyện khác nhau. Trong Godot, khoảng cách giữa hai cái này lớn hơn so với code web vì runtime của Godot phức tạp hơn (scene tree, signals, AnimationTree).

"Compile pass" không có nghĩa là "code đúng". Đây là quy tắc quan trọng nhất khi dùng AI để viết Godot code trong 2026.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí