0.4.12 preview
Pre-releasePreview of Late Game Performance for Timberborn 1.1.2.4. Nothing new in this version has been played in-game yet. The latest release is still 0.4.9. It includes 0.4.10 (one checkbox on the settings page, played) and 0.4.11 (the tree search skips goods the building has no room for, not yet confirmed in a game).
Multiplayer: every player installs this same version. That is all. Nothing here is a setting that could differ.
New: the water check on every plant is read on worker threads
Every tick the game asks, for every plant and every other object that cares about flooding (about 8000 in the colony this is measured in), how high the water stands at its tile, one after another on the main thread: 1.3 ms per tick, 8% of all tick time. Almost none of them change from one tick to the next.
The question is a pure read of a water map the game already keeps safe for other threads, and which is never rewritten during this step. The reads are now spread over worker threads; then the main thread goes through the results in the game's own order and, for each object whose level changed, does exactly what the game does, so a plant starting to drown or a building flooding happens on the main thread, in the same order, with the same values. The result does not depend on the number of threads, so it is the same on every computer.
New: terrain route maps are rebuilt on worker threads
Every building that works the land around it (lumberjack flag, gatherer, farmhouse, forester...) keeps a second route map next to its road one, over open ground, 20 steps out. Every search for a tree or a plant reads it. When the ground changes inside one, the game rebuilds it on the main thread the next time its building searches.
Now every such map that is not built gets built at the end of the navigation tick, with the game's own generator on worker threads, and the main thread waits for the batch. It is a few tens of small maps (in the test harness 90 maps take 32 ms one by one and 7 ms on 7 workers), so this was built as a short wait, not as a background rebuild with gates like the road maps have. How often the ground changes in a real colony, and so how much this saves, has not been measured. The new TerrainMaps: stats line says how many were rebuilt and how long the main thread waited; if that wait ever matters, the background scheme can go under it.
Like the road maps, it builds maps before the first request instead of on it, so the few code paths that use a terrain map only "if it is already filled" find it filled. Every player on this version gets the same.
Removed: the hauling cache's district list
The cache kept each building's hauling jobs, and on top of that the district's whole sorted list until any building changed. In every session measured, on two computers, that list was never served from cache once: a hauler that takes a job reserves stock, which changes a building. It was code and bookkeeping with no effect. The per-building part, which is reused about a third of the time, stays. The HaulCache: stats line now reads 517 hauler list requests built in 310.0 ms (0.600 ms each); buildings reused 42010/129250, recomputed 87240.
New stats lines and startup line
[LateGamePerformance] Simulation features: HaulCache on, RouteMaps on, YielderSearch on, TerrainMaps on, PlantWater on. These are the same for every player on this version.
[LateGamePerformance] Last 1000 ticks. PlantWater: 1000 passes over 8100 objects on 7 workers; reading 240.0 ms (0.240 ms per pass), 310 level changes applied in 1.2 ms
[LateGamePerformance] Last 1000 ticks. TerrainMaps: 3 rebuilds of 96 terrain route maps on 7 workers; the main thread waited 9.5 ms in total, longest 4.1 ms; 5 more built directly in batches of fewer than 4
(The numbers in the last two are illustrations, not measurements.)
What was tested, and what was not
The harness passes against the installed game's assemblies; 47 patch targets resolve (4 new).
- Water: two identical sets of 6000 of the game's real
WaterObjects over a stand-in water map that moves between ticks; one set goes through the game's own loop, the other through the mod. Same stored levels and the same events, in the same order, with the same values, for six ticks (4316 level changes). A handler that throws switches the feature off and hands the tick to the game without applying anything twice. - Terrain: a terrain graph built with the game's
TerrainNavMeshGraph; 90 maps filled one by one and in parallel with the game'sTerrainFlowFieldGeneratorare identical node for node and in node order, a second batch on the same workers too. Against a realTerrainFlowFieldCache: everything cached gets built, a map whose start is off the graph is left alone, a second tick builds nothing, and after a ground change exactly the cleared maps are rebuilt. - Not tested: nothing here has run inside the game. Two things can only be seen there: that reading on worker threads is actually faster than the game's loop under Unity's runtime (the
PlantWater:line gives the read time per pass, to compare with 1.3 ms), and how often terrain maps are rebuilt.PlantWaterVerify = trueinLateGamePerformance.cfgre-reads everything on the main thread and compares;YielderSearchVerify = truedoes the same for the tree search. One session with both andverify mismatches 0in the stats lines is worth having.
If the game misbehaves, go back to 0.4.9 and send Player.log.
Install
- Close Timberborn. Delete any older
LateGamePerformancefolder, then extractLateGamePerformance-0.4.12.zipintoDocuments/Timberborn/Mods. - Requires the Harmony (2.4.1+) and Mod Settings Workshop mods.
SHA-256 of the zip: 62419d451f1033703bd52b465c077736e74ef77f8d04e61acd99c22f669d81d3