Two fair-map matches showed MRP annihilating Stream by ~5min. Build-order
telemetry (new BALTYPES histogram in balance.lua) found the cause: Stream's
podfarm arrived at 5.8min vs MRP's merchtable at 1.7min, so the cheap-swarm
faction fielded 1 bufferbot against 17 djgrunts, and Stream spent 1500cr on the
Algorithm superweapon before it had an army.
Fixes:
* BuildingFractions: barracks 1 -> 10, factories 1 -> 6 so army buildings come
before tech. Result: podfarm 5.8min -> 2.5min, algorithm 3.3min -> 5.8min,
and Stream survived to 9.5min with 13 buildings instead of being wiped at 5.2.
* BuildingDelays on mastering/algorithm (4500) — no superweapon before an army.
* UnitsToBuild shares normalised. Reading UnitBuilderBotModule showed these are
PERCENTAGES of army composition, and mine summed to 233% per faction, which
made unit selection collapse to iteration order and starved Stream of infantry.
balance_report.py now emits a verdict (flatline / runaway / stalled production)
and refuses to judge matches under 5 minutes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Replaces the single flat grey tile. Adds tools/build_tiles.py (atlas builder
with edge-blending + tone matching), paint_terrain.py (surgical tile-plane
repaint: asphalt base, concrete pads, dirt blobs, groove patches near wax,
rubble clumps), jitter_wax.py, render_map.py (offline map preview), and
check_assets.py.
Also fixes the arena harness being rigged: both wax fields sat ~12 cells from
BotA and ~18 from BotB, so BotB starved for map reasons, not balance reasons.
Arena wax is now mirrored (7.1/18/18/19.8 from both starts). Seep interval
90 -> 20 after telemetry showed the slower rate still drained both economies.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>