Skip to content

Demo: N-Body Problem

This demo demonstrates N:N relationships in an ECS, and how to set up and simulate an arbitrary number of bodies in a generic way.

Source Code

This demo is available for the following:

MonoGameGodotFlax EngineUNIGINE UNIGINEStrideRaylib-csNeoAxis Engine NeoAxis Engine

Video (Godot Version)


Case in point here is not raw performance (although the basic GDscript-driven line trail rendering easily eats 90% of the Godot rendering time). Instead, note how short and concise the simulation loop stays - without as much as a single reverse lookup.

// Clear all forces
_accumulator.Blit(new Acceleration());

// Accumulate all forces (we have only 1 attractor stream, this will enumerate each sun 3 times)
_accumulator.For((ref Acceleration acc, ref Body self, ref Body attractor) =>
	if (self == attractor) return; // (we are not attracted to ourselves)

	var distanceSquared = Mathf.Max(0.001f, MathF.Pow(Vector2.DistanceSquared(attractor.position, self.position), 0.75f) / 100000f);
	var direction = Vector2.Normalize(attractor.position - self.position);
	acc.Value += direction * attractor.mass / distanceSquared / self.mass;

	// Just a pinch of dark matter to keep things together a bit more
	acc.Value -= self.position * 0.005f / self.mass;

// Integrate accelerations, velocities, and positions
uniform: (float)delta,
action: static (float dt, ref Acceleration accel, ref Velocity velocity, ref Position position) =>
	velocity.Value += dt * accel.Value;
	position.Value += dt * velocity.Value;

State and Structure are stored in the Components on the Entities:

  • 1x Body as Plain Component (contains mass and last position)
  • Nx Body as Entity-Entity Relation (once for each other body)
  • 1x Position, Velocity, Acceleration (for physics sim)

The state is transferred into the Game Engine directly talking to the Nodes.

fennecs is released under the MIT License. Neofox is released under the CC BY-NC-SA 4.0 License.