From 13f480019160ba62d8ce79bf7e8b88d1a94b0604 Mon Sep 17 00:00:00 2001 From: mlangkabel Date: Sat, 18 Apr 2026 22:37:41 +0200 Subject: [PATCH] requirements for blueprint drops --- docs/architecture.md | 5 +++-- docs/requirements.md | 9 +++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/architecture.md b/docs/architecture.md index 9892882..5becaaa 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -64,10 +64,11 @@ Simulation types shared across subsystems: - `Port` — `struct Port { QPoint tile; Rotation direction; }`. Identifies a belt-adjacent cell and the direction of flow across that cell. - `MovementIntent` — `struct MovementIntent { int priority; QVector2D target; }`. Priority follows the order declared under Movement Arbitration. Cleared at the start of each tick; the highest-priority write wins; `tickMovement` reads the winner. - `FireEvent` — `struct FireEvent { EntityId shooter; EntityId target; Tick emittedAt; }`. Transient record emitted each time a weapon fires (REQ-SHP-FIRING, REQ-SHP-FIRING-BEAM). Buffered in a sim-owned queue and drained by the renderer; see Sim → UI Events. +- `BlueprintDropEvent` — `struct BlueprintDropEvent { ShipBlueprintId blueprint; int newLevel; bool wasNewUnlock; }`. Emitted when a destroyed enemy-defence-station set awards a blueprint (REQ-DEF-BLUEPRINT-DROP). The UI renders a toast (REQ-UI-BLUEPRINT-TOAST); `wasNewUnlock` chooses between the "unlocked" and "level → N" wording. ## Sim → UI Events -The sim owns a small set of per-frame event queues that the UI drains on each render. These carry one-shot signals that are not derivable from persistent state — notably weapon fires (REQ-SHP-FIRING-BEAM). Additional event types can be added here later (e.g., building-complete, unit-death flashes) without changing the pattern. +The sim owns a small set of per-frame event queues that the UI drains on each render. These carry one-shot signals that are not derivable from persistent state — currently weapon fires (REQ-SHP-FIRING-BEAM) and blueprint drops (REQ-UI-BLUEPRINT-TOAST). Additional event types can be added here later (e.g., building-complete, unit-death flashes) without changing the pattern. Implementation: a plain `std::vector` owned by `Simulation`, one vector per event type. Combat resolution (tick-order step 8) appends to it. The UI calls `simulation.drainFireEvents()` once per rendered frame, which returns the accumulated vector by move and clears the internal one. Beams are tracked by the renderer for 0.3 s of wall time (9 ticks at 30 Hz) using the events' `emittedAt` tick, then discarded. If either the shooter or target entity is gone when the renderer looks them up, the beam is dropped early. @@ -92,7 +93,7 @@ Within a single simulation tick, subsystems run in this fixed order. The order i 6. **Belt tick** — advance items along belt tiles; apply splitter routing (REQ-BLD-SPLITTER). 7. **Ship behavior systems** — clear `MovementIntent` on each ship, then run `tickThreatResponse`, `tickScrapCollector`, `tickRepairBehavior`, `tickHomeReturn` in any order (arbitration is via intent priority). 8. **Combat resolution** — ships and defence stations acquire targets, fire, apply damage; queue deaths. Each fire appends a `FireEvent` to the sim's fire-event queue (REQ-SHP-FIRING-BEAM). -9. **Deaths & loot** — process queued deaths: drop scrap (REQ-RES-SCRAP-DROP), drop blueprints (REQ-DEF-BLUEPRINT-DROP), remove entities. +9. **Deaths & loot** — process queued deaths: drop scrap (REQ-RES-SCRAP-DROP); if a full enemy-defence-station set was destroyed this tick, award one blueprint (REQ-DEF-BLUEPRINT-DROP) and append a `BlueprintDropEvent`; remove entities. 10. **`tickMovement`** — advance ship positions based on final `MovementIntent`. 11. **Scrap despawn** — decrement scrap timers; remove expired scrap (REQ-RES-SCRAP-DROP). diff --git a/docs/requirements.md b/docs/requirements.md index da38ce4..9f9ffa4 100644 --- a/docs/requirements.md +++ b/docs/requirements.md @@ -123,8 +123,8 @@ Output port indicators are not building tiles themselves. A building may have mo - REQ-DEF-ENEMY-PLACEMENT: 2 enemy defence stations are placed at the right boundary of the scrollable area at game start, and again each time a new set is spawned after a push. Stats scale with the station level (REQ-PSH-STATION-STATS). - REQ-DEF-ENEMY-FIRE: Enemy defence stations automatically fire at player ships within range. - REQ-DEF-NO-CROSSFIRE: Enemy and player defence stations are never in each other's firing range. -- REQ-DEF-PUSH: When both enemy defence stations in a set are destroyed, the push scaling multiplier is applied (REQ-PSH-ACCUMULATION), the scrollable area is extended (REQ-GW-PUSH-EXPAND), and a new set of enemy defence stations is placed at the new boundary. The destroyed stations drop ship blueprint loot (REQ-DEF-BLUEPRINT-DROP). -- REQ-DEF-BLUEPRINT-DROP: One ship blueprint is chosen uniformly at random from all blueprints defined in `ships.toml`. If the player does not yet have that blueprint, it is unlocked. If the player already has it, the blueprint's `[ship.blueprint].player_production_level` is incremented by 1 — so subsequent ships of that type are produced at a higher level. +- REQ-DEF-PUSH: When both enemy defence stations in a set are destroyed, the push scaling multiplier is applied (REQ-PSH-ACCUMULATION), the scrollable area is extended (REQ-GW-PUSH-EXPAND), a new set of enemy defence stations is placed at the new boundary, and exactly one blueprint drop is awarded for the destroyed set (REQ-DEF-BLUEPRINT-DROP). +- REQ-DEF-BLUEPRINT-DROP: Each destroyed set of enemy defence stations awards exactly one blueprint drop (not one per station). The drop is automatic — no physical item to collect. A blueprint is chosen uniformly at random from all blueprints defined in `ships.toml`. If the player does not yet have that blueprint, it is unlocked. If the player already has it, the blueprint's `[ship.blueprint].player_production_level` is incremented by 1 — so subsequent ships of that type are produced at a higher level. The player is notified via a toast (REQ-UI-BLUEPRINT-TOAST). ## Threat Level & Enemy Waves @@ -176,6 +176,11 @@ The screen is divided into three vertical sections: - REQ-UI-SCROLL: The player scrolls the view horizontally across the scrollable area by pressing A (scroll left) and D (scroll right). - REQ-UI-NO-ZOOM: The view has a fixed zoom level; the player cannot zoom in or out. +- REQ-UI-BLUEPRINT-TOAST: When a blueprint is unlocked or leveled up (REQ-DEF-BLUEPRINT-DROP), a transient notification toast appears in the top-right corner of the game world view for 4 seconds and then fades out. Toast text: + - **New unlock**: `Blueprint unlocked: ` + - **Level-up (duplicate drop)**: ` production level → N` (where N is the new level). + + If multiple toasts arrive in close succession, they stack vertically in a queue (most recent at the top) and each fades out independently after its own 4-second lifetime. - REQ-UI-HOTKEYS: Global keyboard shortcuts: - **Space** — toggles pause. Pressing Space pauses (sets speed to 0×) and stores the previously selected non-zero speed; pressing Space again restores that speed. - **W** — increases game speed by one step in the sequence 0×, 0.5×, 1×, 2×, 4× (no wrap-around past 4×).