Can Nova 2 Lite write working Godot 4 code? 2 of 15 on the first try

By Eduardo Orellana · Updated

Nova 2 Lite passed 2 of 15 Godot 4 tasks on the first try and 4 of 15 after one fix with the test's output, each run headless on Godot 4.7.2. It missed: move a characterbody2d with an input action, fall with gravity and land on the floor, save and load a dictionary as json, health with signals, fade out with a tween, a door with states, an inventory with counts, load a level scene from a path, paint cells on a tilemaplayer, cast a physics ray, a path on a grid around walls, build and play an animation in code, wait for a signal or a timeout.

AppImage, x86_64. Ubuntu 22.04, Debian 12, Fedora 39 or newer.

Intel or AMD Chromebook, with Linux turned on.

Download for macOSDownload for Windows

Every model measured on the same Godot 4 tasks, each run headless on Godot 4.7.2 at a fixed 60 frames per second.

Measured by Flockbay: the same tasks, the same checks, one fix allowed with the test output.

Every model measured on the same Godot 4 tasks, each run headless on Godot 4.7.2 at a fixed 60 frames per second., checked 18 October 2026
ModelFirst tryAfter one fixAgentRun onRead from
Claude Opus 5.515 of 1515 of 15Claude Code2026-10-06Claude Opus 5.5 results
Claude Sonnet 5.515 of 1515 of 15Claude Code2026-10-06Claude Sonnet 5.5 results
GPT-6.1 Sol15 of 1515 of 15Codex2026-10-06GPT-6.1 Sol results
DeepSeek V4.1 Flash15 of 1515 of 15Hosted, by API2026-10-18DeepSeek V4.1 Flash results
Ember-115 of 1515 of 15Hosted, by API2026-10-18Ember-1 results
Gemini 3.1 Pro Preview15 of 1515 of 15Hosted, by API2026-10-18Gemini 3.1 Pro Preview results
Muse Wonder15 of 1515 of 15Hosted, by API2026-10-18Muse Wonder results
Kimi K315 of 1515 of 15Hosted, by API2026-10-18Kimi K3 results
GPT-5.6 Luna15 of 1515 of 15Hosted, by API2026-10-18GPT-5.6 Luna results
GPT-6 Luna15 of 1515 of 15Hosted, by API2026-10-18GPT-6 Luna results
Hy4 preview15 of 1515 of 15Hosted, by API2026-10-18Hy4 preview results
Pareto 26.1015 of 1515 of 15Hosted, by API2026-10-18Pareto 26.10 results
Claude Haiku 5.514 of 1515 of 15Hosted, by API2026-10-18Claude Haiku 5.5 results
MiMo-V2.6-Pro-UltraSpeed14 of 1515 of 15Hosted, by API2026-10-18MiMo-V2.6-Pro-UltraSpeed results
GLM 5.214 of 1515 of 15Hosted, by API2026-10-18GLM 5.2 results
DeepSeek V4 Pro 081314 of 1514 of 15Hosted, by API2026-10-18DeepSeek V4 Pro 0813 results
GPT-5.414 of 1514 of 15Hosted, by API2026-10-18GPT-5.4 results
MiniMax M313 of 1514 of 15Hosted, by API2026-10-18MiniMax M3 results
Qwen3.7 Max13 of 1514 of 15Hosted, by API2026-10-18Qwen3.7 Max results
Fugu Max13 of 1514 of 15Hosted, by API2026-10-18Fugu Max results
Beam 1.0 501B A23B12 of 1514 of 15Hosted, by API2026-10-18Beam 1.0 501B A23B results
Mistral Large 412 of 1513 of 15Hosted, by API2026-10-18Mistral Large 4 results
Claude Haiku 4.511 of 1514 of 15Claude Code2026-10-06Claude Haiku 4.5 results
Nemotron 3.5 Super VL11 of 1514 of 15Hosted, by API2026-10-18Nemotron 3.5 Super VL results
LongCat 2.011 of 1513 of 15Hosted, by API2026-10-18LongCat 2.0 results
Grok 4.311 of 1513 of 15Hosted, by API2026-10-18Grok 4.3 results
Laguna S 2.19 of 1512 of 15Hosted, by API2026-10-18Laguna S 2.1 results
Nova 2 Lite2 of 154 of 15Hosted, by API2026-10-18Nova 2 Lite results

