Files
settled-reach/docs/sprints/sprint-34/server.md
T
jpmschweitzerandClaude Sonnet 4.6 9d9ea96be1 chore(meta): plan Sprint 34: Pulse
Close Phase 2 — wire econ-sim into game server tick loop, expose price
history and trade flows via implant insert panel, add economics debug
console commands for runtime event injection and parameter mutation.

New tickets: #821 (server tick integration), #822 (IPC bridge v21),
#823 (debug command handler), #824 (economics insert panel),
#825 (debug console econ commands). Existing: #810, #785, #811, #748,
#814, #695. 11 tickets total across server, client, copy, planning.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 16:20:29 +02:00

124 lines
5.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Sprint 34: Pulse — Server Tasks
**Goal:** Close Phase 2 — wire the economics simulation into the live game, expose price history and trade flows in the implant, and make the economy observable and tweakable at runtime.
**Branch:** `sprint-34/server`
**Agents:** Dudley (simulation), Tyre (architecture)
## New Tickets
| # | Title | Blocked by |
|---|-------|------------|
| #810 | Event input port implementation | #809 (done) |
| #821 | Integrate econ-sim into game server tick loop | #810 |
| #822 | Expose economy state over IPC bridge to client | #821 |
| #823 | Economics debug command handler — event injection and parameter mutation | #821 |
## Key Decisions
- `decisions/economics.md` — D-178 (model architecture — Leontief + tâtonnement + agents), D-179 (stability criteria), D-180 (event input port — EconEvent struct and visibility modes), D-181 (7-signal vocabulary per node), D-183 (iterative dev cycle)
- `decisions/architecture.md` — D-020 (IPC architecture — ObserverSnapshot + PlayerAction), D-031 (tick-to-time mapping — 10 ticks = 1 game-minute)
## Notes
### #810 — Event input port implementation
The EconEvent struct (D-180) must be added to `tooling/econ-sim/src/model.rs` or a new `events.rs` module. The port is the typed interface through which all external disruptions enter the simulation. An event carries:
```
EconEvent {
target: Node | NodeSet | Corridor | TradeRoute | Currency | Commodity,
effect: ProductivityMultiplier | CapacityMultiplier | DemandShock | ExchangeShock,
duration: ticks,
visibility: Global | Proximate(hops) | Disclosed(specific_nodes) | Hidden,
}
```
Visibility modes are defined in D-180. For this sprint, only `Global` and `Proximate` need to be exercised — `Hidden` is Phase 3 territory (requires the player inspect verb). The port must accept events from: (a) the server tick loop (#821), and (b) debug commands (#823). Test: inject a supply shock, verify cascade propagates and prices recover within 200 ticks per D-179 Test 3.
### #821 — Integrate econ-sim into game server tick loop
The econ-sim is currently a standalone CLI binary at `tooling/econ-sim/`. This ticket makes it run inside the server process. Approach:
1. Extract the simulation logic from `tooling/econ-sim/src/main.rs` into a reusable library crate (e.g. `tooling/econ-sim/src/lib.rs` or a new `server/src/economy/` module — Tyre to decide the crate boundary).
2. Add a `bevy_ecs` `System` that advances the economy N ticks per game tick (rate TBD — likely 1 economy tick per 10 game ticks given D-031 tick-to-time mapping).
3. Store the current economy state as a `Resource` in bevy_ecs so downstream systems (#822, #823) can query it.
4. Economy state must include all 7 D-181 signals per active node so the bridge can later serialize the relevant subset.
Key files: `server/src/simulation/ticker.rs` (where per-tick systems run), `tooling/econ-sim/src/model.rs` (simulation state), `tooling/econ-sim/src/trade.rs` (tâtonnement step). The DB at `server/data/systems.db` is already populated from Sprint 33.
Do NOT load the econ DB on every tick — load once at server startup into the bevy_ecs Resource.
### #822 — Expose economy state over IPC bridge to client
Extend `ObserverSnapshot` to version 21 with an `economy_snapshot` field:
```rust
#[serde(default)]
pub economy_snapshot: Option<EconomySnapshot>,
```
`EconomySnapshot` carries per-system data for the client's economics panel (#824). Phase 2 deliverable is D-181 signals 12 only (price_current, price_trend). Struct sketch:
```rust
pub struct EconomySnapshot {
pub tick: u64,
pub nodes: Vec<EconNodeSnapshot>,
}
pub struct EconNodeSnapshot {
pub system_id: u32,
pub commodity_id: u32,
pub price_current: f64,
pub price_trend: f64, // delta over last N ticks
}
```
Add `EconStateQuery` to the `PlayerAction` enum for on-demand pulls — the client does not need economy data every tick (that would balloon snapshot size). The server responds to `EconStateQuery` by populating `economy_snapshot` on the next snapshot. Without a query, `economy_snapshot` is `None`.
Update `PROTOCOL_VERSION` to 21 in `server/src/bridge/types.rs`.
### #823 — Economics debug command handler
Extend `DebugCommandKind` in `server/src/bridge/types.rs` with three new variants:
```rust
/// Inject an economic event into the running simulation.
InjectEconEvent {
system_id: u32,
commodity_id: Option<u32>, // None = system-wide
effect: EconDebugEffect,
magnitude: f64,
duration_ticks: u32,
},
/// Mutate a tâtonnement parameter at runtime.
SetEconParam {
param: EconParamKind, // Alpha | Beta | CorridorFriction { system_a, system_b }
value: f64,
},
/// Return all 7 D-181 signals for a named system.
GetEconState {
system_id: u32,
},
```
Wire these into the existing debug command dispatch in `server/src/simulation/` (wherever `DebugCommandKind` is matched). Return results via `DebugResponsePayload.text` as a human-readable multi-line string. Blocked by #821 (economy resource must exist to query or mutate).
## Dependency Chain
```
#810 (event port) → #821 (server tick integration) → #822 (IPC exposure)
→ #823 (debug command handler)
```
#822 and #823 are parallel after #821 completes.
## PR Workflow
```bash
tea pr create --repo jpmschweitzer/settled-reach --login schweitz \
--title "feat(simulation): economics in-game tick loop and IPC bridge" \
--description "Sprint 34 server work" \
--base main --head sprint-34/server
```