Godot 4.6 shipped with a change that the community has been anticipating for over a year: Jolt Physics is now the default 3D physics engine. Not an addon. Not a plugin you download from the asset library. The default.
This is a big deal. Jolt has been available as a third-party integration since Godot 4.0, and the community has been using it heavily through the godot-jolt addon. But "available as a plugin" and "the default engine" are fundamentally different things. Default means every tutorial, every template, every new project starts with Jolt. It means the core team is committed to maintaining it. It means GodotPhysics3D is now the alternative, not the standard.
If you're starting a new project, you get Jolt automatically. If you're migrating an existing project from 4.5 or earlier, you have work to do. This guide covers both scenarios.
What Changed and Why
GodotPhysics3D was Godot's custom-built physics engine. It worked. It was functional for many game types. But it had well-documented limitations: inconsistent collision detection at high velocities, performance degradation with large numbers of rigid bodies, and solver instability in complex constraint setups.
Jolt Physics is a C++ physics library originally developed by Jorrit Rouwe. It powers physics in several commercial game engines and has been battle-tested in shipped titles. The library focuses on deterministic simulation, high performance, and robust collision detection.
The Godot team didn't make this switch lightly. The decision came after years of community feedback, extensive benchmarking, and the practical reality that many serious Godot projects were already using godot-jolt anyway. Making it the default acknowledges what the community had already voted for with their project configurations.
What Stays the Same
The good news: the Godot physics API is largely unchanged. Your RigidBody3D, CharacterBody3D, Area3D, and StaticBody3D nodes work the same way from GDScript's perspective. The physics server abstraction layer means most of your code doesn't need to know or care which engine is running underneath.
# This code works identically on both engines
func _physics_process(delta: float) -> void:
var velocity = Vector3.ZERO
if Input.is_action_pressed("move_forward"):
velocity -= transform.basis.z
if Input.is_action_pressed("move_back"):
velocity += transform.basis.z
velocity = velocity.normalized() * speed
move_and_slide()
Signals, collision layers, collision masks, physics materials -- all the same API. If your project uses standard physics nodes through GDScript without directly accessing the physics server, your migration might be as simple as opening the project in 4.6 and testing.
Might be. We'll get to the complications.
What Actually Changed Under the Hood
Jolt replaces the physics solver, collision detection algorithm, and broadphase implementation. The PhysicsServer3D singleton still exists, but its backend is now Jolt. This means:
- Collision detection uses Jolt's GJK/EPA algorithm instead of GodotPhysics's SAT-based approach
- The constraint solver is Jolt's velocity-based solver, which handles stacking and complex joint chains better
- Broadphase uses Jolt's layered bounding volume hierarchy instead of GodotPhysics's octree
- Continuous collision detection (CCD) is now handled by Jolt's motion clamping and speculative contacts
The practical result: things that "mostly worked" in GodotPhysics now work reliably. Stacks of boxes don't jitter. Fast-moving objects don't tunnel through walls. Complex joint chains don't explode.
Performance Benchmarks
Let's talk numbers. The Godot team published benchmarks alongside the 4.6 release, and the community has been running independent tests. Here's what the data shows.
Rigid Body Stress Test
This is the classic "dump a thousand boxes into a scene" test. It measures how many active rigid bodies the engine can simulate at 60fps.
| Scenario | GodotPhysics3D (4.5) | Jolt Physics (4.6) | Improvement |
|---|---|---|---|
| 500 boxes, ground plane | 58 fps | 60 fps | Minimal (both handle this fine) |
| 1,000 boxes, ground plane | 42 fps | 60 fps | ~1.4x |
| 2,000 boxes, ground plane | 21 fps | 55 fps | ~2.6x |
| 5,000 boxes, ground plane | 8 fps | 38 fps | ~4.7x |
| 10,000 boxes, ground plane | 3 fps | 19 fps | ~6.3x |
The improvement scales with complexity. For small scenes with a few hundred physics objects, you won't notice a difference. For scenes with thousands of active rigid bodies, Jolt is dramatically faster.
Important caveat: These are synthetic benchmarks. Your actual game probably doesn't have 5,000 active rigid bodies in a single scene. The real-world improvement for most games is closer to 2-3x in physics-heavy scenarios, and negligible in physics-light scenarios.
Raycasting Performance
Raycasting sees significant improvement because of Jolt's broadphase structure.
| Scenario | GodotPhysics3D (4.5) | Jolt Physics (4.6) | Improvement |
|---|---|---|---|
| 100 raycasts/frame, simple scene | 0.3ms | 0.2ms | ~1.5x |
| 100 raycasts/frame, complex scene (500 colliders) | 1.8ms | 0.6ms | ~3x |
| 1,000 raycasts/frame, complex scene | 18ms | 5.2ms | ~3.5x |
If your game relies heavily on raycasts (FPS hit detection, AI line-of-sight, procedural placement), you'll see meaningful improvement.
CharacterBody3D Performance
Character controllers are where most developers will feel the difference.
| Scenario | GodotPhysics3D (4.5) | Jolt Physics (4.6) | Improvement |
|---|---|---|---|
| Single character, simple level | ~0.05ms | ~0.04ms | Negligible |
| 50 AI characters with move_and_slide | 3.2ms | 1.1ms | ~2.9x |
| 50 AI + complex terrain + slopes | 5.8ms | 1.9ms | ~3x |
For single-player games with one character controller, you won't notice. For games with dozens of AI agents using physics-based movement, the improvement is substantial.
What the Benchmarks Don't Tell You
These numbers measure physics simulation time in isolation. Your game's actual framerate depends on rendering, GDScript execution, audio, networking, and everything else. If your game spends 2ms on physics and 14ms on rendering, a 3x physics improvement saves you about 1.3ms per frame. Nice, but not transformative.
The benchmarks also don't capture stability improvements. Jolt doesn't just run faster -- it produces more stable simulations. Stacks don't collapse randomly. Objects don't clip through each other. Joints don't accumulate error. These qualitative improvements matter more than raw speed for many projects.
Migration Steps: 4.5 to 4.6
Here's the practical migration process. Follow these steps in order.
Step 1: Back Up Everything
This should go without saying, but: create a full backup of your project before upgrading. Git branch, zip file, whatever your backup method is. Do it.
# If you're using git (you should be)
git checkout -b pre-4.6-backup
git add -A
git commit -m "Backup before Godot 4.6 migration"
git checkout main
git checkout -b godot-4.6-migration
Step 2: Remove godot-jolt (If Installed)
If you were using the godot-jolt addon, remove it before upgrading. Godot 4.6 includes Jolt natively. Having the addon installed alongside the built-in Jolt engine causes conflicts.
- Delete the
addons/godot-joltdirectory - Remove any godot-jolt related entries from
project.godot - Delete the
.godotdirectory (it will be regenerated)
rm -rf addons/godot-jolt
rm -rf .godot
If you had custom Jolt settings configured through the addon's project settings, note them down first. You'll re-apply them through the new native settings interface.
Step 3: Open in Godot 4.6
Open your project in Godot 4.6. The editor will re-import assets and regenerate the .godot directory. This can take a while for large projects. Let it finish.
You'll likely see warnings in the output panel. Read them. Most are informational ("physics engine changed to Jolt"), but some may indicate actual issues.
Step 4: Check Physics Settings
Open Project > Project Settings > Physics > 3D. Verify that the physics engine is set to Jolt. Review the new Jolt-specific settings:
- Solver iterations: Default is 4. Higher values improve stability at the cost of performance. Most games are fine with 4. Complex joint setups might need 8-12.
- Solver velocity iterations: Default is 8. Controls velocity constraint resolution.
- Maximum angular velocity: Jolt has a different default here than GodotPhysics. If you had spinning objects calibrated to the old engine, check this.
- CCD mode: Jolt uses speculative contacts by default. You may want motion clamping for specific fast-moving objects.
Step 5: Test Collision Detection
This is where most migration issues surface. Run your game and check:
- Collision shapes: Do objects collide where you expect? Jolt's collision detection is more precise than GodotPhysics, which means some collisions that "sort of worked" before might behave differently.
- Edge cases: Objects sliding along walls, characters on slopes, objects stacked on each other. Test these specifically.
- Tunneling: If you had workarounds for fast objects passing through thin walls, test whether they're still needed. Jolt handles CCD much better, so some workarounds may now cause problems.
# If you had CCD workarounds like this, test if they're still needed
# Jolt's built-in CCD may conflict with manual approaches
func _physics_process(delta: float) -> void:
# Old workaround: manual raycast before movement
var space_state = get_world_3d().direct_space_state
var query = PhysicsRayQueryParameters3D.create(
global_position,
global_position + velocity * delta
)
var result = space_state.intersect_ray(query)
if result:
# Handle collision manually
global_position = result.position
else:
# Move normally
global_position += velocity * delta
# With Jolt, you might be able to just use:
# continuous_cd = true on the RigidBody3D and skip all this
Step 6: Test Joints and Constraints
Joints behave differently under Jolt's solver. The API is the same, but the solver's behavior means:
- HingeJoint3D: More stable. If you had high solver iterations to prevent hinge instability, try lowering them.
- Generic6DOFJoint3D: Jolt's implementation is more robust. Complex limit combinations that were unstable before should work.
- SliderJoint3D: Check your limit values. Jolt enforces limits more strictly.
- ConeTwistJoint3D: Better angular limit handling. Ragdolls should be more stable.
If you have ragdoll physics, this is a good time to revisit your joint limits. Jolt's stricter enforcement means limits that were slightly wrong but "close enough" in GodotPhysics might produce visible artifacts now.
Step 7: Test Physics Materials
Jolt handles friction and restitution (bounciness) differently at a solver level. The values you set are the same, but the resulting behavior may differ slightly.
- Friction: Jolt uses a friction combining mode. If two surfaces with friction 0.5 touch each other, the result might differ from GodotPhysics by a small amount.
- Restitution: Bouncy objects may bounce slightly higher or lower than before. Re-tune if needed.
If your game has carefully tuned physics (platformers, physics puzzles), budget extra time for this step. You may need to adjust values.
The Lighting Breakage Problem (4.5 to 4.6)
This deserves its own section because it catches a lot of people off guard. The lighting changes in Godot 4.6 are unrelated to the physics migration but happen at the same time, making the upgrade feel more disruptive than it needs to be.
Godot 4.6 includes changes to the rendering pipeline that affect how lights are calculated, particularly for OmniLight3D and SpotLight3D attenuation. If your project was authored in 4.5 or earlier, you may notice:
- Scenes appear darker or brighter than expected
- Light falloff curves look different
- Baked lightmaps need regeneration
- Volumetric fog density may need adjustment
This has nothing to do with Jolt. But because it happens during the same upgrade, people often conflate the two issues and spend hours debugging "physics lighting" that doesn't exist.
The fix: After upgrading, review your lighting setup independently of physics testing. Compare screenshots from 4.5 and 4.6. Adjust light energy values and attenuation parameters. Rebake lightmaps if you use LightmapGI.
Other Non-Physics Breaking Changes in 4.6
While you're migrating, watch for these unrelated 4.6 changes that can cause confusion:
- GDScript: Minor syntax changes around typed arrays and dictionary initialization
- Animation: AnimationPlayer has new blend modes that may affect existing animation trees
- Import: Some asset import settings have new defaults that trigger re-imports
- Editor: UI changes in the inspector for physics-related properties (new Jolt settings appear, old GodotPhysics settings are in a legacy section)
When to Use Jolt vs. GodotPhysics
Jolt is the default, but GodotPhysics isn't removed. You can still switch back. Here's when you might want to.
Use Jolt (Default) When:
- You're making a 3D game. Jolt is better than GodotPhysics3D in almost every measurable way for 3D physics.
- You need stable rigid body simulation. Stacking, ragdolls, complex constraints.
- Performance matters. Jolt is faster, especially at scale.
- You're using raycasts heavily. Jolt's broadphase handles raycast queries more efficiently.
- You need reliable CCD. Fast-moving objects that shouldn't tunnel.
Use GodotPhysics When:
- You're making a 2D game. This is the big one. Jolt is a 3D physics engine. GodotPhysics2D is unchanged and remains the default for 2D. Jolt doesn't replace it. If your game is 2D, none of this applies to you.
- You need exact behavioral parity with a 4.5 project. If your game is shipped and working with GodotPhysics3D, and you can't afford to re-tune physics behavior, switching back to GodotPhysics3D preserves existing behavior.
- You're targeting extremely low-end hardware. Jolt's memory footprint is slightly higher than GodotPhysics. On very constrained platforms, this might matter. On any modern PC, phone, or console, it won't.
- You have a very simple 3D game. If your game has a single kinematic character, no rigid bodies, and a static level, you won't benefit from Jolt. Either engine works fine. Use the default.
The 2D Question
People keep asking: "Does Jolt replace GodotPhysics2D?" No. Jolt is a 3D physics library. It doesn't do 2D. GodotPhysics2D continues to be the physics engine for 2D games. Godot 4.6 changes nothing about 2D physics.
If you're making a 2D game, skip this entire guide. Your physics engine didn't change. Your CharacterBody2D, RigidBody2D, and Area2D nodes work exactly as they did in 4.5.
There has been some community discussion about integrating Box2D as a similar upgrade for 2D physics, but nothing is confirmed for future releases.
Practical Migration Examples
Let's walk through some common scenarios.
Example 1: Platformer Character Controller
A typical 3D platformer character controller using CharacterBody3D.
extends CharacterBody3D
@export var speed: float = 5.0
@export var jump_velocity: float = 6.0
@export var gravity_multiplier: float = 2.5
func _physics_process(delta: float) -> void:
# Gravity
if not is_on_floor():
velocity += get_gravity() * gravity_multiplier * delta
# Jump
if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y = jump_velocity
# Movement
var input_dir = Input.get_vector("move_left", "move_right", "move_forward", "move_back")
var direction = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
if direction:
velocity.x = direction.x * speed
velocity.z = direction.z * speed
else:
velocity.x = move_toward(velocity.x, 0, speed)
velocity.z = move_toward(velocity.z, 0, speed)
move_and_slide()
Migration impact: Low. This code works identically on both engines. The move_and_slide() API hasn't changed. You might notice slightly different behavior on slopes or ledges because Jolt's collision resolution is more precise. Test slope sliding and edge detection.
What to check: If your character occasionally clipped through floors or walls in 4.5, that might be fixed now without any code changes. Conversely, if you were relying on slight collision imprecision (like sliding through narrow gaps), that might not work anymore.
Example 2: Physics-Based Puzzle Objects
A game with rigid body stacking puzzles.
extends RigidBody3D
@export var push_force: float = 10.0
@export var max_angular_velocity: float = 5.0
func _ready() -> void:
# Jolt handles angular velocity limits natively
# but you can still set this for extra control
physics_material_override = PhysicsMaterial.new()
physics_material_override.friction = 0.8
physics_material_override.bounce = 0.1
func _integrate_forces(state: PhysicsDirectBodyState3D) -> void:
# Clamp angular velocity for stability
if state.angular_velocity.length() > max_angular_velocity:
state.angular_velocity = state.angular_velocity.normalized() * max_angular_velocity
func apply_push(direction: Vector3) -> void:
apply_central_impulse(direction * push_force)
Migration impact: Medium. The code works, but behavior changes. Jolt's solver produces more stable stacks, which is great for puzzle games. However:
- Friction behavior may differ. A stack that was barely stable in GodotPhysics might be solidly stable in Jolt (or vice versa). Re-tune friction values.
- The angular velocity clamping in
_integrate_forcesmight interact differently with Jolt's own angular velocity limits. Test with and without the clamp. - Impulse response may feel different. The same
push_forcevalue might move objects more or less than before. Jolt's mass and inertia calculations are more physically accurate.
Example 3: Ragdoll System
Ragdolls are where you'll see the most dramatic improvement.
extends Node3D
## Activate ragdoll on the skeleton
func enable_ragdoll() -> void:
var skeleton = $Skeleton3D
for i in skeleton.get_bone_count():
var physical_bone = skeleton.get_bone_node(i)
if physical_bone is PhysicalBone3D:
physical_bone.simulate_physics = true
func disable_ragdoll() -> void:
var skeleton = $Skeleton3D
for i in skeleton.get_bone_count():
var physical_bone = skeleton.get_bone_node(i)
if physical_bone is PhysicalBone3D:
physical_bone.simulate_physics = false
Migration impact: High (but positive). Ragdolls in GodotPhysics3D were notoriously unstable. Limbs would stretch, joints would explode, bodies would clip through floors. Jolt fixes most of these issues. Your ragdoll code stays the same, but:
- Joint limits are enforced more strictly. If your joint limits were set loosely to prevent GodotPhysics from fighting itself, tighten them to anatomically reasonable values.
- Ragdolls settle faster. Jolt's solver converges more quickly, so ragdolls reach rest state sooner. This looks more natural.
- Collision between ragdoll parts is more reliable. Self-collision (arms not clipping through the torso) works better.
Review your PhysicalBone3D joint settings. The cone twist limits and hinge limits that worked "well enough" in GodotPhysics might need adjustment. Jolt's stricter enforcement means bad limits look bad instead of being silently compensated for.
Example 4: Vehicle Physics
Vehicle physics is a special case.
extends VehicleBody3D
@export var engine_force_value: float = 200.0
@export var brake_force_value: float = 50.0
@export var steering_speed: float = 2.0
@export var max_steer_angle: float = 0.5
var current_steer: float = 0.0
func _physics_process(delta: float) -> void:
# Throttle
var throttle = Input.get_axis("brake", "accelerate")
engine_force = throttle * engine_force_value
# Braking
brake = Input.get_action_strength("handbrake") * brake_force_value
# Steering
var steer_input = Input.get_axis("steer_right", "steer_left")
var target_steer = steer_input * max_steer_angle
current_steer = move_toward(current_steer, target_steer, steering_speed * delta)
steering = current_steer
Migration impact: High. VehicleBody3D is one of the areas where Jolt's behavior diverges most from GodotPhysics. The suspension model, tire friction curves, and drivetrain simulation all produce different results. Budget significant time for vehicle tuning.
Specific things to re-tune:
- Suspension stiffness and damping: Jolt's solver handles suspension differently. Start from scratch with tuning values rather than trying to preserve old ones.
- Wheel friction: The friction model produces different slip behavior. Drifting and traction feel different.
- Engine force: The same engine force value produces different acceleration because of how Jolt resolves the force application through the suspension and tire contact.
Comparison: Jolt vs. Chaos Physics (UE5)
If you work across engines -- or you're evaluating Godot vs. Unreal for a new project -- here's how Jolt in Godot compares to Chaos Physics in UE5.
| Feature | Jolt (Godot 4.6) | Chaos (UE5) |
|---|---|---|
| Rigid body performance | Excellent. Handles thousands of bodies efficiently. | Excellent. Similar scale capability. |
| Determinism | Deterministic across platforms (same binary). | Not deterministic by default. Requires specific configuration. |
| Cloth simulation | Not included. Use addon or custom solution. | Built-in cloth solver. |
| Destruction | Not included. Mesh cutting is separate from physics. | Geometry Collection destruction system. |
| Ragdolls | Good with proper joint setup. | Good. More tools for ragdoll authoring. |
| Vehicle physics | Basic VehicleBody3D. Needs manual tuning. | Chaos Vehicles plugin with more parameters. |
| Fluid simulation | Not included. | Not included in base. Niagara can fake it. |
| Soft bodies | Experimental. SoftBody3D exists but is limited. | Chaos deformables (experimental). |
| Ease of use | Simple API. Few settings to configure. | Complex. Many settings, powerful but overwhelming. |
| Source access | Open source. You can modify Jolt if needed. | Source available with license. |
The key takeaway: Jolt brings Godot's 3D physics up to professional quality for rigid body simulation. Unreal still has advantages in specialized areas like cloth, destruction, and vehicle physics -- but those are areas where Unreal has invested years of development across AAA titles.
For indie game physics needs (rigid bodies, character controllers, raycasts, basic joints), Jolt in Godot is competitive with Chaos in Unreal. The difference is in the advanced features and tooling around the physics engine, not the core simulation quality.
If you're working in Unreal and want to leverage AI to speed up physics setup and level design, the Unreal MCP Server provides 305 tools including physics-related operations for automating repetitive setup tasks across your project.
Common Pitfalls
These are the issues people hit most often during migration. Save yourself some debugging time.
Pitfall 1: Collision Shape Margins
Jolt handles collision margins differently than GodotPhysics. GodotPhysics used a margin value on collision shapes to improve solver stability. Jolt doesn't need this.
If you had collision margin set to non-default values, your collision shapes are effectively a different size than they appear visually. After migration, the margin behavior changes, and objects may collide at slightly different distances.
Fix: Set collision shape margins to 0 on all shapes and rely on Jolt's native collision detection. If you need a gap between visual mesh and collision response, adjust the collision shape size directly.
Pitfall 2: Physics Process Order
Jolt processes physics in a different order than GodotPhysics within a single step. If your code depends on specific ordering of physics callbacks (_integrate_forces being called in a particular sequence across objects), that order may change.
Fix: Don't rely on physics process order. If you need ordered operations, use signals or deferred calls to ensure correct sequencing.
Pitfall 3: Sleeping Thresholds
Jolt's object sleeping behavior is different. Objects go to sleep (stop being simulated) at different thresholds. An object that stayed awake in GodotPhysics might sleep in Jolt, or vice versa.
Fix: If you need objects to stay awake, set sleeping to false on the RigidBody3D or adjust the sleep threshold in project settings. If objects aren't sleeping when they should, check that their velocity is actually reaching zero (Jolt's threshold is different).
Pitfall 4: Area3D Overlap Detection
Area3D overlap callbacks may fire in a different order or at slightly different times under Jolt. The detection itself is the same (overlap is overlap), but the frame in which you receive body_entered or body_exited signals might differ by one physics frame.
Fix: Don't write code that depends on receiving area overlap signals in the same frame as the overlap occurs. Add a one-frame tolerance to any overlap-based logic.
Pitfall 5: Scale on Collision Shapes
Jolt is more strict about non-uniform scale on collision shapes. GodotPhysics tolerated some non-uniform scaling on shapes like BoxShape3D and CapsuleShape3D. Jolt may produce warnings or unexpected behavior.
Fix: Avoid non-uniform scale on physics nodes. If you need a stretched collision shape, change the shape's dimensions directly rather than scaling the CollisionShape3D node.
Pitfall 6: Kinematic Body Movement
If you're moving StaticBody3D or AnimatableBody3D nodes directly through code (setting global_position each frame), Jolt calculates velocity from the position delta differently. Objects riding on moving platforms or pushed by kinematic bodies may behave differently.
# Instead of setting position directly:
# global_position = target_position # Can cause issues
# Use AnimatableBody3D with sync_to_physics:
# Set the property in the inspector or:
func _ready() -> void:
sync_to_physics = true
func _process(delta: float) -> void:
# Move in _process, let physics interpolate
global_position = target_position
Fix: Use AnimatableBody3D with sync_to_physics enabled for moving platforms. This gives Jolt the velocity information it needs to properly interact with other physics objects.
Jolt Configuration Deep Dive
Once you've migrated, here are the Jolt-specific settings worth understanding.
Solver Settings
Found in Project Settings > Physics > 3D > Jolt:
# Key settings and their effects:
velocity_iterations = 8 # Higher = more stable stacking, slower
position_iterations = 4 # Higher = less penetration, slower
velocity_min_sleep = 0.03 # Lower = objects sleep faster
time_before_sleep = 0.5 # Seconds of low velocity before sleep
max_linear_velocity = 500.0 # Clamp for linear velocity (m/s)
max_angular_velocity = 47.1 # Clamp for angular velocity (rad/s)
For most games, the defaults are fine. Adjust if:
- Stacking is unstable: Increase
velocity_iterationsto 12-16 - Objects penetrate each other: Increase
position_iterationsto 8 - Objects don't sleep when they should: Lower
velocity_min_sleeportime_before_sleep - High-speed objects behave oddly: Increase
max_linear_velocity
Per-Object Settings
Individual RigidBody3D nodes have Jolt-specific properties:
- CCD mode: Enable for fast-moving objects. "Cast motion" is the default CCD mode in Jolt.
- Max contacts reported: Jolt can report more contacts per body. Useful for complex interactions.
- Linear/angular damping: Same API, but Jolt applies damping differently. Re-tune if your objects feel too floaty or too sluggish.
Layer Configuration
Jolt uses a layer system that maps to Godot's collision layers. However, Jolt internally optimizes based on layer interactions. Configure your collision layers thoughtfully:
- Use separate layers for static geometry, dynamic objects, characters, projectiles, and triggers
- Disable layer interactions that will never occur (projectiles don't need to collide with triggers)
- Jolt's broadphase uses layer information for optimization. Properly configured layers improve performance.
Automating Physics Setup with MCP
If you're setting up physics across a large Godot project -- configuring collision layers, setting up physics materials, testing collision shapes -- you can use the Godot MCP Server to automate repetitive physics configuration tasks. With 131 tools for Godot editor automation, it handles bulk operations like setting collision layers across multiple nodes, generating collision shapes for mesh libraries, and testing physics configurations programmatically.
This is especially useful during migration when you need to audit and update physics settings across an entire project.
What Doesn't Work (or Doesn't Work Well)
Honest assessment of Jolt's current limitations in Godot 4.6.
Soft Bodies
SoftBody3D in Godot 4.6 with Jolt is experimental. It works for basic cases (cloth-like simulation on simple meshes), but complex soft body setups are unreliable. If your project depends on soft body physics, test thoroughly.
Height Map Terrain Collision
Large HeightMapShape3D collision shapes can be slower in Jolt than GodotPhysics for some terrain configurations. This is a known issue. For very large terrains, consider using simplified collision meshes or multiple smaller collision shapes instead of a single large height map.
Debug Visualization
Jolt's physics debug visualization (visible in the editor viewport) shows different information than GodotPhysics's debug view. Contact points, broadphase regions, and sleep state visualization are different. If you relied on specific debug views for development, familiarize yourself with Jolt's debug rendering.
Determinism Across Versions
Jolt is deterministic within a single build. The same input produces the same output on the same binary. However, different Godot versions (even minor patches like 4.6.1 vs. 4.6.2) may update the Jolt version, breaking determinism. If your game requires cross-version determinism (replays, lockstep networking), pin your Godot version precisely.
Thread Safety
Jolt supports multithreaded physics internally, which Godot 4.6 leverages. However, accessing physics state from multiple threads in GDScript is still unsafe. The same threading rules apply: only touch physics from _physics_process or use call_deferred.
Migration Checklist
Here's a condensed checklist for your migration:
- Back up project (git branch or full copy)
- Remove godot-jolt addon if installed
- Delete
.godotdirectory - Open in Godot 4.6
- Verify physics engine is set to Jolt in project settings
- Test character controllers (slopes, edges, ledges)
- Test rigid body behavior (stacking, impulses, sleeping)
- Test joints and constraints (ragdolls, hinges, sliders)
- Test collision detection (area overlaps, raycasts)
- Re-tune physics materials (friction, restitution)
- Check vehicle physics (if applicable)
- Fix lighting changes (unrelated to physics but happens in same upgrade)
- Re-tune any finely calibrated physics values
- Remove CCD workarounds that Jolt handles natively
- Audit collision shape margins
- Test on target platform hardware
Budget 2-4 hours for a small project, 1-2 days for a medium project, and 3-5 days for a large project with complex physics. Most of that time is testing and tuning, not code changes.
Conclusion
Godot 4.6's switch to Jolt Physics is the right call. The performance improvements are real, the stability improvements are dramatic, and the API compatibility means migration is manageable.
If you're starting a new project, just use Jolt. It's the default for a reason.
If you're migrating, budget the time for testing and tuning. The code changes are minimal, but physics behavior changes require hands-on verification. Don't ship a Jolt migration without playing through your entire game.
And if you're making a 2D game, close this tab. Nothing changed for you.