godotengine/godot
Physics servers
Purpose
Godot ships two physics APIs in parallel: PhysicsServer2D and PhysicsServer3D. Both are pluggable — backends register themselves with PhysicsServer3DManager / PhysicsServer2DManager and the active backend is selected by a project setting. The 3D side has two backends in-tree (Godot Physics and Jolt); the 2D side has one (Godot Physics).
Directory layout
servers/physics_2d/ PhysicsServer2D public API + WrapMT shim
├── physics_server_2d.{cpp,h}
├── physics_server_2d_extension.{cpp,h} Subclassing hook for module backends
└── physics_server_2d_wrap_mt.{cpp,h} Threaded shim
servers/physics_3d/ PhysicsServer3D public API + WrapMT shim
├── physics_server_3d.{cpp,h}
├── physics_server_3d_extension.{cpp,h}
├── physics_server_3d_dummy.h Inert backend (no simulation)
└── physics_server_3d_wrap_mt.{cpp,h}
modules/godot_physics_2d/ Built-in 2D backend
modules/godot_physics_3d/ Built-in 3D backend
modules/jolt_physics/ Jolt-based 3D backendThe 2D and 3D APIs are designed in parallel so concepts map cleanly between them. The rest of this page covers both; differences are called out where they exist.
Public API surface
PhysicsServer3D (physics_server_3d.h, ~41 KB header) groups methods into:
- Shapes —
shape_create_*for BOX, SPHERE, CAPSULE, CYLINDER, CONVEX_POLYGON, CONCAVE_POLYGON, HEIGHTMAP, WORLD_BOUNDARY, SEPARATION_RAY (3D) plus 2D-specific shapes (segment, world boundary, capsule, etc. in 2D). - Spaces —
space_create,space_set_active. Each space is an isolated simulation; viewports map to spaces viaWorld3D::get_space()/World2D::get_space(). - Bodies —
body_create,body_set_mode(STATIC / KINEMATIC / RIGID / RIGID*LINEAR),body_add_shape,body_set_collision_layer,body_set_state,body_apply*\*(impulses, forces). - Areas —
area_create,area_add_shape,area_set_*(gravity overrides, fluid, monitorable). Used for trigger volumes and gravity zones. - Joints —
joint_make_*for HINGE, PIN, SLIDER, CONE_TWIST, GENERIC_6DOF, plus 2D variants (PIN, GROOVE, DAMPED_SPRING). - SoftBody (3D only) — soft-body cloth-like simulation.
- Direct state —
body_get_direct_state,space_get_direct_statefor synchronous queries (raycasts, shape casts) inside_physics_process.
The 2D server mirrors this set under PhysicsServer2D, minus 3D-only types (cylinder, soft body, generic 6DOF joint, height map).
Backends
Godot Physics (built-in)
modules/godot_physics_2dandmodules/godot_physics_3dare the in-tree implementations. They are simple, dependency-free, and the historical default.- 3D backend includes broad-phase via
BVHTree/BroadPhase, narrow-phase via SAT for primitives + GJK/EPA for convex shapes, soft-body integration, and an iterative impulse solver. - 2D backend uses similar techniques with SAT for polygons and circles.
Jolt Physics
modules/jolt_physicswraps Jolt Physics (vendored underthirdparty/jolt). Jolt is faster and more accurate for complex scenes; it has become Godot's recommended 3D physics engine.- Selectable via
physics/3d/physics_engine = "Jolt Physics"in project settings.
See Modules — Jolt Physics for the integration details.
How a tick proceeds
sequenceDiagram
participant Tree as SceneTree
participant API as PhysicsServer3D (WrapMT)
participant Backend as Godot Physics / Jolt
participant Bodies as Body / Area / Joint state
participant Nodes as PhysicsBody3D / Area3D nodes
Tree->>API: physics_server.flush_queries()
Tree->>Tree: emit _physics_process(delta) on nodes
Nodes->>API: body_apply_impulse / body_set_state / area_get_overlapping_bodies
Tree->>API: physics_server.step(delta)
API->>Backend: integrate forces, broad-phase, narrow-phase, solve, integrate velocities
Backend->>Bodies: update transforms + sleep states
API->>Tree: body_state_callbacks emit transforms back to nodes
Tree->>Nodes: NOTIFICATION_TRANSFORM_CHANGED / signalsThe API hands transforms back to nodes via state callbacks (registered via body_set_state_sync_callback / body_set_force_integration_callback). RigidBody3D uses these to update its Node3D transform after each step.
Direct state
Physics queries (raycasts, shape casts, point queries, intersect-with-area) are issued through "direct state" handles:
PhysicsDirectSpaceState3D *space_state = get_world_3d()->get_direct_space_state();
PhysicsRayQueryParameters3D::create(from, to);
Dictionary hit = space_state->intersect_ray(query);These are synchronous, only valid inside _physics_process (or another physics step phase), and are how RayCast3D, ShapeCast3D, and high-level move_and_slide work internally.
CharacterBody3D::move_and_slide (defined under scene/3d/physics/character_body_3d.cpp) wraps body_test_motion with the slide/snap/floor-detection logic that platformer character controllers depend on.
Threading and steps
- The physics step is invoked from
SceneTree::physics_processat a fixed rate (physics/common/physics_ticks_per_second, default 60 Hz). - The
WrapMTshim allows the 3D physics step to run on a dedicated thread (physics/3d/run_on_separate_thread); body state callbacks run synchronously from there. - Sub-stepping happens via the project setting
physics/common/physics_jitter_fixand Jolt's own substep configuration. - Interpolation between physics ticks is handled by
SceneTreeFTI(variable-rate frames smoothly interpolate node transforms between fixed physics ticks).
Key abstractions
| Abstraction | File | Role |
|---|---|---|
PhysicsServer3D / PhysicsServer2D |
servers/physics_* |
Public API |
PhysicsServer3DManager / PhysicsServer2DManager |
servers/physics_* (in register_server_types.cpp) |
Backend registry |
PhysicsServer3DExtension / PhysicsServer2DExtension |
servers/physics_*_extension.h |
Subclass hook for backends |
PhysicsDirectBodyState3D / PhysicsDirectSpaceState3D |
inside physics_server_3d.h |
Synchronous body + space queries |
Shape3D / Shape2D resources |
scene/resources/3d/*_shape_3d.cpp and scene/resources/2d/*_shape_2d.cpp |
Editor-side shape resources that wrap server shape RIDs |
CollisionObject3D / CollisionObject2D |
scene/3d/physics/, scene/2d/physics/ |
Node base for any object with collision |
RigidBody3D, CharacterBody3D, StaticBody3D, AnimatableBody3D, Area3D |
scene/3d/physics/ |
Concrete physics nodes |
SoftBody3D |
scene/3d/physics/soft_body_3d.cpp |
Cloth-like soft body (Godot Physics + Jolt support) |
Integration points
- Nodes in
scene/{2d,3d}/physics/create RIDs by callingPhysicsServer*::body_create, register their shapes viabody_add_shape, and forward their transforms withbody_set_state(BODY_STATE_TRANSFORM, ...). - The
move_and_slideslide/snap algorithm inCharacterBody*is implemented on top ofbody_test_motion, which the backend implements server-side. - Picking input through
PhysicsBody*::input_eventandArea*::input_eventrequiresViewport::set_physics_object_picking(true)so the viewport can shoot a ray each frame and route the result. - The editor's gizmos for shapes, joints, and motion live in
editor/plugins/; they read shape resources and visualize them.
Entry points for modification
- Adding a new shape primitive → declare a new
PhysicsServer3D::SHAPE_*enum, add backend support, write a correspondingShape3Dresource and a node-side gizmo. - Writing an external physics backend → subclass
PhysicsServer3DExtension, register it from a module'sregister_module_types, and ship it as a module the user enables. - Tuning the solver → backend-specific. For Godot Physics see
modules/godot_physics_3d/godot_physics_server_3d.cppand the constraint solver undermodules/godot_physics_3d/joints/. For Jolt seemodules/jolt_physics/.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.