From 7358ee322ed3b31a093840e5f3450d00436bb0c5 Mon Sep 17 00:00:00 2001 From: EugeneTes Date: Fri, 12 Jun 2026 13:26:23 +0000 Subject: [PATCH] Add design spec for probability-based space trading sim --- ...26-06-12-probability-trading-sim-design.md | 161 ++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 docs/superpowers/specs/2026-06-12-probability-trading-sim-design.md diff --git a/docs/superpowers/specs/2026-06-12-probability-trading-sim-design.md b/docs/superpowers/specs/2026-06-12-probability-trading-sim-design.md new file mode 100644 index 0000000..d9a5365 --- /dev/null +++ b/docs/superpowers/specs/2026-06-12-probability-trading-sim-design.md @@ -0,0 +1,161 @@ +# Probability — design spec + +A single-player space trading simulation in the browser. Inspired by Space Rangers. +The core conceit: NPC ships in systems the player cannot see exist as probability +clouds, not concrete positions. Entering a system collapses the clouds in it. +Probability is visible gameplay, not just an engine optimization: the player sees +clouds, stale prices, and aging intel, and trades on imperfect information — exactly +like every NPC does. + +## Goals + +- A complete, playable trading loop: fly, dock, buy low, sell high, reach a credit target. +- The probability mechanic is visible and legible: clouds on the map, intel that ages. +- A living galaxy of 100–200 NPC traders at near-zero simulation cost while unobserved. +- Deterministic, headless-testable simulation core. + +## Non-goals (v1) + +- Combat, named pirate units, missions, factions, sound, save/load. + (Pirates exist only as hazard fields. localStorage save is a v1.5 candidate.) +- Free 2D flight. All movement is graph-based, including inside systems. +- Multiplayer, server, persistence beyond a session. + +## World model + +- **Galaxy**: an undirected graph of ~25 systems connected by jump lanes, generated + from a seed with a roughly planar layout. +- **System contents**: one star, 1–3 planets, one jump gate per lane. Inside a system, + ships move along straight legs between gate(s) and planets — still a graph + (nodes: gates, planets; edges: legs). +- **Commodities**: 6 goods. Each planet produces some and consumes others at fixed + rates. Price is a deterministic curve over current stock (low stock → high price). +- **Hazard fields**: each lane has a pirate danger rating in [0, 1]. Danger feeds the + probabilities of bad branches for ships using that lane: delay, cargo loss, or + destruction. No individual pirate units exist in v1. + +## NPC model + +NPC traders (100–200) alternate between two states: + +- **Docked (concrete decision point)**: the NPC picks the best arbitrage opportunity + it knows about and plans a route. Decisions use *stale news*, not live state: + price snapshots propagate through the galaxy at a fixed speed (a few lanes per + game-day). This bounds decision cascades — an NPC's plan depends only on committed + history at planning time — and makes NPCs fallible the same way the player is. +- **In transit (branch tree)**: the plan is a tree of possible histories. Branch + points: route choice (weighted by NPC caution vs. lane danger), hazard outcomes + per lane (safe / delayed / cargo lost / destroyed), and fuzzy arrival times + (a time distribution per leg whose spread grows with legs traveled since the NPC + was last observed). + +**Hidden-variable determinism**: every NPC has a seed. Every branch outcome is drawn +deterministically from (seed, branch id). Outcomes are therefore fixed-but-unknown +from the moment a plan is made; observation merely reveals them. This guarantees +observation-order consistency (seeing a market first or the ship first always yields +the same history) and makes the sim reproducible for tests. + +## Probability clouds + +Because movement is graph-based, a cloud is one-dimensional: a weighted set of +lane/leg segments, derived analytically from the plan and elapsed time (no per-tick +integration). Properties: + +- Total mass is 1 across all branches/segments (invariant, asserted). +- Spread grows with time/legs since last observation. +- Observation that excludes branches (e.g., "the ore never arrived at B, so the + safe-and-on-time branch is dead") renormalizes the remainder — observing a market + sharpens the cloud of every ship entangled with it. + +## Markets and probabilistic trades + +Markets in unobserved systems hold **pending probabilistic transactions** +("+50 ore, 85% likely, arriving t=10–18") instead of applying trades on a schedule. +Anything needing a price meanwhile (NPC planning, news snapshots) uses the +expected (probability-weighted) market state. The concrete price exists only after +resolution. + +## Observation and collapse + +The player's current system is a **classical bubble** — fully concrete and simulated +in real time. All conversion happens at its boundary: + +- **Player enters a system**: every cloud with mass inside is sampled (from its seed): + the ship spawns concrete, or is excluded and its remaining cloud renormalized + outside. +- **While the player stays**: an **arrival queue** holds potential arrival events for + this system — every branch in every NPC tree that routes through it, plus new + plans made elsewhere as they are created. When an event comes due, roll it: ship + materializes at the gate, or the branch silently didn't happen. Traffic volume + emerges from trade-route topology; nothing is scripted. +- **Docking at a planet**: resolve that market's pending transactions in + chronological order → concrete stock and price. +- **A concrete ship jumps out / the player leaves**: concrete state re-fuzzes into a + tight cloud anchored at the last known position and time, spreading thereafter. + +## Time + +Real-time with pause and ×1 / ×4 / ×16 speed. Internally: a global event queue +(arrivals, plan completions, news propagation) plus a fixed sim tick (~10 Hz, +scaled by game speed) for in-system ship motion. Clouds cost nothing between +observations. + +## Player gameplay (v1) + +- Fly between systems via gates, dock at planets, buy/sell on a market screen, + manage credits and cargo capacity. Win: reach a credit target (e.g., 100,000 cr). +- Player ship is subject to the same lane hazards (cargo loss / delay; destruction + = game over). +- **Galaxy map intel layer**: + - Lanes tinted by hazard rating. + - Last-known prices per planet, displayed with their age ("ore 12 cr — 3 days old"). + The player's price knowledge updates by visiting or as news reaches their location. + - Probability clouds rendered as glowing smears along lanes — only for ships the + player has personally observed at least once. + +## Rendering + +- **PixiJS v8** on a single canvas, WebGL backend. +- **Two views**: galaxy map (systems = bright circles, lanes = dim lines, clouds = + bloomed smears) and system view (star = large bright circle, planets = circles, + ships = triangles sliding along legs, gates marked at the rim). +- **Neon look**: `AdvancedBloomFilter` (pixi-filters) over the world container; + simple flat-color geometry underneath. +- **UI as DOM overlay** (not canvas): market table, cargo panel, time controls, + hover tooltips. + +## Architecture + +``` +src/ + sim/ pure JS, zero rendering imports; deterministic given a seed + galaxy generation, economy, news propagation, NPC planning, + branch trees, clouds, observation/collapse, event queue, seeded RNG + render/ Pixi scene graph, two views, bloom, motion interpolation + ui/ DOM panels and tooltips + main.js game loop: advance sim, project state into render/ui +``` + +The sim exposes a small read API (system contents, cloud segments, market views, +player state) and a small command API (depart, dock, buy, sell, set speed). The +renderer and UI never mutate sim state directly. + +Plain JavaScript (ES modules), Vite for dev server and bundling, Vitest for tests. + +## Testing + +Headless tests against `sim/`: + +- Cloud invariants: mass sums to 1; renormalization after exclusion is correct. +- **Observation-order independence**: observing market-then-ship produces the same + committed history as ship-then-market (the per-seed hidden-variable guarantee). +- Economy sanity: prices respond to stock; NPC arbitrage narrows price gaps over time. +- Event queue: chronological resolution; arrival events match branch probabilities + over many seeds (statistical test). +- Determinism: same galaxy seed + same player inputs → identical end state. + +## Error handling + +Single-player browser game: invariant assertions in `sim/` (probability mass, +non-negative stock, queue ordering) that throw in dev builds. No network, no I/O +beyond the page.