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.
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.
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.
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.