Open-Source Wikis

/

Godot

/

Systems

/

Physics servers

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 backend

The 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:

  • Shapesshape_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).
  • Spacesspace_create, space_set_active. Each space is an isolated simulation; viewports map to spaces via World3D::get_space() / World2D::get_space().
  • Bodiesbody_create, body_set_mode (STATIC / KINEMATIC / RIGID / RIGID*LINEAR), body_add_shape, body_set_collision_layer, body_set_state, body_apply*\* (impulses, forces).
  • Areasarea_create, area_add_shape, area_set_* (gravity overrides, fluid, monitorable). Used for trigger volumes and gravity zones.
  • Jointsjoint_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 statebody_get_direct_state, space_get_direct_state for 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_2d and modules/godot_physics_3d are 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_physics wraps Jolt Physics (vendored under thirdparty/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 / signals

The 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_process at a fixed rate (physics/common/physics_ticks_per_second, default 60 Hz).
  • The WrapMT shim 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_fix and 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 calling PhysicsServer*::body_create, register their shapes via body_add_shape, and forward their transforms with body_set_state(BODY_STATE_TRANSFORM, ...).
  • The move_and_slide slide/snap algorithm in CharacterBody* is implemented on top of body_test_motion, which the backend implements server-side.
  • Picking input through PhysicsBody*::input_event and Area*::input_event requires Viewport::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 corresponding Shape3D resource and a node-side gizmo.
  • Writing an external physics backend → subclass PhysicsServer3DExtension, register it from a module's register_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.cpp and the constraint solver under modules/godot_physics_3d/joints/. For Jolt see modules/jolt_physics/.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Physics servers – Godot wiki | Factory