How the test works

Each task asks for one GDScript file with a stated API, in a fresh Godot project. Nova 2 Lite was asked through its API, the way Flockbay reaches its hosted models: the task in one request, no tools, and the whole file back in a code block. A check scene then loaded the file and drove it on Godot 4.7.2, headless, at a fixed 60 frames per second: it pressed input actions, stepped physics, waited on timers and signals, and compared the results.

When a task failed, the model got the check's output once and could fix its file. Every task touches an API that changed between Godot 3 and Godot 4, or was added since: move_and_slide and is_on_floor, FileAccess and JSON, signals, tweens, Timer nodes, PackedScene, TileMapLayer, ray queries, AStarGrid2D, AnimationLibrary, and lambdas, which capture local variables by value.

The checks themselves are tested first: each passes on a reference answer and fails on an empty script. Run on 2026-10-18.

Nova 2 Lite in Flockbay

Nova 2 Lite is a hosted model in the Flockbay app's model menu, on the Indie Developer plan and above. It uses the plan's hosted usage about 18.7 times as fast as Auto.

It takes images, so Flockbay can show it screenshots of your game, and it has an effort setting in the composer, from quick answers to longer reasoning.

Move a CharacterBody2D with an input action: fail

The task: Write res://player.gd for Godot 4: a script for a CharacterBody2D that moves right at 200 pixels per second while the input action "ui_right" is held, and stands still otherwise.

Failed on the first try (BENCH FAIL: after 0.5 s holding ui_right x is 0.0, expected about 100) and after one fix (BENCH FAIL: after 0.5 s holding ui_right x is 0.0, expected about 100).

What Godot 4.7.2 printed on the first try:

Godot Engine v4.7.2.stable.mono.official.ed1daf0bf - https://godotengine.org

