From 622447c45bf6edb6bb67cda31bf04cac441bb848 Mon Sep 17 00:00:00 2001 From: Malte Langkabel Date: Tue, 4 Aug 2026 15:24:31 +0200 Subject: [PATCH] correct the belt subsystem interface description in architecture.md The section documented a 5-method port interface and claimed "no other system ever asks what is on tile X". The real surface is 15 methods and peekItem does ask exactly that, so the doc was misleading about a subsystem it exists to explain. It also showed a tryPutItem signature that no longer matches. Describes what is there now, grouped by purpose, and separates the two claims that had been conflated: item transport is still port-only, but tile topology is genuinely coupled to BuildingSystem because belts are Buildings for cost and construction. The v2 migration note is qualified accordingly. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01YHcUerKAZKWNvSKJxYKbnG --- 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