{"slug": "why-does-chatgpt-keep-giving-me-godot-3-code-we-tested-150-answers", "title": "Why does ChatGPT keep giving me Godot 3 code? We tested 150 answers", "summary": "Ziva.sh, maker of the Ziva AI agent for Godot, tested 150 answers from OpenAI's GPT-6 Luna on 10 November 2026 and found 0 Godot 3 API errors across the 10 beginner Godot prompts it ran through OpenAI's Codex endpoint, checking all code against Godot 4.7.2. The remaining failures were 3 answers with real errors in the plain-chat \"Godot 4\" default-reasoning setup — 2 parse errors and 1 runtime error — rather than the Godot 3 constructs such as KinematicBody2D, export var and yield that Godot 4.0 removed on 1 March 2023. Ziva.sh attributes older complaints, including an October 2024 forum post citing GPT-4o, to models that mixed the two versions, and advises developers to use a current model, state their Godot version and check generated code in Godot.", "body_md": "# Why does ChatGPT keep giving me Godot 3 code? We tested 150 answers\n\nChatGPT gives you Godot 3 code when the model behind it mixes up the two versions. [Godot 4.0 shipped on 1 March 2023](https://godotengine.org/article/godot-4-0-sets-sail/) and renamed or removed many Godot 3 classes, methods and keywords, so `KinematicBody2D`, `export var` and `yield` no longer work. A current model may not do this anymore: in November 2026 we asked GPT-6 Luna, a current OpenAI model, 10 beginner Godot questions in plain chat, with \"Godot 4\" in the prompt, without a version, and with web search on. In 150 answers it wrote 0 Godot 3 API errors. What did go wrong was different: a few parse errors, and a few runtime-only bugs that Godot's parser accepts. If you still get Godot 3 code, use a current model, say your Godot version, and check the code in Godot.\n\nZiva.sh makes Ziva, an AI agent for Godot, and ran this test. We captured every answer on 10 November 2026 (UTC) and checked the code on Godot 4.7.2. We called GPT-6 Luna through OpenAI's Codex endpoint with a ChatGPT account login, not through the ChatGPT app, which can behave differently. We also ran the same prompts through Ziva on the same model; results are [below](#where-ziva-fits).\n\n## [Where the complaints come from](#where-the-complaints-come-from)\n\n- In October 2024 a Godot forum user [posted ChatGPT-written code](https://forum.godotengine.org/t/unexpected-identifier-in-class-body-error/50110/6) with`onready var` and`self.connect(\"input_event\", self, \"_on_input_event\")` that failed in Godot 4, and added the next day:[\"Even ChatGPT4.o failed\"](https://forum.godotengine.org/t/unexpected-identifier-in-class-body-error/50110/8) .\n- In September 2025 a forum thread asked whether ChatGPT is a good way to learn Godot. One reply: [\"they confuse Godot 4 and Godot 3 functions\"](https://forum.godotengine.org/t/is-it-bad-to-use-chatgpt-to-help-me-learn-specific-situations-in-godot/121995) . Another: \"The Godot 3/4 mix up is real\".\n- In September 2026 a forum user wrote that AI answers [\"are mixes from the syntax of Godot3 and Godot4. Even if i explicit say for Godot4..\"](https://forum.godotengine.org/t/adviced-for-a-no-code-exp/143691) , without naming the AI.\n\nOnly the first names a specific model version, GPT-4o. We cannot tell which models the others used, and our result says nothing about those models.\n\n## [How we tested](#how-we-tested)\n\nWe wrote 10 beginner prompts from forum threads: a 2D platformer player, a third-person controller, spawning enemies on a timer, saving a high score, a Start button that changes scene, fading out a coin, placing tiles from code, a health bar that follows an exported variable, random numbers, and a trap that disappears after 2 seconds. None names an API that changed between Godot 3 and 4. Example: \"I'm making my first 2D platformer in Godot 4. Can you write me a player script so my character can run left and right, jump, and fall with gravity?\"\n\nPlain chat got each prompt 3 times per setup, with no project and no system prompt apart from the web-search setup's short instruction to answer from web results. An AI agent read every code block and a script scanned it for a checklist of Godot 3 forms built from the [official upgrade guide](https://docs.godotengine.org/en/stable/tutorials/migrating/upgrading_to_godot_4.html) and Godot 4.7.2's own upgrade-tool rename map; the same agent did both, and the read was not blind to the scan. Every script also went through Godot 4.7.2's `--check-only`. Every runtime error below was confirmed by running the code headless on Godot 4.7.2.\n\n## [Results](#results)\n\n| Setup | Godot 3 API errors | Other real errors | \n|---|---|---|\n| GPT-6 Luna plain chat, prompt says \"Godot 4\", default reasoning | GPT-6 Luna plain chat: 0 in 30 answers | GPT-6 Luna plain chat: 3 answers (2 parse errors, 1 runtime error) | \n| GPT-6 Luna plain chat, prompt says \"Godot 4\", low reasoning | GPT-6 Luna plain chat, low reasoning: 0 in 30 | GPT-6 Luna plain chat, low reasoning: none | \n| GPT-6 Luna plain chat, prompt says only \"Godot\" | GPT-6 Luna plain chat, no version: 0 in 30 | GPT-6 Luna plain chat, no version: 2 answers (1 runtime error, 1 told to connect a signal StaticBody2D does not have) | \n| GPT-6 Luna with web search, prompt says \"Godot 4\" | GPT-6 Luna with web search: 0 in 30 | GPT-6 Luna with web search: 2 answers (1 runtime error, 1 wrong setup instruction) | \n| GPT-6 Luna with web search, prompt says only \"Godot\" | GPT-6 Luna with web search, no version: 0 in 30 | GPT-6 Luna with web search, no version: 2 answers (both parse errors) | \n| Ziva on GPT-6 Luna, question prompts as above | Ziva on GPT-6 Luna: 0 in 10 chats | Ziva on GPT-6 Luna: 2 chats (1 parse error in chat reply code, 1 runtime error) | \n| Ziva on GPT-6 Luna, build-it prompts (\"Add the script to my project.\") | Ziva on GPT-6 Luna: 0 in 10 chats | Ziva on GPT-6 Luna: 1 chat (runtime error) | \n| Ziva on GPT-6 Luna, build-it prompts, only \"Godot\" | Ziva on GPT-6 Luna: 0 in 10 chats | Ziva on GPT-6 Luna: 2 chats (1 runtime error, 1 instruction that breaks the script) | \n\nThe code used Godot 4 forms throughout: `@export`, `@onready`, `CharacterBody2D` with the `velocity` property and `move_and_slide()` without arguments, `instantiate()`, `pressed.connect(...)`, `create_tween()`, `change_scene_to_file()`, `TileMapLayer.set_cell()`, `randi_range()` and `await ... .timeout`.\n\nWithout a version in the prompt and without search, 18 of 30 plain-chat answers said they target Godot 4 and the rest named no version; none targeted Godot 3. With web search on, every search GPT-6 Luna ran started with `site:docs.godotengine.org/en/stable`, its own choice. Docs pages for Godot 3 or older came back in the search results of 23 of 60 answers, no answer cited one, and none of those answers had Godot 3 code.\n\nZero is not proof of never. If every answer were independent, 0 in 150 would put the rate below about 2% with 95% confidence; answers to the same prompt are not independent, so the real uncertainty is larger.\n\n## [What went wrong instead](#what-went-wrong-instead)\n\nSeven of the 150 plain-chat answers had code that does not work in Godot 4.7.2: four fail to parse and three parse cleanly and break when they run. Two more gave wrong setup instructions. Three examples.\n\n**1. Turning off an Area2D inside its own signal.** This line appeared in five places across plain chat and Ziva, in the coin and trap prompts:\n\n`--check-only` accepts it. When the player touches the coin, Godot 4.7.2 prints this and `monitoring` stays `true`:\n\nUse `set_deferred(\"monitoring\", false)`, as several other answers did.\n\n**2. A setter that touches a node before it exists.** One web-search answer wrote this health bar script:\n\nIt parses. Set Health to 50 in the Inspector and run the scene: the saved value is applied before the `ProgressBar` child is added, so the setter fails and the bar shows 0 until health changes again in code:\n\nWrap the two `$ProgressBar` lines in `if is_node_ready():` and update the bar once in `_ready()`.\n\n**3. A type Godot cannot infer.** Four answers failed to parse, three of them on an untyped loop variable in tile-placement code, like this:\n\n`for direction: Vector2i in [...]` fixes it. Unlike the first two, `--check-only` catches this one.\n\n## [What Godot's parser catches, and what it does not](#what-godots-parser-catches-and-what-it-does-not)\n\nNo answer used Godot 3 code, so this list comes from running each Godot 3 form through Godot 4.7.2 ourselves.\n\nGodot 4.7.2's `--check-only` rejects these, so a parse check finds them:\n\n- `export var` ,`onready var` ,`tool` ,`setget` ,`yield` and`remote func`\n- `button.connect(\"pressed\", self, \"_on_pressed\")` : \"Invalid argument for \"connect()\" function: argument 2 should be \"Callable\" but is ...\"\n- `File.new()` ,`Directory.new()` ,`OS.get_ticks_msec()` ,`rand_range()` ,`update()` ,`BUTTON_LEFT`\n- `.empty()` on a typed Array\n- `move_and_slide(velocity, Vector2.UP)` and`velocity = move_and_slide()`\n- classes such as `KinematicBody2D` ,`Spatial` ,`Position2D` and`PoolStringArray`\n- `rect_position` and`translation` on the script's own node\n\nThese pass Godot 4.7.2's `--check-only` and fail only when the line runs:\n\n- `scene.instance()` : \"Invalid call. Nonexistent function 'instance' in base 'PackedScene'.\"\n- `get_tree().change_scene()` and`change_scene_to()`\n- `Tween.new()` and the Tween node's`interpolate_property()` : \"Tween can't be created directly. Use create_tween() method.\"\n- `yield(get_tree(), \"idle_frame\")` rewritten as`await get_tree().idle_frame`\n- TileMap `set_cellv()` and`world_to_map()`\n- `rect_position` and`.empty()` on an untyped variable\n\n## [Check AI-written GDScript in one line](#check-ai-written-gdscript-in-one-line)\n\nParse and analyze one script without opening the editor:\n\nIt prints `SCRIPT ERROR: Parse Error: ...` with the line and exits with code 1. A clean script exits with 0. Replace `godot` with the path to your Godot 4 executable.\n\nFor the runtime-only list, run the scene. In the editor, press F6 and read the Output and Debugger panels. Headless:\n\n`--quit-after 120` stops after 120 frames. Read the output for `SCRIPT ERROR` lines: in our run a scene calling `change_scene()` printed \"Invalid call. Nonexistent function 'change_scene' in base 'SceneTree'.\" and Godot still exited with code 0.\n\n## [If you still get Godot 3 code](#if-you-still-get-godot-3-code)\n\n- **Use a current model.** The complaint above that names a model is about GPT-4o in 2024; GPT-6 Luna wrote none in our test. We did not test older models side by side.\n- **Say your exact version** , such as \"Godot 4.7\". It made no difference for GPT-6 Luna, but a chat model cannot see your project.\n- **Check the code in Godot** with the two commands above before you build on it.\n- **Give your agent a rename table.** Our free, MIT-licensed[godot-skills](https://github.com/ziva-sh/godot-skills) pack includes a`godot-4-api-pitfalls` skill with a Godot 3 to 4 rewrite table and the list of Godot 3 lines that pass`--check-only` and fail at runtime. It works with agents that read the Agent Skills format; see[Godot AI skills](https://ziva.sh/blogs/godot-ai-skills) .\n\n## [Where Ziva fits](#where-ziva-fits)\n\n[Ziva](https://ziva.sh/) is our AI agent inside the Godot editor. It is proprietary and has a free Hobby plan. We ran the same 10 prompts through Ziva on the same model, GPT-6 Luna, one chat per prompt, in three sets of 10. Ziva also wrote 0 Godot 3 API errors.\n\n- **Asked a question, Ziva mostly answered in chat.** With the prompts above (\"How do I ...? Please write the script.\"), Ziva wrote a file in 1 of 10 chats and replied in chat in the other 9. Ziva does not check code in a chat reply.\n- **Asked to build it, Ziva wrote the file and checked it.** With the same prompts reworded as instructions (\"Add the script to my project.\"), Ziva wrote a`.gd` file in all 20 chats. After each write, Ziva's check returned \"No problems in this file or its callers.\" on all 21 writes in the build-it chats.\n- **The check is a parse, not a run.** It is Godot's GDScript language server plus the editor's script reload, the same kind of check as`--check-only` . Two of those files had the`monitoring = false` bug from example 1 and still got \"No problems\". In a separate probe, a script with`instance()` ,`change_scene()` ,`Tween.new()` and`set_cellv()` also got \"No problems\".\n\nSo this test did not show Ziva's check catching a Godot 3 error, because there were none to catch, and the check cannot see runtime-only errors. Running the scene and reading its output catches those. Ziva can run scenes too, but that was not part of this test.\n\n## [Limits](#limits)\n\n- One model, GPT-6 Luna, on one date. Older models, other providers and the ChatGPT app were not tested.\n- Plain chat used OpenAI's Codex endpoint, and web search used that endpoint's search tool with instructions to answer from web results. The model searched only the Godot docs, so old forum answers never came up.\n- 10 prompts that we wrote, 3 answers per prompt in each plain-chat setup and 1 chat per prompt in each Ziva set.\n- We added the \"add the script to my project\" Ziva prompts after seeing that Ziva answered the question prompts in chat, so the two Ziva sets are not a planned comparison. The no-version and web-search sets were also added after the first results, each written down before it ran.\n- Ziva ran with low reasoning effort and plain chat with the default; the low-reasoning plain chat set covers that gap. Ziva tells the model the Godot version in its own instructions, so its \"only Godot\" set still had a version.\n- An AI agent, not a person, read the code, and the same agent ran the checklist scan, so the read was not blind to the scan.\n- For the build-it Ziva runs we moved the second editor's language-server port, because two Godot editors were open on the test machine and Ziva's check otherwise queried the other editor, as it did for the one file written in the question set. We filed that as a Ziva bug.\n\n## [Related reading](#related-reading)\n\n- [Claude Godot Code: Claude vs GPT-4o on Godot 4 APIs](https://ziva.sh/blogs/claude-godot) : training cutoffs and Godot versions\n- [How do I generate GDScript with AI?](https://ziva.sh/blogs/generate-gdscript-with-ai) : chat, AI code editors and agents inside Godot\n- [Godot AI skills](https://ziva.sh/blogs/godot-ai-skills) : skill packs for Godot and how to install one", "url": "https://wpnews.pro/news/why-does-chatgpt-keep-giving-me-godot-3-code-we-tested-150-answers", "canonical_source": "https://ziva.sh/blogs/chatgpt-godot-3-code", "published_at": "2026-11-11 00:00:00+00:00", "updated_at": "2026-11-11 07:21:03.191115+00:00", "lang": "en", "topics": ["ai-tools", "large-language-models", "generative-ai", "ai-agents"], "entities": ["Ziva", "OpenAI", "GPT-6 Luna", "Godot 4.7.2", "Godot 4.0", "GPT-4o", "Codex"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/why-does-chatgpt-keep-giving-me-godot-3-code-we-tested-150-answers", "markdown": "https://wpnews.pro/news/why-does-chatgpt-keep-giving-me-godot-3-code-we-tested-150-answers.md", "text": "https://wpnews.pro/news/why-does-chatgpt-keep-giving-me-godot-3-code-we-tested-150-answers.txt", "jsonld": "https://wpnews.pro/news/why-does-chatgpt-keep-giving-me-godot-3-code-we-tested-150-answers.jsonld"}}