Can DeepSeek V4.1 Flash write working Godot 4 code? 15 of 15 on the first try
By Eduardo Orellana · Updated
DeepSeek V4.1 Flash passed 15 of 15 Godot 4 tasks on the first try and 15 of 15 after one fix with the test's output, each run headless on Godot 4.7.2. It missed none.
AppImage, x86_64. Ubuntu 22.04, Debian 12, Fedora 39 or newer.
Intel or AMD Chromebook, with Linux turned on.
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.
| Model | First try | After one fix | Agent | Run on | Read from |
|---|---|---|---|---|---|
| Claude Opus 5.5 | 15 of 15 | 15 of 15 | Claude Code | 2026-10-06 | Claude Opus 5.5 results |
| Claude Sonnet 5.5 | 15 of 15 | 15 of 15 | Claude Code | 2026-10-06 | Claude Sonnet 5.5 results |
| GPT-6.1 Sol | 15 of 15 | 15 of 15 | Codex | 2026-10-06 | GPT-6.1 Sol results |
| DeepSeek V4.1 Flash | 15 of 15 | 15 of 15 | Hosted, by API | 2026-10-18 | DeepSeek V4.1 Flash results |
| Ember-1 | 15 of 15 | 15 of 15 | Hosted, by API | 2026-10-18 | Ember-1 results |
| Gemini 3.1 Pro Preview | 15 of 15 | 15 of 15 | Hosted, by API | 2026-10-18 | Gemini 3.1 Pro Preview results |
| Muse Wonder | 15 of 15 | 15 of 15 | Hosted, by API | 2026-10-18 | Muse Wonder results |
| Kimi K3 | 15 of 15 | 15 of 15 | Hosted, by API | 2026-10-18 | Kimi K3 results |
| GPT-5.6 Luna | 15 of 15 | 15 of 15 | Hosted, by API | 2026-10-18 | GPT-5.6 Luna results |
| GPT-6 Luna | 15 of 15 | 15 of 15 | Hosted, by API | 2026-10-18 | GPT-6 Luna results |
| Hy4 preview | 15 of 15 | 15 of 15 | Hosted, by API | 2026-10-18 | Hy4 preview results |
| Pareto 26.10 | 15 of 15 | 15 of 15 | Hosted, by API | 2026-10-18 | Pareto 26.10 results |
| Claude Haiku 5.5 | 14 of 15 | 15 of 15 | Hosted, by API | 2026-10-18 | Claude Haiku 5.5 results |
| MiMo-V2.6-Pro-UltraSpeed | 14 of 15 | 15 of 15 | Hosted, by API | 2026-10-18 | MiMo-V2.6-Pro-UltraSpeed results |
| GLM 5.2 | 14 of 15 | 15 of 15 | Hosted, by API | 2026-10-18 | GLM 5.2 results |
| DeepSeek V4 Pro 0813 | 14 of 15 | 14 of 15 | Hosted, by API | 2026-10-18 | DeepSeek V4 Pro 0813 results |
| GPT-5.4 | 14 of 15 | 14 of 15 | Hosted, by API | 2026-10-18 | GPT-5.4 results |
| MiniMax M3 | 13 of 15 | 14 of 15 | Hosted, by API | 2026-10-18 | MiniMax M3 results |
| Qwen3.7 Max | 13 of 15 | 14 of 15 | Hosted, by API | 2026-10-18 | Qwen3.7 Max results |
| Fugu Max | 13 of 15 | 14 of 15 | Hosted, by API | 2026-10-18 | Fugu Max results |
| Beam 1.0 501B A23B | 12 of 15 | 14 of 15 | Hosted, by API | 2026-10-18 | Beam 1.0 501B A23B results |
| Mistral Large 4 | 12 of 15 | 13 of 15 | Hosted, by API | 2026-10-18 | Mistral Large 4 results |
| Claude Haiku 4.5 | 11 of 15 | 14 of 15 | Claude Code | 2026-10-06 | Claude Haiku 4.5 results |
| Nemotron 3.5 Super VL | 11 of 15 | 14 of 15 | Hosted, by API | 2026-10-18 | Nemotron 3.5 Super VL results |
| LongCat 2.0 | 11 of 15 | 13 of 15 | Hosted, by API | 2026-10-18 | LongCat 2.0 results |
| Grok 4.3 | 11 of 15 | 13 of 15 | Hosted, by API | 2026-10-18 | Grok 4.3 results |
| Laguna S 2.1 | 9 of 15 | 12 of 15 | Hosted, by API | 2026-10-18 | Laguna S 2.1 results |
| Nova 2 Lite | 2 of 15 | 4 of 15 | Hosted, by API | 2026-10-18 | Nova 2 Lite results |
How the test works
Each task asks for one GDScript file with a stated API, in a fresh Godot project. DeepSeek V4.1 Flash 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.
DeepSeek V4.1 Flash in Flockbay
DeepSeek V4.1 Flash is a hosted model in the Flockbay app's model menu, on the Hobby plan and above. It uses the plan's hosted usage at about 0.3 times the rate of Auto, so it lasts longer.
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: pass
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.
Passed on the first try.
extends CharacterBody2D
const SPEED := 200.0
func _physics_process(_delta: float) -> void:
if Input.is_action_pressed("ui_right"):
velocity.x = SPEED
else:
velocity.x = 0.0
move_and_slide()
Fall with gravity and land on the floor: pass
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.
Passed on the first try.
extends CharacterBody2D
## Downward acceleration, in pixels per second squared.
const GRAVITY := 980.0
func _physics_process(delta: float) -> void:
# Fall, unless we are resting on the floor.
if is_on_floor():
velocity.y = 0.0
else:
velocity.y += GRAVITY * delta
move_and_slide()
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.
extends Label
## Current total score.
var score: int = 0
func _ready() -> void:
_update_text()
## Adds points to the score and refreshes the label.
func add(points: int) -> void:
score += points
_update_text()
func _update_text() -> void:
text = "Score: %d" % score
Save and load a dictionary as JSON: pass
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.
Passed on the first try.
extends RefCounted
## Small helper for persisting a Dictionary as JSON.
##
## Usage:
## const SaveGame = preload("res://save_game.gd")
## SaveGame.save_data({"level": 3}, "user://save.json")
## var data := SaveGame.load_data("user://save.json")
## Serializes [param data] to JSON and writes it to [param path].
## Errors are reported through push_error() instead of halting the game.
static func save_data(data: Dictionary, path: String) -> void:
var file := FileAccess.open(path, FileAccess.WRITE)
if file == null:
push_error(
"save_data: cannot open '%s' for writing (error %d)."
% [path, FileAccess.get_open_error()]
)
return
file.store_string(JSON.stringify(data, "\t"))
file.close()
## Reads the JSON file at [param path] and returns it as a Dictionary.
## Returns an empty Dictionary if the file is missing, unreadable,
## not valid JSON, or does not contain a JSON object.
static func load_data(path: String) -> Dictionary:
if not FileAccess.file_exists(path):
push_warning("load_data: file '%s' does not exist." % path)
return {}
var file := FileAccess.open(path, FileAccess.READ)
if file == null:
push_error(
"load_data: cannot open '%s' for reading (error %d)."
% [path, FileAccess.get_open_error()]
)
return {}
var text := file.get_as_text()
file.close()
var parsed: Variant = JSON.parse_string(text)
if not (parsed is Dictionary):
push_error("load_data: '%s' does not contain a valid JSON object." % path)
return {}
return parsed as Dictionary
Health with signals: pass
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.
Passed on the first try.
extends Node
## Tracks a health value that never drops below 0.
##
## Emits [signal health_changed] whenever the value actually changes and
## [signal died] exactly once, at the moment health first reaches 0.
signal health_changed(old_value: int, new_value: int)
signal died
const MAX_HEALTH: int = 100
var health: int = MAX_HEALTH
var _is_dead: bool = false
## Returns true if the node is dead (health is 0).
func is_dead() -> bool:
return _is_dead
## Lowers health by [param amount], clamped to a minimum of 0.
## Emits health_changed when the value changes, and died once when it hits 0.
func take_damage(amount: int) -> void:
if amount <= 0:
return
if _is_dead:
return
var old_value: int = health
var new_value: int = maxi(health - amount, 0)
if new_value == old_value:
return
health = new_value
health_changed.emit(old_value, new_value)
if health == 0 and not _is_dead:
_is_dead = true
died.emit()
Fade out with a tween: pass
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.
Passed on the first try.
extends Node2D
## Emitted when a fade_out() finishes (or completes instantly for a
## non-positive duration).
signal faded
## Fades this node's modulate alpha from 1 to 0 over `duration` seconds.
## Emits `faded` when the fade ends.
func fade_out(duration: float) -> void:
modulate.a = 1.0
if duration <= 0.0:
modulate.a = 0.0
faded.emit()
return
var tween := create_tween()
tween.tween_property(self, "modulate:a", 0.0, duration)
tween.finished.connect(faded.emit)
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.
extends Node
## Spawns a new Node2D child every SPAWN_INTERVAL seconds,
## stopping once MAX_SPAWNS children have been created.
const SPAWN_INTERVAL := 0.25
const MAX_SPAWNS := 4
var spawned_count := 0
var _timer: Timer
func _ready() -> void:
_timer = Timer.new()
_timer.wait_time = SPAWN_INTERVAL
_timer.one_shot = false
_timer.autostart = false
_timer.timeout.connect(_on_timer_timeout)
add_child(_timer)
_timer.start()
func _on_timer_timeout() -> void:
if spawned_count >= MAX_SPAWNS:
_timer.stop()
return
var spawned := Node2D.new()
spawned.name = "Spawned%d" % (spawned_count + 1)
add_child(spawned)
spawned_count += 1
if spawned_count >= MAX_SPAWNS:
_timer.stop()
A door with states: pass
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".
Passed on the first try.
extends Node
## A door that can be interacted with.
##
## The door starts CLOSED. Calling interact() on a closed door puts it into the
## OPENING state; 0.5 seconds of game time later it becomes OPEN.
enum State {
CLOSED,
OPENING,
OPEN,
}
## How long (in seconds of game time) the door takes to open.
const OPEN_DURATION: float = 0.5
var _state: State = State.CLOSED
var _time_until_open: float = 0.0
func _ready() -> void:
_state = State.CLOSED
_time_until_open = 0.0
set_process(false)
## Starts opening the door if it is currently closed.
## Does nothing if the door is already opening or open.
func interact() -> void:
if _state != State.CLOSED:
return
_state = State.OPENING
_time_until_open = OPEN_DURATION
set_process(true)
func _process(delta: float) -> void:
if _state != State.OPENING:
set_process(false)
return
_time_until_open -= delta
if _time_until_open <= 0.0:
_time_until_open = 0.0
_state = State.OPEN
set_process(false)
## Returns "CLOSED", "OPENING" or "OPEN".
func get_state_name() -> String:
match _state:
State.CLOSED:
return "CLOSED"
State.OPENING:
return "OPENING"
State.OPEN:
return "OPEN"
return ""
An inventory with counts: pass
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.
Passed on the first try.
extends RefCounted
## A simple inventory that tracks item names and their quantities.
##
## Usage:
## var inv := Inventory.new() # or preload("res://inventory.gd").new()
## inv.add_item("potion", 3)
## inv.remove_item("potion", 1)
## print(inv.get_count("potion")) # 2
## Internal storage mapping item name -> quantity.
var _items: Dictionary = {}
## Adds `count` of `item_name` to the inventory.
## Non-positive counts are ignored.
func add_item(item_name: String, count: int) -> void:
if count <= 0:
return
_items[item_name] = get_count(item_name) + count
## Removes `count` of `item_name` if there are enough in the inventory.
## Returns true if the removal happened, false otherwise.
func remove_item(item_name: String, count: int) -> bool:
if count <= 0:
return false
var current: int = get_count(item_name)
if current < count:
return false
var remaining: int = current - count
if remaining == 0:
_items.erase(item_name)
else:
_items[item_name] = remaining
return true
## Returns the quantity of `item_name`; 0 if it was never added.
func get_count(item_name: String) -> int:
return _items.get(item_name, 0)
Load a level scene from a path: pass
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.
Passed on the first try.
extends Node
func load_level(path: String) -> Node:
var scene: PackedScene = load(path)
if scene == null:
push_error("Failed to load level scene at path: %s" % path)
return null
var level: Node = scene.instantiate()
add_child(level)
return level
Paint cells on a TileMapLayer: pass
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.
Passed on the first try.
extends TileMapLayer
## Paints and queries horizontal rows of tiles on a TileMapLayer.
##
## Tiles are written using tile source 0 and atlas coordinates (0, 0).
## Attach this script to a TileMapLayer node whose TileSet has a source
## registered with the id 0.
const SOURCE_ID: int = 0
const ATLAS_COORDS: Vector2i = Vector2i(0, 0)
## Paints every cell from (from_x, y) to (to_x, y) inclusive.
## Works with reversed ranges too: paint_row(3, 7, 2) paints x = 7, 6, 5, 4, 3, 2.
func paint_row(y: int, from_x: int, to_x: int) -> void:
var step: int = 1 if to_x >= from_x else -1
var x: int = from_x
while true:
set_cell(Vector2i(x, y), SOURCE_ID, ATLAS_COORDS)
if x == to_x:
break
x += step
## Returns true when the given cell has a tile placed on it.
func is_painted(cell: Vector2i) -> bool:
return get_cell_source_id(cell) != -1
Cast a physics ray: pass
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.
Passed on the first try.
extends Node2D
## Casts a ray through the 2D physics world from `from` to `to` and returns
## the point where it first hits a collider, or `to` if nothing is hit.
## Must be called during physics processing.
func first_hit(from: Vector2, to: Vector2) -> Vector2:
var space := get_world_2d().direct_space_state
var query := PhysicsRayQueryParameters2D.create(from, to)
# Exclude nothing by default; adjust here if you want to ignore self or groups.
var result := space.intersect_ray(query)
if result.is_empty():
return to
return result.position
A path on a grid around walls: pass
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.
Passed on the first try.
extends RefCounted
## Finds the shortest path between two cells of a rectangular grid.
##
## The grid has `size` cells (width x height), cells are addressed with
## Vector2i coordinates where x is the column and y is the row.
## Movement is restricted to the four orthogonal neighbours (up, down, left,
## right) and wall cells are never entered.
##
## Returns an Array[Vector2i] containing the path from `from` to `to`, both
## included, in order. Returns an empty array when no path exists or when the
## arguments are invalid (out of bounds, or `from` / `to` is a wall cell).
const DIRS: Array[Vector2i] = [
Vector2i(1, 0),
Vector2i(-1, 0),
Vector2i(0, 1),
Vector2i(0, -1),
]
func find_path(size: Vector2i, walls: Array[Vector2i], from: Vector2i, to: Vector2i) -> Array[Vector2i]:
var empty: Array[Vector2i] = []
if size.x <= 0 or size.y <= 0:
return empty
if not _is_inside(from, size) or not _is_inside(to, size):
return empty
var wall_set := {}
for wall in walls:
wall_set[wall] = true
# A wall cell can never be part of a path.
if wall_set.has(from) or wall_set.has(to):
return empty
if from == to:
var single: Array[Vector2i] = [from]
return single
# Breadth-first search: the first time we reach a cell is along a
# shortest path, so we only need to remember where we came from.
var start_index := _index(from, size)
var goal_index := _index(to, size)
var visited := {}
visited[start_index] = true
var came_from := {}
var queue: Array[Vector2i] = [from]
var head := 0
while head < queue.size():
var current: Vector2i = queue[head]
head += 1
if current == to:
break
for dir in DIRS:
var next: Vector2i = current + dir
if not _is_inside(next, size):
continue
if wall_set.has(next):
continue
var next_index := _index(next, size)
if visited.has(next_index):
continue
visited[next_index] = true
came_from[next_index] = current
queue.append(next)
if not visited.has(goal_index):
return empty
# Walk the parent chain backwards, then flip it.
var path: Array[Vector2i] = []
var cursor: Vector2i = to
while cursor != from:
path.append(cursor)
cursor = came_from[_index(cursor, size)]
path.append(from)
path.reverse()
return path
func _is_inside(cell: Vector2i, size: Vector2i) -> bool:
return cell.x >= 0 and cell.y >= 0 and cell.x < size.x and cell.y < size.y
func _index(cell: Vector2i, size: Vector2i) -> int:
return cell.y * size.x + cell.x
Build and play an animation in code: pass
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.
Passed on the first try.
extends Node2D
func _ready() -> void:
var player := AnimationPlayer.new()
add_child(player)
var anim := Animation.new()
anim.length = 1.0
anim.loop_mode = Animation.LOOP_LINEAR
var track := anim.add_track(Animation.TYPE_VALUE)
anim.track_set_path(track, NodePath(".:visible"))
anim.track_set_interpolation_type(track, Animation.INTERPOLATION_NEAREST)
anim.value_track_set_update_mode(track, Animation.UPDATE_DISCRETE)
anim.track_insert_key(track, 0.0, true)
anim.track_insert_key(track, 0.5, false)
anim.track_insert_key(track, 1.0, true)
var lib := AnimationLibrary.new()
lib.add_animation("blink", anim)
player.add_animation_library("", lib)
player.play("blink")
Wait for a signal or a timeout: pass
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.
Passed on the first try.
extends Node
## Every waiter that is still waiting is kept referenced until the end of the
## frame in which it resolved, so it can never be freed while the signal
## emission that resolved it is still on the call stack.
var _waiters: Array = []
## Waits for [param sig] to be emitted, or for [param seconds] of game time to
## pass, whichever comes first.
##
## Returns [code]true[/code] if the signal was emitted before the time ran out,
## [code]false[/code] otherwise. [param seconds] is game time, so it is affected
## by [member Engine.time_scale]. This is a coroutine, so it has to be awaited:
## [codeblock]
## if await wait_for(button.pressed, 2.0):
## print("the button was pressed in time")
## else:
## print("nobody pressed the button")
## [/codeblock]
func wait_for(sig: Signal, seconds: float) -> bool:
var waiter := _Waiter.new()
_waiters.append(waiter)
var on_signal: Callable = waiter._on_signal
var on_timeout: Callable = waiter._on_timeout
sig.connect(on_signal, CONNECT_ONE_SHOT)
var timer := get_tree().create_timer(seconds)
timer.timeout.connect(on_timeout, CONNECT_ONE_SHOT)
var signal_first: bool = await waiter.finished
# The race is over, so the losing side must not call into the waiter anymore.
if sig.is_connected(on_signal):
sig.disconnect(on_signal)
if timer.timeout.is_connected(on_timeout):
timer.timeout.disconnect(on_timeout)
# Let the emission that woke us up fully unwind before dropping the waiter.
_release_waiter.call_deferred(waiter)
return signal_first
func _release_waiter(waiter: _Waiter) -> void:
_waiters.erase(waiter)
## Resolves a single [method wait_for] call by emitting [signal finished] as
## soon as the awaited signal or the timer wins the race.
class _Waiter:
extends RefCounted
signal finished(signal_first: bool)
var _resolved := false
func _on_signal() -> void:
_resolve(true)
func _on_timeout() -> void:
_resolve(false)
func _resolve(signal_first: bool) -> void:
if _resolved:
return
_resolved = true
finished.emit(signal_first)
Questions
- Is DeepSeek V4.1 Flash good at Godot?
- On these 15 tasks it passed 15 on the first try and 15 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.
Related
- Claude Haiku 5.5 on the same tasks
- Claude Opus 5.5 on the same tasks
- Claude Sonnet 5.5 on the same tasks
- Ember-1 on the same tasks
- Gemini 3.1 Pro Preview on the same tasks
- GLM 5.2 on the same tasks
- GPT-5.6 Luna on the same tasks
- GPT-6 Luna on the same tasks
- Every verified Godot 4 answer
- Can Kimi K3 write working Godot 4 code? 15 of 15 on the first try
- Can Muse Wonder write working Godot 4 code? 15 of 15 on the first try
- Can GPT-5.4 write working Godot 4 code? 14 of 15 on the first try
- Can Fugu Max write working Godot 4 code? 13 of 15 on the first try
- Can MiniMax M3 write working Godot 4 code? 13 of 15 on the first try
Flockbay runs your own agent, Claude or ChatGPT on the official Godot 4.7.2, and gives it Godot's errors the way this test does.
Download Flockbay free