Skip to content
Loadout

Fix

Godot 3 code in Godot 4

Answer

In Godot 4 use CharacterBody2D not KinematicBody2D; await not yield; @export not export var; set velocity then move_and_slide() with no args.

  • Godot 4.7.2-stable (18 August 2026)
  • GDScript 2.0

Last verified 2026-10-15

Agents still paste Godot 3 into a Godot 4 project. The names that show up are KinematicBody2D, yield, export var, and move_and_slide(velocity). The Godot 4 pack is written to stop that paste. It is pinned to Godot 4.7.2-stable (18 August 2026) and GDScript 2.0. The rename table on this page is the ban list copied from that pack.

Bodies are CharacterBody2D and CharacterBody3D. They own a velocity property, Vector2 or Vector3. Set velocity, then call move_and_slide() with no arguments. Do not pass the velocity, an up vector, or a delta into move_and_slide. Do not multiply horizontal velocity by delta. move_and_slide() applies the timestep. Gravity is the exception: velocity.y += gravity * delta before the call. Read input with Input.get_vector or Input.is_action_pressed, using actions from the Input Map. Do not hardcode key scancodes in gameplay code. Run movement in _physics_process, not _process.

Coroutines use await, not yield. yield(...) and yield(self, "completed") are on the ban list. A timer wait is await get_tree().create_timer(1.0).timeout. Designer-facing values use @export with a type and a default. onready var becomes @onready var, used to cache child nodes. Do not call get_node() every frame. Connect a signal with a Callable: button.pressed.connect(_on_pressed). Disconnect with disconnect. Emit with hit.emit(amount), not emit_signal("hit", amount). Declare the signal as signal hit(amount: int).

Load a fixed path with preload and instance it with instantiate(), not instance(). Change scene with get_tree().change_scene_to_file. Read and write files with FileAccess.open. List directories with DirAccess. Both are static. There is no File.new(). Spatial and SpatialMaterial become Node3D and StandardMaterial3D. rand_range(a, b) becomes randf_range(a, b). PoolStringArray and PoolIntArray become PackedStringArray and PackedInt32Array. change_scene("res://x.tscn") becomes change_scene_to_file("res://x.tscn"). OS.get_window_size() and OS.window_fullscreen move to DisplayServer window methods.

If a name is in the left column of the table, stop and use the right column. Last verified 2026-10-15. doc-verified; GDScript sample parsed by Godot 4.7.2 headless (--check-only), with a Godot 3 control script correctly rejected.

Godot 4 pack — GDScript 2.0 rules that refuse Godot 3 APIs.

doc-verified; GDScript sample parsed by Godot 4.7.2 headless (--check-only), with a Godot 3 control script correctly rejected

Sample from the pack

The movement sample in the Godot 4 rules file.

extends CharacterBody2D

@export var speed: float = 200.0
@onready var sprite: Sprite2D = $Sprite2D

func _physics_process(_delta: float) -> void:
    var input := Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
    velocity = input * speed
    move_and_slide()

Rename table

Godot 3, or removed, on the left. The replacement from the pack on the right.

Godot 3 names and the Godot 4 replacements copied from the pack
Do not writeWrite instead
`KinematicBody2D`, `KinematicBody``CharacterBody2D`, `CharacterBody3D`
`yield(...)`, `yield(self, "completed")``await`
`export var`, `export(int)`, `onready var``@export var`, `@onready var`
`move_and_slide(velocity)`set `velocity`, then `move_and_slide()`
`connect("pressed", self, "_on_pressed")``pressed.connect(_on_pressed)`
`emit_signal("hit", n)``hit.emit(n)`
`packed.instance()``packed.instantiate()`
`File.new()`, `Directory.new()``FileAccess`, `DirAccess`
`Spatial`, `SpatialMaterial``Node3D`, `StandardMaterial3D`
`rand_range(a, b)``randf_range(a, b)`
`PoolStringArray`, `PoolIntArray``PackedStringArray`, `PackedInt32Array`
`change_scene("res://x.tscn")``change_scene_to_file("res://x.tscn")`
`OS.get_window_size()`, `OS.window_fullscreen``DisplayServer` window methods

Sources in the pack

Questions

What should I write instead of Godot 3 code in Godot 4?
In Godot 4 use CharacterBody2D not KinematicBody2D; await not yield; @export not export var; set velocity then move_and_slide() with no args.
What replaces KinematicBody2D in Godot 4?
CharacterBody2D replaces KinematicBody2D, and CharacterBody3D replaces KinematicBody. Set velocity, then call move_and_slide() with no arguments.
Do yield and export var still work in Godot 4?
No. Use await, not yield(...) or yield(self, "completed"). Use @export var and @onready var, not export var, export(int), or onready var.
When was this Godot 4 rename list last checked?
Last verified 2026-10-15. doc-verified; GDScript sample parsed by Godot 4.7.2 headless (--check-only), with a Godot 3 control script correctly rejected.