From 64c344c3a31f4a26c0440f6df7baee0ab1b86d5e Mon Sep 17 00:00:00 2001 From: mlangkabel Date: Tue, 4 Aug 2026 18:12:02 +0200 Subject: [PATCH] correct the belt subsystem interface description in architecture.md --- docs/architecture.md | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/docs/architecture.md b/docs/architecture.md index 2765397..f541bd0 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -136,17 +136,43 @@ Belts and splitters are their own specialized subsystem. Belt items are **not** ### Public Interface -Narrow and representation-agnostic: +`BeltSystem.h` is authoritative. The surface is wider than the original design sketch — 15 public methods in five groups, not the 5-method port interface this section used to describe: ```cpp class BeltSystem { public: - bool tryPutItem(Port port, Item item); - std::optional tryTakeItem(Port port); + // Placement — belts/splitters/tunnels are Buildings for cost and + // construction, so BuildingSystem registers and unregisters their tiles. + void placeBelt(QPoint tile, Rotation direction); + void placeTunnelEntry(QPoint tile, Rotation direction, int maxDistance); + void placeTunnelExit(QPoint tile, Rotation direction); + void placeSplitter(QPoint tile, Rotation outputA, Rotation outputB); + void removeTile(QPoint tile); + + // Splitter filter configuration (REQ-BLD-SPLITTER). A splitter's filters + // live here, not on Building, so callers that re-register a tile must + // carry them across (see BuildingSystem::reregisterBeltTile). + void setSplitterFilters(QPoint tile, const std::vector& filterA, + const std::vector& filterB); + std::optional getSplitterInfo(QPoint tile) const; + + // Port interface (buildings <-> belts) + bool tryPutItem(QPoint tile, Item item, Rotation fromDir = Rotation::West); + std::optional tryTakeItem(Port port); + std::optional peekItem(Port port) const; + double getProgressPerTick_tpt() const; // shared so building output items + // travel at belt speed (REQ-MAT-OUTPUT-EMERGE) + + // Maintenance void clearTiles(const std::vector& tiles); // REQ-UI-BELT-CLEAR void tick(); + + // Rendering void forEachVisualItem(QRect viewportTiles, std::function visit) const; + + // Determinism (docs/replay_design.md) + void appendChecksum(Hasher& hasher) const; }; struct VisualItem { @@ -155,12 +181,12 @@ struct VisualItem { }; ``` -Buildings interact with belts only through port-level push and pull. Rendering reads only through `forEachVisualItem`. No other system ever asks "what is on tile X". +Item *transport* is still reached only through push and pull: `tryPutItem` / `tryTakeItem` move items, `peekItem` reveals the leading item's type but never an identity, and rendering reads only through `forEachVisualItem`. The growth is in tile **topology** — placement, removal and splitter filters — which `BuildingSystem` drives because belts are `Building`s for cost, construction and deconstruction. That coupling is real and is not going away. ### Implementation Strategy - v1: per-tile representation. Each belt tile stores up to 2 items with a progress value in `[0, 1]` along the tile's belt direction. Sufficient for the scale this game targets. -- v2 (optional, only if v1 profiles poorly): Factorio-style belt-segment compression. Because the public interface never exposes tile-level item identity, migration is internal to the subsystem. +- v2 (optional, only if v1 profiles poorly): Factorio-style belt-segment compression. The migration argument still holds for the item representation, since no method exposes tile-level item identity — but a v2 would have to keep the placement and splitter-filter methods working per tile, which is a stronger constraint than this section originally implied. ### Rendering Note