Player Movement Diverges From Trajectory Preview

Godot Version

Godot Engine v4.4.1.stable.official.49a5bc7b6

Project

Bounce Platform Demo Project

Question

Hello, I’m developing a 2D platformer and encountering an issue with trajectory prediction. I have a bounce platform that launches the player with a specified direction and power. The gizmo also displays a trajectory preview line in the editor to help with level design.

The problem is that the player’s actual movement after being launched doesn’t perfectly match the trajectory preview.

The gizmo calculates the trajectory using bounce_direction, bounce_power, and gravity.

Both the gizmo and the player are using the same gravity value obtained from ProjectSettings.get_setting("physics/2d/default_gravity") (which is 768).

The player adds the gravity value to velocity:

velocity.y += ProjectSettings.get_setting("physics/2d/default_gravity") * delta

Interestingly, something that changes player’s actual path is affected by Engine.time_scale. At lower time scales, the player’s movement aligns more closely with the preview, while at higher time scales, the deviation is much more significant.

I think the issue might be with delta time and how I’m calculating it possibly. The gizmo calculates the trajectory in steps (preview_time_step = 0.01666666666667) (delta), and the player’s movement is using delta as well. Perhaps these aren’t perfectly synchronized? Or could small inaccuracies accumulate and become worse at higher time scales?



Yes. You are doing math with floats.

Math done using the float type is not guaranteed to be exact and will often result in small errors.

1 Like

I see, makes sense. Is there any way of correcting it or getting around that issue? Precision=Double on the engine maybe?

There may be a way to correct or get around it, but I doubt changing the precision of the game engine is it.

Float inaccuracy is inherent in all the programming languages I have worked with. That’s why special data types have been created for handling things like money.

1 Like

Physics simulation is always dependent on the delta time used in between steps. That’s because the simulation is a numerical integration problem which is always an approximation. The default method used in Godot (and most game engines) is called symplectic Euler which is good enough for most use cases, but has some error, and you can see it in your example because at different timesteps (prediction one vs physics engine one) the trajectories slightly diverge.

Short answer: In your case, the simple solution is to use the same timestep in your prediction as you use in the actual game so trajectories are the same.

Long answer: If you want to have a more timescale resistant prediction, you would have to implement a custom integration method, both in the prediction and in the physics. Unfortunately, implementing custom physics would be a major pain so you probably don’t need it for such a simple use case. If you want to go down this rabbit hole, here are some more references on different integration techniques and my implementation of them in Godot (not ready for general use). Also, no, you can’t use custom_integrator for this, as its implementation in Godot is kind of useless at the moment.

Note regarding the other answer: float has nothing to do with this. Float operations in the same order, on the same processor generate a deterministic result. This is a problem of error in the physics integration.

Edit: fixed my initial explanation of time_scale

1 Like