SCRIPT ERROR: Parse Error: Too many arguments for "move_and_slide()" call. Expected at most 0 but received 1.
   at: GDScript::reload (res://player.gd:8)
   GDScript backtrace (most recent call first):
       [0] _ready (res://bench_check.gd:4)
ERROR: Failed to load script "res://player.gd" with error "Parse error".
   at: load (modules/gdscript/gdscript_resource_format.cpp:46)
   GDScript backtrace (most recent call first):
       [0] _ready (res://bench_check.gd:4)
BENCH FAIL: after 0.5 s holding ui_right x is 0.0, expected about 100

Fall with gravity and land on the floor: fail

The task: Write res://ball.gd for Godot 4: a script for a CharacterBody2D that falls with a gravity of 980 pixels per second squared and stops when it lands on the floor. The scene gives it its collision shape.

Failed on the first try (BENCH FAIL: not on the floor after 2 s; y is 0.0) and after one fix (BENCH FAIL: not on the floor after 2 s; y is 0.0).

What Godot 4.7.2 printed on the first try:

Godot Engine v4.7.2.stable.mono.official.ed1daf0bf - https://godotengine.org

SCRIPT ERROR: Parse Error: Function "is_in_collision()" not found in base self.
   at: GDScript::reload (res://ball.gd:14)
   GDScript backtrace (most recent call first):
       [0] _ready (res://bench_check.gd:4)
ERROR: Failed to load script "res://ball.gd" with error "Parse error".
   at: load (modules/gdscript/gdscript_resource_format.cpp:46)
   GDScript backtrace (most recent call first):
       [0] _ready (res://bench_check.gd:4)
BENCH FAIL: not on the floor after 2 s; y is 0.0

A score label: pass

The task: Write res://score_label.gd for Godot 4: a script for a Label that shows "Score: 0" when it enters the scene, and has a method add(points: int) that adds to the score and updates the text to "Score: <total>".

Passed on the first try.

# res://score_label.gd
extends Label

var score: int = 0

func _ready() -> void:
	update_label()

func add(points: int) -> void:
	score += points
	update_label()

func update_label() -> void:
	text = "Score: %d" % score

Save and load a dictionary as JSON: pass after one fix

The task: Write res://save_game.gd for Godot 4: a script extending RefCounted with two static functions: save_data(data: Dictionary, path: String) -> void writes the dictionary to the file as JSON, and load_data(path: String) -> Dictionary reads it back.

Failed on the first try (BENCH FAIL: read back { }), passed after one fix.

What Godot 4.7.2 printed on the first try:

Godot Engine v4.7.2.stable.mono.official.ed1daf0bf - https://godotengine.org

SCRIPT ERROR: Invalid operands 'String' and 'int' in operator '=='.
   at: save_data (res://save_game.gd:16)
   GDScript backtrace (most recent call first):
       [0] save_data (res://save_game.gd:16)
       [1] _ready (res://bench_check.gd:9)
ERROR: Failed to parse JSON from file user://bench_save.json: Unknown error getting token
   at: push_error (core/variant/variant_utility.cpp:1023)
   GDScript backtrace (most recent call first):
       [0] load_data (res://save_game.gd:44)
       [1] _ready (res://bench_check.gd:10)
BENCH FAIL: read back {  }

Health with signals: fail

The task: Write res://health.gd for Godot 4: a script extending Node with health starting at 100, a signal health_changed(old_value: int, new_value: int), a signal died, and a method take_damage(amount: int) that lowers health without going below 0, emits health_changed when health changes, and emits died once, when health reaches 0.

Failed on the first try (SCRIPT ERROR: Parse Error: Unrecognized annotation: "@signal".) and after one fix (SCRIPT ERROR: Parse Error: Unrecognized annotation: "@signal".).

What Godot 4.7.2 printed on the first try:

Godot Engine v4.7.2.stable.mono.official.ed1daf0bf - https://godotengine.org

SCRIPT ERROR: Parse Error: Unrecognized annotation: "@signal".
   at: GDScript::reload (res://health.gd:4)
   GDScript backtrace (most recent call first):
       [0] _ready (res://bench_check.gd:7)
ERROR: Failed to load script "res://health.gd" with error "Parse error".
   at: load (modules/gdscript/gdscript_resource_format.cpp:46)
   GDScript backtrace (most recent call first):
       [0] _ready (res://bench_check.gd:7)
SCRIPT ERROR: Invalid access to property or key 'health_changed' on a base object of type 'Node'.
   at: _ready (res://bench_check.gd:14)
   GDScript backtrace (most recent call first):
       [0] _ready (res://bench_check.gd:14)

Fade out with a tween: fail

The task: Write res://fader.gd for Godot 4: a script extending Node2D with a method fade_out(duration: float) that fades the node's modulate alpha from 1 to 0 over duration seconds with a tween, and a signal faded emitted when the fade ends.

Failed on the first try (SCRIPT ERROR: Parse Error: Unrecognized annotation: "@signal".) and after one fix (SCRIPT ERROR: Parse Error: Unrecognized annotation: "@signal".).

What Godot 4.7.2 printed on the first try:

Godot Engine v4.7.2.stable.mono.official.ed1daf0bf - https://godotengine.org

SCRIPT ERROR: Parse Error: Unrecognized annotation: "@signal".
   at: GDScript::reload (res://fader.gd:4)
   GDScript backtrace (most recent call first):
       [0] _ready (res://bench_check.gd:6)
ERROR: Failed to load script "res://fader.gd" with error "Parse error".
   at: load (modules/gdscript/gdscript_resource_format.cpp:46)
   GDScript backtrace (most recent call first):
       [0] _ready (res://bench_check.gd:6)
SCRIPT ERROR: Invalid access to property or key 'faded' on a base object of type 'Node2D'.
   at: _ready (res://bench_check.gd:14)
   GDScript backtrace (most recent call first):
       [0] _ready (res://bench_check.gd:14)

Spawn on a timer, then stop: pass

The task: Write res://spawner.gd for Godot 4: a script extending Node that, once in the scene, adds a new child Node2D every 0.25 seconds, using a Timer, and stops after 4 children. It keeps the number spawned in a variable spawned_count.

Passed on the first try.

# res://spawner.gd
extends Node

var spawned_count: int = 0
var max_children: int = 4

func _ready() -> void:
	# Create a Timer node
	var timer := Timer.new()
	timer.wait_time = 0.25
	timer.autostart = true
	add_child(timer)
	
	# Connect the timeout signal to the spawn function
	timer.timeout.connect(_on_timer_timeout)

func _on_timer_timeout() -> void:
	if spawned_count >= max_children:
		return
	
	# Create a new Node2D child
	var new_node := Node2D.new()
	add_child(new_node)
	spawned_count += 1

A door with states: fail

The task: Write res://door.gd for Godot 4: a script extending Node for a door with the states CLOSED, OPENING and OPEN. It starts CLOSED. A method interact() starts opening a closed door; 0.5 seconds of game time later it is OPEN. A method get_state_name() -> String returns "CLOSED", "OPENING" or "OPEN".

Failed on the first try (SCRIPT ERROR: Parse Error: Expected end of statement after return statement, found "Identifier" instead.) and after one fix (SCRIPT ERROR: Parse Error: Expected end of statement after return statement, found "Identifier" instead.).

What Godot 4.7.2 printed on the first try:

Godot Engine v4.7.2.stable.mono.official.ed1daf0bf - https://godotengine.org

SCRIPT ERROR: Parse Error: Expected end of statement after return statement, found "Identifier" instead.
   at: GDScript::reload (res://door.gd:20)
   GDScript backtrace (most recent call first):
       [0] _ready (res://bench_check.gd:4)
ERROR: Failed to load script "res://door.gd" with error "Parse error".
   at: load (modules/gdscript/gdscript_resource_format.cpp:46)
   GDScript backtrace (most recent call first):
       [0] _ready (res://bench_check.gd:4)
SCRIPT ERROR: Invalid call. Nonexistent function 'get_state_name' in base 'Node'.
   at: _ready (res://bench_check.gd:11)
   GDScript backtrace (most recent call first):
       [0] _ready (res://bench_check.gd:11)

An inventory with counts: fail

The task: Write res://inventory.gd for Godot 4: a script extending RefCounted with add_item(item_name: String, count: int), remove_item(item_name: String, count: int) -> bool that removes only when there are enough and returns whether it did, and get_count(item_name: String) -> int that is 0 for an item never added.

Failed on the first try (SCRIPT ERROR: Parse Error: Could not find type "Dict" in the current scope.) and after one fix (SCRIPT ERROR: Parse Error: Could not find type "Dict" in the current scope.).

What Godot 4.7.2 printed on the first try:

Godot Engine v4.7.2.stable.mono.official.ed1daf0bf - https://godotengine.org

SCRIPT ERROR: Parse Error: Could not find type "Dict" in the current scope.
   at: GDScript::reload (res://inventory.gd:6)
   GDScript backtrace (most recent call first):
       [0] _ready (res://bench_check.gd:4)
ERROR: Failed to load script "res://inventory.gd" with error "Parse error".
   at: load (modules/gdscript/gdscript_resource_format.cpp:46)
   GDScript backtrace (most recent call first):
       [0] _ready (res://bench_check.gd:4)
SCRIPT ERROR: Invalid call. Nonexistent function 'new' in base 'GDScript'.
   at: _ready (res://bench_check.gd:8)
   GDScript backtrace (most recent call first):
       [0] _ready (res://bench_check.gd:8)

Load a level scene from a path: pass after one fix

The task: Write res://level_loader.gd for Godot 4: a script extending Node with a method load_level(path: String) -> Node that loads the scene file at path, creates an instance of it, adds it as a child, and returns it.

Failed on the first try (SCRIPT ERROR: Parse Error: Unexpected "/" in class body.), passed after one fix.

What Godot 4.7.2 printed on the first try:

Godot Engine v4.7.2.stable.mono.official.ed1daf0bf - https://godotengine.org

SCRIPT ERROR: Parse Error: Unexpected "/" in class body.
   at: GDScript::reload (res://level_loader.gd:6)
   GDScript backtrace (most recent call first):
       [0] _ready (res://bench_check.gd:4)
ERROR: Failed to load script "res://level_loader.gd" with error "Parse error".
   at: load (modules/gdscript/gdscript_resource_format.cpp:46)
   GDScript backtrace (most recent call first):
       [0] _ready (res://bench_check.gd:4)
SCRIPT ERROR: Invalid call. Nonexistent function 'load_level' in base 'Node'.
   at: _ready (res://bench_check.gd:20)
   GDScript backtrace (most recent call first):
       [0] _ready (res://bench_check.gd:20)
WARNING: 2 RIDs of type "CanvasItem" were leaked.
   at: _free_rids (servers/rendering/renderer_canvas_cull.cpp:2735)
WARNING: 2 ObjectDB instances were leaked at exit (run with `--verbose` for details).
   at: cleanup (core/object/object.cpp:2536)

Paint cells on a TileMapLayer: fail

The task: Write res://grid_painter.gd for Godot 4.7: a script extending TileMapLayer with paint_row(y: int, from_x: int, to_x: int) that sets the cells from (from_x, y) to (to_x, y) inclusive to tile source 0, atlas coordinates (0, 0), and is_painted(cell: Vector2i) -> bool that says whether a cell has a tile.

Failed on the first try (SCRIPT ERROR: Parse Error: Unexpected "/" in class body.) and after one fix (SCRIPT ERROR: Parse Error: Function "has_cell()" not found in base self.).

What Godot 4.7.2 printed on the first try:

Godot Engine v4.7.2.stable.mono.official.ed1daf0bf - https://godotengine.org

SCRIPT ERROR: Parse Error: Unexpected "/" in class body.
   at: GDScript::reload (res://grid_painter.gd:4)
   GDScript backtrace (most recent call first):
       [0] _ready (res://bench_check.gd:4)
ERROR: Failed to load script "res://grid_painter.gd" with error "Parse error".
   at: load (modules/gdscript/gdscript_resource_format.cpp:46)
   GDScript backtrace (most recent call first):
       [0] _ready (res://bench_check.gd:4)
SCRIPT ERROR: Invalid call. Nonexistent function 'paint_row' in base 'TileMapLayer'.
   at: _ready (res://bench_check.gd:18)
   GDScript backtrace (most recent call first):
       [0] _ready (res://bench_check.gd:18)

Cast a physics ray: fail

The task: Write res://line_of_sight.gd for Godot 4: a script extending Node2D with first_hit(from: Vector2, to: Vector2) -> Vector2 that casts a physics ray through the 2D world from `from` to `to` and returns the point where it first hits a collider, or `to` when it hits nothing. It is called from physics processing.

Failed on the first try (SCRIPT ERROR: Parse Error: Identifier "this" not declared in the current scope.) and after one fix (SCRIPT ERROR: Parse Error: Function "get_collision_mask()" not found in base self.).

What Godot 4.7.2 printed on the first try:

Godot Engine v4.7.2.stable.mono.official.ed1daf0bf - https://godotengine.org

SCRIPT ERROR: Parse Error: Identifier "this" not declared in the current scope.
   at: GDScript::reload (res://line_of_sight.gd:18)
   GDScript backtrace (most recent call first):
       [0] _ready (res://bench_check.gd:4)
SCRIPT ERROR: Parse Error: Identifier "Physics2DServer" not declared in the current scope. Did you mean to use "PhysicsServer2D"?
   at: GDScript::reload (res://line_of_sight.gd:17)
   GDScript backtrace (most recent call first):
       [0] _ready (res://bench_check.gd:4)
ERROR: Failed to load script "res://line_of_sight.gd" with error "Parse error".
   at: load (modules/gdscript/gdscript_resource_format.cpp:46)
   GDScript backtrace (most recent call first):
       [0] _ready (res://bench_check.gd:4)
SCRIPT ERROR: Invalid call. Nonexistent function 'first_hit' in base 'Node2D'.
   at: _ready (res://bench_check.gd:21)
   GDScript backtrace (most recent call first):
       [0] _ready (res://bench_check.gd:21)

A path on a grid around walls: fail

The task: Write res://path_finder.gd for Godot 4: a script extending RefCounted with find_path(size: Vector2i, walls: Array[Vector2i], from: Vector2i, to: Vector2i) -> Array[Vector2i] that returns the shortest path of grid cells from `from` to `to`, both included, on a grid of `size` cells, never entering a wall cell and moving only up, down, left or right.

Failed on the first try (SCRIPT ERROR: Parse Error: Cannot call on an expression. Use ".call()" if it's a Callable.) and after one fix (SCRIPT ERROR: Parse Error: Cannot call on an expression. Use ".call()" if it's a Callable.).

What Godot 4.7.2 printed on the first try:

Godot Engine v4.7.2.stable.mono.official.ed1daf0bf - https://godotengine.org

SCRIPT ERROR: Parse Error: Cannot call on an expression. Use ".call()" if it's a Callable.
   at: GDScript::reload (res://path_finder.gd:8)
   GDScript backtrace (most recent call first):
       [0] _ready (res://bench_check.gd:4)
ERROR: Failed to load script "res://path_finder.gd" with error "Parse error".
   at: load (modules/gdscript/gdscript_resource_format.cpp:46)
   GDScript backtrace (most recent call first):
       [0] _ready (res://bench_check.gd:4)
SCRIPT ERROR: Invalid call. Nonexistent function 'new' in base 'GDScript'.
   at: _ready (res://bench_check.gd:9)
   GDScript backtrace (most recent call first):
       [0] _ready (res://bench_check.gd:9)

Build and play an animation in code: fail

The task: Write res://blinker.gd for Godot 4: a script extending Node2D that, when it enters the scene, creates an AnimationPlayer child and a looping animation named "blink", 1 second long, that keeps the node visible for the first half of each second and hidden for the second half, and plays it.

Failed on the first try (BENCH FAIL: visible at 0.25, 0.75, 1.25 and 1.75 s was [true, true, true, true], expected [true, false, true, false]) and after one fix (BENCH FAIL: visible at 0.25, 0.75, 1.25 and 1.75 s was [true, true, true, true], expected [true, false, true, false]).

What Godot 4.7.2 printed on the first try:

Godot Engine v4.7.2.stable.mono.official.ed1daf0bf - https://godotengine.org

SCRIPT ERROR: Parse Error: Identifier "this" not declared in the current scope.
   at: GDScript::reload (res://blinker.gd:18)
   GDScript backtrace (most recent call first):
       [0] _ready (res://bench_check.gd:4)
ERROR: Failed to load script "res://blinker.gd" with error "Parse error".
   at: load (modules/gdscript/gdscript_resource_format.cpp:46)
   GDScript backtrace (most recent call first):
       [0] _ready (res://bench_check.gd:4)
BENCH FAIL: visible at 0.25, 0.75, 1.25 and 1.75 s was [true, true, true, true], expected [true, false, true, false]

Wait for a signal or a timeout: fail

The task: Write res://waiter.gd for Godot 4: a script extending Node with wait_for(sig: Signal, seconds: float) -> bool, a coroutine that waits until the signal is emitted or `seconds` of game time pass, whichever comes first, and returns true if the signal came first. The signal has no arguments.

Failed on the first try (SCRIPT ERROR: Parse Error: Expected statement, found "void" instead.) and after one fix (SCRIPT ERROR: Parse Error: Cannot find member "is_emitted" in base "Signal".).

What Godot 4.7.2 printed on the first try:

Godot Engine v4.7.2.stable.mono.official.ed1daf0bf - https://godotengine.org

SCRIPT ERROR: Parse Error: Expected statement, found "void" instead.
   at: GDScript::reload (res://waiter.gd:17)
   GDScript backtrace (most recent call first):
       [0] _ready (res://bench_check.gd:4)
ERROR: Failed to load script "res://waiter.gd" with error "Parse error".
   at: load (modules/gdscript/gdscript_resource_format.cpp:46)
   GDScript backtrace (most recent call first):
       [0] _ready (res://bench_check.gd:4)
SCRIPT ERROR: Invalid call. Nonexistent function 'wait_for' in base 'Node'.
   at: _ready (res://bench_check.gd:13)
   GDScript backtrace (most recent call first):
       [0] _ready (res://bench_check.gd:13)

Questions

Is Nova 2 Lite good at Godot?
On these 15 tasks it passed 2 on the first try and 4 after one fix. Each task is small and checked by running it, so the score says whether its Godot 4 code works, not how well it designs a game.