Velocity.x is being smoothly incremented in script but is very choppy in game

Godot Version

v4.6.3

Question

I’m trying to build a2D orbital physics sim but running into an issue I can’t find a fix for.

In the script for the character (space ship) I’m applying gravity as a force vector and adding it to the ships’ velocity. Then I add the velocity directly to the global_position. This is functioning fine in the Y axis, but in the X axis it appears as though the velocity is being rounded at “random” increments.

I’ve tried using move_and_slide() and move_and_collide() but the result is always the same.

#Calculate gravity and convert into a force vector
#grav = 1
var M = 600.0
var dist = self.global_position.distance_to(planet.global_position)
var gravity = grav * (M / (dist ** 2))
var theta = self.global_position.angle_to_point(planet.global_position)
var force = Vector2(gravity * cos(theta), gravity * sin(theta)) * simSpeed

#Other code here that doesn't affect velocity

#Add force vector to velocity (+ thrust if thrusting)
if Input.is_action_pressed("thrust"):
	velocity.x += (force[0] + (thrust * cos(self.rotation))) * delta
	velocity.y += (force[1] + (thrust * sin(self.rotation))) * delta
else:
	velocity.x += force[0] * delta
	velocity.y += force[1] * delta

#Add velocity to global position			
global_position += velocity *  simSpeed
print(velocity)
print(global_position)

#Other controls that don't affect velocity down here

Running this, in the output window I see my velocity climbing in both the x and y axis as I’d expect. The global position however does not change as expected. The y position begins to change immediately (as it should), but the x position doesn’t change until the x velocity has passed a seemingly arbitrary threshold. As I continue accelerating in the x axis, the x velocity keeps increasing linearly but the actual movement in the x axis continues to be incremented creating straight orbital paths that should be smooth curves.

Please help I’m loosing my mind

What is your global position? Is it significantly high, far away from zero? If so you may be experiencing a floating point rounding error which is exacerbated at high values.

It is quite high so could very likely be my problem.

Most large games will use world partitioning systems, keeping the player near the origin and loading distant places closer to the player, with a special Vector2i to mark which sector the player is.

Alternatively you can try to use a double precision build of Godot, this is a fair amount of work, has a lot of caveats, and doesn’t really solve the problem as much as give you a lot more world space.

Understood, thank you so much!

Or you can do what Team Curiosity did with SFS (Space Flight Simulator) and just scale everything down :slight_smile:

SFS on Steam

SFS on Google Play Store (Included in Play Pass sub with all DLCs)

Granted, you might already know it, but it’s a good example of a scaled down Solar System retaining realistic simulation while being accessible. It’s moddable, and easier to do so then in previous versions where you had to inject your mods’ code (C#), e.g. hack the exe.

Cheers ! Curious to see your progress, as Space simulations are dear to my heart. Countless hours spent in Orbiter and other sims/games.

True, scaling things down can make better use of your available value-range; same issues as using double-precision it can be difficult to convert to smaller units, physics will behave strangely, and it still doesn’t fix the issue, only giving you more room to work with.

Super large scale such as space games will make much better use trying to assume 1 unit = 1 kilometer instead of the usual 1 meter. Space games may implement their own physics though too since determinism and simulation accuracy matters more for the genre.

Changing the scale to 1 = 1km is actually a better idea than my suggestion!

Cheers !