Kepler, Newton, Godot


The first technical problem to solve for this project is physics. In particular, gravity.

I'm using the Godot game engine. Godot has a great physics engine on board, so gravity should not be a problem, right? It's not quite that simple.

In the game, I want to to able to have a large system of perhaps thousands of of stars, planets, moon's, asteroids, etc.  In theory they are all attracting each other. For for N bodies, there are N*(N-1) interactions, and for large N this is a lot of computation. This is known as the N-body problem. There are great solutions for this using the GPU. But I don't need to go that way, because these solutions don't solve my problem. Why? Because in general, for any system with N>=3, orbits are not stable, and I want all the bodies to be in stable orbits (except for players and some other smaller objects). Just like planets in the solar system that are in stable (mostly) circular obits.

Why stable orbits?

1. I want to be able to design star systems, i.e. plan where planets go, how fast they orbit, etc., because I need them to play a role in the stories in the game. If orbits are not stable, I won't know where they will be at later time in the game, they could be super far away, or crashed into star, etc. 

2. I want to be able to show the orbits of the bodies. That means: predicting the trajectory of a body for some period of time. If the trajectory is not a closed stable orbit, then computing the trajectory for even a short time is computationally expensive (and after a longer time useless due to rounding errors). Also, showing all these chaotic trajectories will create a jumble on the screen!

In Newton's physics, orbits are so called conic sections; which include circles, ellipses, parabola and hyperbola.  For my use case, circles are fine. (Ellipses might be nice to have too, I'll consider implementing those maybe later).

Stable orbits in Godot:

Actually, moving bodies in circular orbits, should be easy, much easier than the real gravity calculations. In game engines, like Godot, we can create trees of nodes, for example: one node is a star, and it's child nodes are planets, which may have moons as child nodes, etc. Over time, the planets rotate around the star, the moons rotate around the planets. Rotation of nodes is a basic operation in the game engine, so this should be easy to implement. 

I made in tool in Godot that allows you to place objects in circular obits. For each body it shows the circle that is the body's obit and a circle that is it's sphere-of-influence. The SOI is the area where the force of gravity by the body creates a significant acceleration (which I set, in this example, to 1 pixel/second^2). It also determines the orbital speed from the mass of the body around which another body is orbiting, using Kepler's laws. 

This is what it looks like:

The bodies in the orbit's can be any RigidBody (Godot objects under control of  Godot's physics engine).  Normally, when the physics engine applies gravity, a stable circular orbits is not guaranteed. So, I'm no using Godot's gravity. My code applies forces to keep the body in a perfect circular orbit for ever. But because I control the body via the physics engine, all the usual physics still works on the body. So other objects can collide with it, bounce, stick, slide, etc. And most importantly, we can land our spaceship on it!

Computing trajectories

Flying in orbits and execute orbital maneuvers takes practice and even with practice is not always easy. To make it a bit easier, the game should show where you are going, and also the orbits of the planets.

The orbits of the planets and other bodies in stable orbits are easy; they orbit in circles around their parent body. Actually, because the parent body may also be in orbit, these trajectories can create quite  interesting patterns!



The player's ship (and other small bodies such as NPC ships) are not in stable orbits; we want to be able to go from planet to planet after all. To compute these trajectories, we have to simulate gravity using Newton's law: 

f=G*m1*m2 / d^2 

where f is the force, G is the gravitation constant, m1 and m2 are the masses of two bodies and d is the distance between the bodies.

The force can be fed into the physics engine to make the body move. To compute the trajectory, we can't use the physics engine, but we have to compute the speed and position of the bodies ourselves, again using some more of Newton's work, his laws of motion. As the position of the body changes over time, we have to repeat the calculation many times with small time steps to create a trajectory . And in theory we have to compute the forces from all bodies in the star system. It will be quite expensive if there are many bodies. However, most bodies will be too far away to have a noticeable influence on trajectory. We use the SOI that we computed earlier to exclude all bodies that are too far away to have an significant influence.

The trajectory that we have computed in this way, is in global coordinates, i.e with respect to a fixed point in the universe (0,0). Like the pretty patterns created by nested circles in the picture above, these trajectories are not very practical for navigation, because the whole star system may be moving. Instead of the trajectory in global coordinates, we should show a trajectory that is relative to another body, which I call the reference body. Which body is the reference? There are several possible ways to choose, but for now I've chosen it to be the body that has the strongest gravitational influence. Along the trajectory, the reference body can change. That means that there will be a jump in the visualization of the trajectory when you approach a different body.

This is what the effect looks like in the game:

In the video you can also see a number of dots with different sizes plotted on the trajectories. These indicate where the object will be on the trajectory in 1,2,4,8,16 (etc.) seconds from now. 

The current visualization is too technical-looking;  for the game I'm looking for a more friendly style. Also, the planets look very simple. A simple procedural generator creates the geometry of the planets and moons, but in the future they should be created by more interesting algorithms or designed by hand. Also, it looks like some work on collision shapes is needed, because now the rocket sometimes sits just above or inside the surface of the planets. But that's for another time. 

If you got this far, thanks for reading! Let me know what you think.

Leave a comment

Log in with itch.io to leave a comment.