Fast Spaceship Physics

Last Friday’s post Leading Design Challenges identified the need for a simulation model that could unify gameplay inside and outside of spaceships. To me this implies a physics system that is far reaching enough to handle the manoeuvre and collision of large and complicated ships, whilst stable enough to frame character gameplay inside of those ships. Given the complexity of the game’s inspirations, the simulation system would ideally be able to cope with numerous complex ship designs. I therefore believe the speed of the simulation, the amount of work computers need to perform, should be the main design target. The target of a fast simulation rules out doing things properly. With true physics driven deformation calculations such as the finite element method simply being too computationally expensive to underpin real time gameplay.

In this post I’ll walk through my prototyping of a simulation that meets this brief. As prototyping is inherently transient I will focus on the logic and concepts of a design, rather than specific code implementations. A lot of my prototyping is done in Mathematica, which helps me iterate quickly and make visualisations.

Lightning fast

Vanilla model, sped up five fold

Vanilla model, sped up five fold

In the search of speed, things need to be as simple as possible. A central source of complexity in a physics engine is the number of different things that need to be considered simultaneously in order to make an update. To advance time in a realistic system, all of the physically connected components need to be considered together. Looking for speed, we can instead use for the simplest possible connectivity systems, and look at the smallest possible components of those systems. A spring based physics system is made up of points connected by lines, or springs. This means a simple update for a spring system could have each point looking down lines it is connected to, to its small pool of neighbouring points. So each point does not need to acknowledge a whole spaceship. In an iterative spring approximation, even these neighbours can be considered one at a time. This is a great basis for speed, but a host of issues can stem from ignoring the physics.

The prototype starts with data. This means a simple spaceship, imagined as a nest of scaffolding around an interior, with two rockets at the back. The points at the joins of this ship are written down as a list of coordinate values. The joins themselves are then written down as reference numbers into that list of points, telling us which two points each connection joins. Finally this information is used to calculate the length of each connection, as the Euclidean norm of the difference between the locations of the points at each end. The action of the rockets will be applied as movement to the two points that each one is connected to. I’ll set the leftmost rocket to move fifty percent faster than the other, and we should expect that differential thrust to result in some clockwise rotation for our ship.

A flowchart of the iterative spring frame logic

A flowchart of the iterative spring frame logic

The core of the iterative spring system is the chain from point locations, to point distances, to location changes. This is shown in the accompanying flowchart. These calculations are performed for each unit of time the physics engine advances. The central variable element in this process is the response function. This function tells us what change is selected for a point based on the compression of one of its connections. As a baseline, the difference between the point and the expected end of the connection would be multiplied by one minus the compression ratio. For a single connection, this would instantly return the point to equilibrium, where the connection is not compressed. When a point has multiple connections, this adjustment would be expected to compound, causing run away amplification of vibration. To combat this, a dampening factor is added. I’ve chosen 1/(2-Log[Compression]^2) for this factor, plotted in the figure below, which is logarithmically symmetric about the compression ratio. For small compression values, where the ratio remains close to one, this is perfect. Unfortunately, where the compression ratio deviates too far, this dampening can backfire, causing the whole system to instantaneously explode. The upshot of this is that the forces in this vanilla implementation of iterative spring physics must always be kept low to keep the system stable. The result of that, as visualised above, is a result that can be computed extremely quickly, but that can only cope with extremely gentle and elastic forces and motions. One solution to this is to run the procedure many times, for example calculating ten physics frames for each rendering frame of the game. However this would inflate the cost of the method, compromising the core ideal of speed. I will use this cheap system as a core, and see what can be done to improve its reliability and rigidity.

A plot of the vanilla dampening function

A plot of the vanilla dampening function

Derivatives kill vibration

Derivative model, real time

Derivative model, real time

The central problem with the initial iterative model is with runaway vibration. In short, problems occur whenever we observe symmetric over correction. A point is first adjusted too far in one direction, and then too far back in response, resulting in exponential amplification, and a break down of the model. The attempted solution of limiting speed is intended to ensure there are never any over corrections, but the result is not capable of the range of gameplay we would like to use. As the problem is with alternation, another solution is to make the changes to a derivative, rather than directly, and thus smooth out vibrations. This sounds complicated, and in an ideal simulation some formal mathematics might be warranted. In real time we don’t have computational resources to burn on all that, so a derivative model becomes incredibly simple. Where previously we would calculate the total change for each point and apply it directly, in a derivative system we instead keep adding these total changes into a running total value, and apply that running total to the point each frame. The result is a fantastic improvement. As this system is now effectively acting to create equilibrium within the moving system, we achieve more realistic acceleration and inertia, observing effects like drift. A limitation of this approach is the runaway intensity of the running totals caused by vibrations through the model. To address this, the total is slowly faded out, discarding one percent of each running total each frame. Whilst this system allows the simulation to handle much faster motions reliably, it also amplifies the elastic effects, with the motion of the test ship appearing more like that of a jellyfish than of a steel spacecraft.

Tracking energy

Energy model, real time

Energy model, real time

In the prototyping of the derivative spring iterative model above, several issues arose concerning analogies for energy. In contrast to a direct physics simulation, the derivative model is both creating and consuming motion with no side effects in various circumstances. Where two connections push a point in opposite directions, the point does not move. This effectively destroys the energy transferred out of those connections, but with no effect. Similarly, various vibrations amplify freely, creating motion without requiring proportional input. These energy concerns gave me an idea for how the derivative model might be improved. A visible issue with the derivative model is its response to large forces. As forces propagate through the chains of connections slowly, never jumping, the speed at which large changes pass from one edge of the ship to the other is not dissimilar to the speed at which a tiny change passes. This is one of the reasons large forces are generating so much vibration. The idea of tracking energy or strain at each point is am approach by which the transfer of motion could be accelerated, by amplifying the transfer of motion from strained areas of the ship to unstrained areas. A focal example of this would be of a new motion passing through the ship at rest. Without any energy modelling, the motion of a point towards and away from the motion is fairly symmetrical. Motion propagating away from the engines has no preference to the vibration causing motions passed back towards the engines. If the model were aware of the implied strain near the engines, this could raise the amount of movement directed towards motion, and lower the amount directed into vibrations.

This idea of energy tracking is prototyped with two energy sources. The first is where opposing motion cancels itself out at a point. The second is when a constraint tries to move a point too far in a single frame, storing the difference between the maximum movement and the attempted movement. Each of these energy vectors are placed into a running total for each point. That energy total for the points is then used to bias movement between points toward points with lower energy totals, multiplying the movements of the derivative model by the proportion of the point strain across each connection. As desired, this energy model is biased far more towards movement than the preceding prototype. The introduction of maximum movements for each connection provides a parameter which determines what proportion of movement is applied directly, and what proportion is converted to point energy. This begins to allow direct tuning of the elasticity of the movement of the ship.

The existence of increasingly high energies in scenarios of extreme vibration or rapid acceleration inspires a very direct avenue for introduction of destruction into the model. Where the forces are much higher than the permissible movement, we see large energy spikes in the points. These spikes could be good places for connections to start to deform or snap.

The next post on Friday will introduce destruction into the physics prototype.

Previous
Previous

Physical Destruction

Next
Next

Leading Design Challenges