isPlacementValid, findRotateInPlaceTarget and the bodyCellsWithinWorldBounds
helper become PlacementRules.h — where a building may go and what already sits
on those tiles, answered from the factory state and the config. getInputPorts
and getSiteSplitterInfo join FactoryQueries.h, whose header comment now says
plainly that the last two also take the config because answering them means
reading a building definition.
computeInputPorts goes to PortGeometry.h alongside outputBodyTile/inputBodyTile:
it needs only Port and QPoint, so it belongs in core rather than in sim.
BuildingSystem is left with no query that reads the factory — its remaining const
methods are the emerging/incoming item walks, the checksum fold, and the buffer
initialisers. It changes the factory now; it no longer describes it.
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
The eleven forwarding members added last commit are gone; callers now read the
data directly through FactoryQueries.h. Simulation and ArenaSimulation expose
getFactoryState() so the UI, the balancing view and the tests can reach it.
isQueuedForDeconstruction joined the free functions along the way — it only
reaches findBuilding, so it was state-pure too.
No facade was introduced. The chained form was the reason one looked attractive,
but rewriting sim.getBuildings().findBuilding(id) to findBuilding(sim.getFactoryState(), id)
turned out to be mechanical, and the result says which data is read rather than
which system happens to own it.
BuildingSystem.cpp is down to 1735 lines and no longer answers questions about
the factory — it only changes it. What remains on it are the mutators, the tick
phases, and the queries that also need GameConfig.
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
Ten queries that read nothing but FactoryState become free functions in
FactoryQueries.h; the BuildingSystem methods stay as one-line forwards, so no
existing caller moves yet.
That lets the AI path drop its dependency on the system entirely. AiSystem,
SalvagerSystem, DeliverScrapEvaluator and DeliverScrapExecutor took a
BuildingSystem& purely to call findBuilding, findNearestBuilding and
deliverScrapToSalvageBay — all three are state-pure — so they now take
FactoryState& and say what they actually read. Four forward declarations of
BuildingSystem go with them.
No facade: the queries are plain free functions over the data. A facade was
considered to spare the ~180 UI call sites, but the AI needed only the data and
would have been given GameConfig it has no use for.
isProductionBuildingType moves to BuildingType.h beside isAutoRecipeBuildingType
and isBeltSubsystemType rather than being copied into the new file.
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