Commit Graph

51 Commits

Author SHA1 Message Date
7540c21d5c depend on factory data instead of BuildingSystem in the AI path
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
2026-08-04 21:26:49 +02:00
2522a8c974 move FactoryState ownership out of BuildingSystem to Simulation
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
2026-08-04 20:55:32 +02:00
e39b81eb22 gather the factory's world data into FactoryState
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
2026-08-04 20:39:34 +02:00
71d0dad3f2 give tile occupancy its own class, BuildingGrid
Eleven methods maintained m_tileOccupancy by hand — place, deconstruct,
removeBuilding, placeImmediate, tickDeconstruction, findRotateInPlaceTarget and
tryDirectCoupleDeposit all indexed a raw std::map<std::pair<int,int>, BuildingId>
directly, so the invariant "occupancy stays in sync with placement" was
re-implemented at every call site. They now ask and tell a small owned index
instead: occupy / release / isOccupied / findOwner.

BuildingGrid is a member of BuildingSystem, not a peer system: it has no
per-tick behaviour and nothing outside BuildingSystem touches it.

The internal keying stays std::pair<int,int> rather than moving to QPoint. The
checksum folds the entries in map iteration order, so the comparator is part of
the determinism contract; changing it is a separate decision, not a side effect
of this move. 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
2026-08-04 17:22:40 +02:00
fda88fe75c share BuildingSystem's free functions instead of copying them
Four of the five file-local helpers in BuildingSystem.cpp had duplicates
elsewhere: isAutoRecipeBuildingType and isBeltSubsystemType were re-spelled as
isAutoRecipeBuilding and isBeltLike in SelectedBuildingPanel.cpp, and
outputBodyTile was copied verbatim as portBodyTile in GameWorldView.cpp. Same
predicates, different names, so a change to one would silently not reach the
others.

The two BuildingType predicates move to BuildingType.h, which already hosts the
free functions over that enum and is already included by both lib and ui. The
port geometry moves to a new PortGeometry.h; inputBodyTile has no duplicate but
is outputBodyTile's counterpart and belongs beside it — the sim moves items
across the port edge and the renderer draws the virtual belt there, so the two
must agree on which tile a port owns.

inputLaneEntryFree stays file-local: single use, and tied to BeltItemSlot rather
than to building types or port geometry.

Verified the six moved bodies are character-identical to their originals.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YHcUerKAZKWNvSKJxYKbnG
2026-08-04 16:09:01 +02:00
993325d97c remove duplicate findBuildingDef from BuildingSystem
BuildingSystem::findBuildingDef was a byte-equivalent re-implementation of
BuildingsConfig::findBuildingDef. Same cleanup as the GameWorldView copy;
this one sits in the sim layer, so it was missed by both earlier passes.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GH8ZMRY3vhxxXcaUxBqxkk
2026-08-02 21:34:24 +02:00
84d32b6c16 add findShipDef/findModuleDef/findRecipeDef to config structs
Ships/Modules/RecipesConfig now carry lookup helpers mirroring
BuildingsConfig::findBuildingDef. The hand-rolled linear scans in
BuildingSystem, ShipSystem, ShipStatsCalculator, ThreatCostCalculator,
ShipLayoutDialog, SelectedBuildingPanel and SchematicChoiceDialog now
call them instead.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GH8ZMRY3vhxxXcaUxBqxkk
2026-08-02 20:42:24 +02:00
b722955f7e fix splitter filters being lost when rotating in place
rotateInPlace re-implemented the belt-tile re-registration switch inline
instead of calling reregisterBeltTile, and its splitter branch omitted the
setSplitterFilters call the canonical version has. Since an operational
splitter keeps its filters only in BeltSystem, removeTile discarded them and
rotating a configured splitter silently reset it to "accept all".

Replace the duplicated switch with a call to reregisterBeltTile, capturing
the filters beforehand via getSplitterInfo — the same idiom deconstruct
already uses. This removes the second copy of the switch that allowed the
two to drift apart in the first place.

