A cooperative, local-multiplayer submarine bridge simulator that serves as a sandbox for testing multiple LLMs as fleet command and ship AI agents. Five players occupy classic stations on a nuclear attack submarine and must coordinate under time pressure, conflicting objectives, and imperfect information. The backend runs an authoritative 20 Hz sim loop; the frontends are lightweight station UIs served from one host.
- A real-time sim of ownship kinematics, acoustics, weapons, and damage/engineering.
- A five-station experience designed to create tension and immersion via power/noise budgets, maintenance/failure mechanics, and EMCON tradeoffs.
- An offline-friendly architecture with optional AI “enemy” control in the future.
- Grants firing consent (time-limited window), raises/lowers periscope and radio masts (EMCON risk).
- Receives the mission brief and Rules of Engagement (ROE).
- Monitors EMCON state: sees noise budget and detectability.
- Steers and drives the ship: heading, speed, depth.
- Must respect cavitation and thermocline to manage acoustic signature.
- Responds to power caps; speed may be limited by Engineering’s allocations.
- Tracks passive contacts (bearing-only) with noisy bearings and confidence accumulation.
- Triggers active pings (cooldown). Active returns appear as bright dots on the DEMON waterfall and in a Ping Responses list (bearing, estimated range, strength, timestamp). Pings increase counter-detection risk.
- Manages classification/marking flow to support Weapons’ firing solution quality (future).
- Manages tubes: load → flood → doors → fire. Tube timers and interlocks apply.
- Requires Captain consent to fire (if enabled). Power allocation affects tube timing.
- Receives solution inputs (bearing/run depth) and monitors timers/door states.
- Allocates reactor power budget across Helm (propulsion), Sonar (sensors), Weapons, and Engineering (maintenance).
- Manages reactor output, SCRAM, pumps; tracks battery, flooding, and hull damage.
- Oversees maintenance levels per system (rudder, ballast, sonar, radio, periscope, tubes). Neglect causes failures (e.g., lost rudder authority, limited ballast rate, sensor outages). Allocating power to Engineering recovers maintenance over time.
- Balances acoustic noise budget: pumps, cavitation, and raised masts increase detectability.
- Authoritative 20 Hz sim loop integrates kinematics, sonar (passive/active), weapons, and damage/engineering.
- Acoustic noise budget affects detectability; EMCON risk is surfaced to Captain and Sonar.
- Shared power budget forces tradeoffs across propulsion, sensors, weapons, and maintenance.
- Maintenance/failure model: low maintenance degrades or disables systems; recovery requires sustained Engineering allocation.
- Active sonar pings: cooldown-limited, with responses rendered and listed; trigger counter-detection events.
- Station noise meters: each station UI shows a station-only dB meter with peak-hold; Captain sees only an aggregate ship dB meter (forces comms/coordination). Sources include reactor MW, pumps, tube operations (load/flood/doors), cavitation, maintenance tasks, masts raised, and weapon events.
- Passive sonar now includes torpedoes and depth charges; depth charge detonations appear as bold orange bearings on the waterfall.
- The sim uses compass bearings: 0°=North, 90°=East, 180°=South, 270°=West. If ownship is at (0,0) heading 000 and another ship is at (x>0, y=0), its true bearing is ~090.
- Debug view provides a live truth map of entities.
- Restart Mission button resets world state.
- Mission selector with built-in Patrol and asset-driven missions. Asset missions live under
assets/missions/*.jsonand include captain summary, ROE, target waypoints, and structured mission supplements. Prompts are mission-agnostic; missions provide data, not instructions. - Debug helpers:
- Mission dropdown fetches available missions from
/api/missions; select and “Restart Mission” to apply changes in.env(viaMISSION_ID). - Surface Training mission spawns a single convoy-like surface ship at ~6 km with a target waypoint for the Fleet Commander.
- Mission dropdown fetches available missions from
- Two-tier AI (Fleet Commander + Ship Commanders):
- Fleet (slower cadence, stronger model) produces
FleetIntentwith per-ship objectives and optionalspeed_knandgoaltext, plus an overall one-linesummaryand optionalnotes. - Ships (faster cadence, smaller models) issue constrained tool calls:
set_nav,fire_torpedo,deploy_countermeasure. They generally followFleetIntentbut may deviate, marking summaries withdeviate:.
- Fleet (slower cadence, stronger model) produces
- Each
Shipnow carriesship_class(e.g.,SSN,Convoy,Destroyer) andcapabilities(navigation, sensors, weapons, countermeasures). - A debug
ai.toolcommand applies minimal tool calls for LLM control:set_nav:{"ship_id":"red-01","tool":"set_nav","arguments":{"heading":120,"speed":6,"depth":0}}
- Fleet Commander prompt (high-level): emphasizes formations/strategy (in
summary), per-ship objectives, EMCON settings, fused contact picture (from bearings), and concise, actionablenotes. Strict JSON-only. - Ship Commander outputs must include a short human-readable
summaryexplaining intent; the/fleetlog displays it. - When the orchestrator is enabled, stub-generated ship actions are disabled — only LLM-produced ship actions are applied.
- The
/fleetUI shows engines/models and enhanced AI run metadata: provider/model, OK/FAIL, decision source (llm/intent_fallback/disabled_stub/none), and autoSummary flag.
- Design: One global Fleet Commander plans strategy; each hostile ship executes local orders via tool calls.
- Cadence (configurable in
.env):- Fleet Commander: ~20–30 s
- Ship Commander: 5–15 s (shorter when alert)
- Information boundaries: Fleet sees only mission supplement + enemy belief (no truth); Ships see only local state and FleetIntent subset.
- Engines: Pluggable AI engines (stub, local
ollama, remote OpenAI). Calls are async so the 20 Hz loop remains authoritative. - Debug/Control:
/fleetshows engines/models,FleetIntent, and recent runs. - Fleet Commander cadence triggers: runs infrequently by default, but will run immediately and switch to alert cadence if a RED ship first achieves a high-confidence contact (thresholds configurable in
.env).
See also: docs/AI.md for detailed schemas, prompts, scheduling, and agent-based handoff/tracing.
- Python 3.11+
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp example.env .env # then edit .env as needed; do NOT commit your real .envuvicorn sub-bridge.backend.app:app --reload --host 0.0.0.0 --port 8000Open:
- http://localhost:8000/
- http://localhost:8000/captain
- http://localhost:8000/helm
- http://localhost:8000/sonar
- http://localhost:8000/weapons
- http://localhost:8000/engineering
- http://localhost:8000/fleet
LAN access: http://192.168.1.100:8000/ (adjust to your host IP)
- Copy
example.envto.envand edit values locally. Never commit.env. - Relevant keys:
USE_AI_ORCHESTRATORto enable Fleet/Ship agents orchestration.AI_FLEET_ENGINE/AI_SHIP_ENGINE=stub|ollama|openaiwith corresponding*_MODEL.OPENAI_API_KEY(only in your local.env) if using OpenAI;OLLAMA_HOSTfor local LLMs.- Agent cadences:
AI_FLEET_CADENCE_S,AI_SHIP_CADENCE_S,AI_SHIP_ALERT_CADENCE_S. - Missions:
MISSION_IDselectsassets/missions/<id>.json.
- Open
/fleetto view current FleetIntent, recent runs, engines/models, and a live call log. - A health-check is issued via
GET /api/ai/healthshortly after page load to verify engine connectivity. - Press “Restart Mission” in
/debugafter changing.env. The server reloads.envand re-initializes the orchestrator without full server restart.