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.
| Do not write | Write 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.