Why we started over

The first attempt
Before the current project there was an earlier one with the same idea: a toy for wrecking buildings, in the spirit of an older destruction game we like. It built its buildings from voxels (small cubes), drew them with Three.js in a browser engine wrapped in a desktop shell, and ran its physics single-threaded, in WebAssembly, on the main thread.
It was an experiment that kept growing until it was unusable, and with about six buildings at once it started to fail. Part of the trouble was the voxels. They made the math easy, but the voxel compute and the physics could not keep up. The project had also tried to build too much at once, including a grand story, when it should first have been a place to take a building down.
What we scoped for the restart
On September 28, we decided to try again with a narrower goal and set these terms:
- The first stage is an engine that holds up. Custom or existing both count, as long as it can carry what we want to do with it.
- No Unity, which was too much for this project, and no Java, which is not efficient enough.
- The game is Mac only, and it is for us to play. If anyone else gets to play it, that is a bonus.
- Prefer structural destruction to voxels: buildings that break along their structure.
- The first playable is one procedurally generated building at a time that can be respawned. A tiny house, a set of silos, a very tall skyscraper or a stadium would all do, each with real structure and debris that looks plausible when it comes down.
- Later, the player flies, with rifles, bombs and remote charges, and the world grows toward a larger one with more buildings.
- Not wanted: people in the world, automatic defenses, a grand story.
The planning that followed, recorded in the brief, added two decisions. Buildings should fracture and render the way real buildings would, and the architecture should leave room for terrain, trees and water later.
What carried over
The restart kept the earlier project’s measurements. The architecture notes list them as rules.
| Earlier measurement | Rule in the restart |
|---|---|
| A voxel collider on a moving body cost 98 times a plain box | No mesh or voxel colliders on moving bodies. Debris is a convex hull (a solid with no dents) or a group of them |
| 800 resting pieces cost 0.06 ms a step, against 11.87 ms awake | Resting debris is nearly free and awake debris is not, so settling is a feature |
| About 3,300 draw calls, roughly 70% of them in the shadow pass | All opaque geometry is drawn in one call per pass |
| Contacts with the static world cost about 30 µs each in the full scene, against 1.4 µs alone, and the cause was never found | Measure those contacts instead of assuming them |
A step here is one tick of the physics simulation, 1/60 s. A draw call is one batch of geometry sent to the graphics chip.
We added a lesson about how the earlier project was measured. It was tuned on clean scenes without rubble, and slowed to a crawl once debris built up. The restart’s rendering gate draws six intact buildings with 20,000 fragments lying around them, so a result includes rubble.
What the restart measured differently
The same kind of test, rubble in a building compared with rubble on flat ground, cost about 20 times as much in the earlier project. On the physics library the restart uses, it costs 1.3 times as much. The earlier project never found why its number was so high, so the comparison shows the new stack does not have the problem. It does not explain the old one.
The decision record also lists what was considered and set aside, with the reasons as of September 29:
- Unity, which we ruled out.
- Godot, which is built around its editor and had open reports of freezes in its Mac renderer.
- Bevy, kept as the fallback if the flat-ground numbers failed.
- NVIDIA’s Blast and PhysX 5, which do not run on macOS.
- Apple’s SceneKit and RealityKit, which have no fracture support.
The stack that stayed is Swift and Metal with the Jolt physics library, compiled from source.
How this post was made
- Drafted by
- A Claude Code session in the trilithon.games repository, October 10, 2026, working from the game's changelog, docs and tracker.
- What it did
- Drafted this post from the game's brief, architecture notes and engine decision record, and checked each number against them.
- Reviewed by
- Alex van Rossum,
On the roadmap: Physics, built from source