From 58e173ad5bfdacddfc97605a9e83c3dc48d33790 Mon Sep 17 00:00:00 2001 From: Malte Langkabel Date: Tue, 4 Aug 2026 21:38:30 +0200 Subject: [PATCH] move the asteroid width bound into FactoryState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It was the last piece of mutable world data BuildingSystem still owned, and the placement queries need it: isPlacementValid reaches it through bodyCellsWithinWorldBounds, so those queries cannot become free functions over FactoryState while the bound lives on the system. Left out of the checksum deliberately. It is derived from config and Simulation's expansion count, which is folded already, so adding it would change every checksum without adding information. Still seeded from config by BuildingSystem's constructor, which keeps the initialization at exactly the point it happened before; reset() clears the state before initializeSubsystems() rebuilds the system, so the ordering holds. Verified with a golden-checksum capture before and after — all four sample ticks identical. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01YHcUerKAZKWNvSKJxYKbnG --- src/lib/sim/BuildingSystem.cpp | 4 ++-- src/lib/sim/BuildingSystem.h | 3 +-- src/lib/sim/FactoryState.h | 6 ++++++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/lib/sim/BuildingSystem.cpp b/src/lib/sim/BuildingSystem.cpp index b5f16f7..1e77834 100644 --- a/src/lib/sim/BuildingSystem.cpp +++ b/src/lib/sim/BuildingSystem.cpp @@ -40,8 +40,8 @@ BuildingSystem::BuildingSystem(const GameConfig& config, , m_spawnShip(std::move(spawnShip)) , m_isItemUnlocked(std::move(isItemUnlocked)) , m_rng(rng) - , m_asteroidWidth_tiles(config.world.regions.asteroidWidth_tiles) { + m_state.asteroidWidth_tiles = config.world.regions.asteroidWidth_tiles; } // --------------------------------------------------------------------------- @@ -340,7 +340,7 @@ bool BuildingSystem::bodyCellsWithinWorldBounds(const std::vector& bodyC QPoint anchor) const { const int heightTiles = m_config.world.heightTiles; - const int leftEdgeX = -m_asteroidWidth_tiles; + const int leftEdgeX = -m_state.asteroidWidth_tiles; for (const QPoint& cell : bodyCells) { const QPoint worldCell = anchor + cell; diff --git a/src/lib/sim/BuildingSystem.h b/src/lib/sim/BuildingSystem.h index 89a7a99..469c841 100644 --- a/src/lib/sim/BuildingSystem.h +++ b/src/lib/sim/BuildingSystem.h @@ -77,7 +77,7 @@ public: // Sets the current buildable asteroid width in tiles. Grows the left // placement bound as the player unlocks asteroid expansions (REQ-EXP-UNLOCK). // Defaults to world.regions.asteroid_width_tiles at construction. - void setAsteroidWidth_tiles(int widthTiles) { m_asteroidWidth_tiles = widthTiles; } + void setAsteroidWidth_tiles(int widthTiles) { m_state.asteroidWidth_tiles = widthTiles; } // Mark a building or construction site for demolition (REQ-BLD-DECONSTRUCT). // A construction site is removed instantly and the full cost is returned. @@ -298,5 +298,4 @@ private: const std::optional&)> m_spawnShip; std::function m_isItemUnlocked; std::mt19937& m_rng; - int m_asteroidWidth_tiles; }; diff --git a/src/lib/sim/FactoryState.h b/src/lib/sim/FactoryState.h index 62e5966..46f2d1f 100644 --- a/src/lib/sim/FactoryState.h +++ b/src/lib/sim/FactoryState.h @@ -45,4 +45,10 @@ struct FactoryState // The authority on which building owns which tile; every placement and removal // path claims and releases its body cells here. BuildingGrid grid; + + // Current buildable asteroid width, the left bound for placement. Grows as the + // player buys expansions (REQ-EXP-UNLOCK). Deliberately not checksummed: it is + // derived from config and Simulation's expansion count, which is folded already. + // Seeded from config by BuildingSystem's constructor. + int asteroidWidth_tiles = 0; };