Performance and limits
Hammerite is developed against a large imported reference level, and each slow path found on it is fixed and the measurement recorded in the commit that fixed it. The figures below are that level's, on an Apple Silicon Mac, and move as the work goes on. Measure your own levels with the benchmarks at the end.
The reference level
| brushes | 7,240 |
| rooms | about 1,800 |
| walls after carving | about 130,000 |
| entities | 2,200 |
| lightmap patches | about 4 million |
What it costs
| Opening, cold | the world is carved from scratch: of the order of a minute on the reference level. Saving writes a worldrep cache beside the map (level.worldrep.hcache), and opening with one is far faster |
| An edit | recompiles only what the edit's carves reach: about half a second on the reference level, and no pause to notice on a small one |
| Drawing, in the game | each room's walls are drawn only when the camera can see into it through the doorways, so the cost follows what is in view rather than the level's size |
| Navigation | building walkable ground and links takes over a minute on the reference level (#114); it runs on the compile's worker thread |
| Baking | 22 minutes on the reference level on a GTX 1070 Ti with the native kernel, nearly all of it light transfer (#125). Patch data is about 1.2 GB there |
These costs grow with the level. A level of tens of rooms carves in a fraction of a second and edits without a pause.
Keeping a level fast
- Save as
.hmap, and keep the worldrep cache with it. It is what makes opening fast; deleting it is safe but costs a full carve on the next open. - Overlap to extend a space, abut to divide one. Every air brush is a cell, and every pair that touches is a portal to find: dressing carved with many small air brushes costs more than the same shape in detail brushes.
- Detail brushes for dressing. They do not take part in carving, so they cost nothing at compile time beyond their own faces.
- Lightmap scale. A face's
lightmap_scale(16 units a texel by default) sets how many patches it makes. Coarser on large, dim surfaces is the biggest lever on bake time and memory.
Measuring
The benchmarks print timings rather than asserting them. Run one against the tests project:
godot --headless --path tests --script res://benchmark_compile.gd # carving, by level size
godot --headless --path tests --script res://benchmark_detail.gd # the cost of carving dressing
godot --headless --path tests --script res://benchmark_nav.gd # navigation build
godot --headless --path tests --script res://benchmark_persist.gd # save and load