Add a regression test; the existing [rotate-in-place] cases covered belt
tiles only, which is why this went unnoticed.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GH8ZMRY3vhxxXcaUxBqxkk
2026-08-02 20:22:53 +02:00
e20a0bba67 Rename Demolish to Deconstruct 2026-07-22 21:40:42 +02:00
b2ce20e6ad Add deconstruction queue 2026-07-22 21:37:56 +02:00
a75222f111 Never rotate tunnels in place 2026-07-21 21:14:27 +02:00
4ca5b332cd Snap belt-drag end tile to a building's input edge 2026-07-21 21:09:07 +02:00
1cbc695bc5 Add building status light 2026-07-20 22:19:58 +02:00
9622fa4345 Use std::optional instead of sentinel values for absent data 2026-07-20 20:27:20 +02:00
d412c69f82 Prefix all getters with "get" 2026-07-19 21:17:38 +02:00
486296feee Allow direct output-to-input port coupling between adjacent buildings 2026-07-14 20:23:24 +02:00
c9f14970a1 Animate items entering building input ports 2026-07-14 20:21:25 +02:00
6a8c456aa1 Animate items emerging from building output ports 2026-07-14 20:18:47 +02:00
dd7c997816 Auto-process smelter and reprocessing plant (no recipe selection) 2026-07-12 21:35:23 +02:00
cd966daba9 fix issue where shipyard produces ships with modules without requiring items for the modules if the ship's layout was never changed 2026-07-09 21:29:04 +02:00
88bc4f2170 fix bug where selecting the same ship again in a shipyard clears the layout and resets the progress 2026-07-09 21:05:01 +02:00
2ddf13238c Fix Salvage Bay drop-off not working by adding config-driven buffer capacity 2026-07-09 20:11:12 +02:00
e8786c3922 implement cost formula for asteroid expansion 2026-07-08 20:33:19 +02:00
d74ba5bfad Replay: deterministic record & playback (#4)
Add deterministic record/playback for a run.

Recording captures `(seed, config hash, ordered tick-tagged commands)` and re-simulates on playback — no state snapshots. `DotaFactory.exe --replay <file>` re-plays a recorded run view-only with manual speed/pause.

Reviewed-on: #4
Co-authored-by: Malte Langkabel <malte.langkabel@gmail.com>
Co-committed-by: Malte Langkabel <malte.langkabel@gmail.com>
2026-07-01 19:20:08 +00:00
d271d65678 allow to set the recipe already for construction sites 2026-06-22 22:15:56 +02:00
e5017ab3c5 fix issue where construction sites could be placed outside of game world and add tests 2026-06-22 21:13:01 +02:00
1ea1cc59fb show threat rate in debug output 2026-06-14 13:39:10 +02:00
54a6056b77 implicit item locking 2026-06-12 16:14:21 +02:00
6b95619806 add units in config files 2026-06-06 20:46:36 +02:00
abc261c03a add tracing for performance profiling 2026-06-05 16:38:36 +02:00
b57299fd2a rename EntityId to BuildingId 2026-05-23 07:53:56 +02:00
bd488db8ef remove unused building HP 2026-05-22 21:34:21 +02:00
4e3dc51981 fix stations were not drawn 2026-05-22 21:15:26 +02:00
9d20048705 cleanup 2026-05-22 20:45:10 +02:00
ca07cbaf0e switch to ECS architecture 2026-05-22 20:31:39 +02:00
d08bf5d37b implement ship modules 2026-05-18 08:54:26 +02:00
2770bf96be allow to rotate buildings in place 2026-04-29 21:51:04 +02:00
559dde96cf fix bug where buildings could not output directly on splitters 2026-04-27 21:38:11 +02:00
fb83db98ab rename blueprint to schematic 2026-04-26 21:00:55 +02:00
774f5dee28 read tunnel length from different config and fix tests 2026-04-26 20:41:40 +02:00
89005d6bb7 implement tunnels 2026-04-26 17:15:50 +02:00
55997ef851 store belts as buildings and fix issue that belts could not be selected 2026-04-24 21:09:28 +02:00
807ccc2ddf implement belts are now added to the build queue 2026-04-22 21:54:07 +02:00
f29dc9862a dont require output belts to be aligned with output ports 2026-04-22 21:15:39 +02:00
393c49e1bb fix issue where shipyard did not produce anything 2026-04-21 22:17:48 +02:00
79e89b524e implement returning full cost for buildings that get demolished in construction queue 2026-04-21 21:19:27 +02:00
2991a9584f show ports 2026-04-20 21:37:41 +02:00
46188bd9ca fix belts were not drawn 2026-04-20 21:18:14 +02:00
498b97db20 implement waves 2026-04-20 14:10:01 +02:00
65de4ddc5c implement ship behaviors 2026-04-20 08:29:53 +02:00