Simulation (and ArenaSimulation in the balancing tool) now owns the factory's
world data; BuildingSystem holds a reference to it. This is what lets the systems
that operate on the data be handed the same state — phase 3's construction and
deconstruction systems, and later the ecs/system/ classes that today take a
BuildingSystem& only to query it.
reset() clears the state alongside m_admin and m_beltSystem, matching how the
subsystems were already rebuilt from scratch.
Falls short of the tick-argument form I sketched: BuildingSystem still reaches
the data through a member reference rather than a parameter. Making it truly
stateless means the const query surface has to find the data some other way, and
that surface is large — findBuilding alone has 64 call sites, with findSite,
getAllBuildings, getAllSites, isTileOccupied and the rest behind it. Doing that
needs a queries facade behind Simulation::getBuildings() so the callers do not
all move, which is its own decision rather than a side effect of this one.
The constructor gains a parameter, so the four owners and the three test fixtures
that build a BuildingSystem directly are updated; the 33 files that only use one
are untouched.
Verified with a golden-checksum capture before and after — all four sample ticks
identical.
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YHcUerKAZKWNvSKJxYKbnG
BuildingSystem is the one system in the codebase that owns the world data it
operates on. The ecs/system/ classes already do the opposite — AiSystem and
SalvagerSystem hold config and their own scratch, and take EntityAdmin and the
other systems as tick arguments — so this is bringing the outlier in line, not
inventing a pattern.
Phase 1 of that: the buildings vector, both work queues and the tile grid move
into a FactoryState struct, still owned by BuildingSystem. Every method reaches
through m_state. The public API is untouched, so none of the 33 files that
reference BuildingSystem needed a change.
DeconstructionEntry moves out of BuildingSystem's private section into
FactoryState.h, since the queue that holds it lives there now.
m_asteroidWidth_tiles stays on the system: it is not checksummed and is a cached
placement bound derived from config and the expansion count, not factory data.
The intent is for Simulation to own FactoryState and pass it into the tick
methods, leaving the systems stateless over it. FactoryState.h notes explicitly
that this is a data/behaviour split and not a step toward putting buildings in
the entity model, which architecture.md rules out.
Verified with a golden-checksum capture before and after — all four sample
ticks identical.
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YHcUerKAZKWNvSKJxYKbnG