Physics2DDirectBodyState in Godot 4: it is PhysicsDirectBodyState2D now
By Eduardo Orellana · Updated
Physics2DDirectBodyState is called PhysicsDirectBodyState2D in Godot 4, the "2D" moving to the end like the rest of the physics classes. In a Godot 4 project, a variable typed Physics2DDirectBodyState fails to parse with Could not find type "Physics2DDirectBodyState" in the current scope.
AppImage, x86_64. Ubuntu 22.04, Debian 12, Fedora 39 or newer.
Intel or AMD Chromebook, with Linux turned on.
What Godot is checking
GDScript resolves every type annotation when the script loads. Physics2DDirectBodyState is not a class in Godot 4, so the analyzer stops with Could not find type and none of the script runs.
The converter carries Physics2DDirectBodyState to PhysicsDirectBodyState2D. It is what a RigidBody2D's _integrate_forces(state) receives: set linear_velocity on it, or read get_contact_count(), to control the body safely inside the physics step.
Reproduce it
A Godot 3 variable typed Physics2DDirectBodyState, in a Godot 4 project.
extends Node
var state: Physics2DDirectBodyState
func _ready():
print(state)
What Godot 4.7.2 prints
Godot Engine v4.7.2.stable.mono.official.ed1daf0bf - https://godotengine.org
SCRIPT ERROR: Parse Error: Could not find type "Physics2DDirectBodyState" in the current scope.
at: GDScript::reload (res://answers/physics2ddirectbodystate-in-godot-4/repro.gd:3)
ERROR: Failed to load script "res://answers/physics2ddirectbodystate-in-godot-4/repro.gd" with error "Parse error".
at: load (modules/gdscript/gdscript_resource_format.cpp:46)Fix it
A RigidBody2D whose _integrate_forces() caps its speed. get_class() prints the physics server's own subclass of it, which is what the engine hands you.
extends RigidBody2D
var reported := false
func _ready() -> void:
linear_velocity = Vector2(900, 0)
func _integrate_forces(state: PhysicsDirectBodyState2D) -> void:
state.linear_velocity = state.linear_velocity.limit_length(300)
if not reported:
reported = true
print(state.get_class(), " speed capped to ", state.linear_velocity.length())
What the fixed script prints
Godot Engine v4.7.2.stable.mono.official.ed1daf0bf - https://godotengine.org
GodotPhysicsDirectBodyState2D speed capped to 300.0Verified on Godot 4.7.2
Both scripts on this page were run headless on Godot 4.7.2 (4.7.2.stable.mono.official.ed1daf0bf) on 18 October 2026, and the output above is what Godot printed, unedited.
Where the check lives in Godot's source: [renames_map_3_to_4.cpp line 1565, Physics2DDirectBodyState to PhysicsDirectBodyState2D](https://github.com/godotengine/godot/blob/4.7.2-stable/editor/project_upgrade/renames_map_3_to_4.cpp#L1565), [PhysicsDirectBodyState2D class reference](https://github.com/godotengine/godot/blob/4.7.2-stable/doc/classes/PhysicsDirectBodyState2D.xml).
Questions
- Why change velocity in _integrate_forces() and not _physics_process()?
- Setting it on the state inside the step avoids fighting the solver, which overwrites velocity set from outside.
- What is the 3D class?
- PhysicsDirectBodyState3D, Godot 3's PhysicsDirectBodyState.
Related
- RigidBody in Godot 4: it is RigidBody3D now
- Physics2DServerSW in Godot 4: use the PhysicsServer2D singleton
- Every verified Godot 4 answer
- How to get collisions after move_and_slide() in Godot 4
- KinematicBody in Godot 4: it is CharacterBody3D now
- PhysicsDirectSpaceState in Godot 4: it is PhysicsDirectSpaceState3D now
- KinematicBody2D in Godot 4: Could not find base class "KinematicBody2D"
- Identifier "…" not declared in the current scope in Godot 4
Flockbay's agent reads Godot's debugger output and fixes errors like this one in your project, on the official Godot.
Download Flockbay free