Add game UI panels, keyboard shortcuts, docs narrative overhaul, and unified dev script
- Add MiniStarMap, NpcMarketPanel, ShipStatusPanel, useKeyboardShortcuts - Add progress bars for approach/mining operations and cargo fill indicator - Rewrite docs from spreadsheet-first to exploration-first open-world RPG - Replace dev:db + dev:standalone with unified dev script (scripts/dev.sh) - Add Vite chunk splitting for three.js and spacetimedb - Fix displayName dependency in useSpacetimeConnection - Remove stale usePlayerSession.ts - Add AGENTS.md files across all packages
This commit is contained in:
56
apps/docs/AGENTS.md
Normal file
56
apps/docs/AGENTS.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# apps/docs — Living Design Documentation
|
||||
|
||||
Package: `@void-nav/docs`
|
||||
Port: `http://localhost:5173/docs`
|
||||
|
||||
This is the **design documentation hub** and interactive prototype playground. It contains the full GDD as 16 browsable pages, 14 interactive demos validating individual game subsystems, and a complete game-slice prototype implementing the full MVP loop in-browser with localStorage.
|
||||
|
||||
## Structure
|
||||
|
||||
```
|
||||
src/
|
||||
App.tsx Route definitions (16 doc pages + 14 demo routes + 1 prototype)
|
||||
main.tsx Entry point
|
||||
components/ Shared UI: NotFound, Sidebar, TopBar
|
||||
data/
|
||||
nav.ts Sidebar navigation structure and page titles
|
||||
fakeBackend.ts Mock data for demos
|
||||
layouts/
|
||||
DocsLayout.tsx Sidebar + content layout wrapper
|
||||
lib/
|
||||
threeHelpers.ts Shared Three.js utility functions
|
||||
pages/docs/ 16 design doc page components:
|
||||
OverviewPage.tsx Vision, pillars, core loop, HUD architecture, onboarding
|
||||
ArchitecturePage.tsx System architecture, error handling, persistence, audio
|
||||
TechStackPage.tsx Technology decisions
|
||||
BackendPage.tsx 56+ database tables, movement model, ER diagram
|
||||
AgentsPage.tsx Scheduled agent system (3 scheduling strategies)
|
||||
GameplayPage.tsx Core loop, security, NPC pirates, combat, missions, travel, events, balancer
|
||||
ShipsPage.tsx Ship classes, fitting, acquisition, AI crew
|
||||
EconomyPage.tsx Trade routes, info diffusion, refining, manufacturing, NPC pricing, faucets/sinks
|
||||
SocialPage.tsx XP & skills, chat, bounty, kill feed, corporations
|
||||
ShipAIPage.tsx Zora companion AI with soul depth and module gating
|
||||
RoadmapPage.tsx 16 phases (0-15), 2 eras, 6 integration gates
|
||||
RisksPage.tsx Open risks and questions
|
||||
TodoPage.tsx Living implementation status tracker (68 items across 8 phases)
|
||||
DemoGalleryPage.tsx Links to all demos
|
||||
GapAnalysisPage.tsx Cross-reference: specs vs demos vs readiness
|
||||
VerticalSliceEvaluationPage.tsx Alignment matrix, phase readiness
|
||||
DesignDocPage.tsx Original GDD reference
|
||||
prototypes/
|
||||
game-slice/ Full MVP loop prototype (localStorage, not SpacetimeDB)
|
||||
existing-demos/ 14 standalone interactive demo components
|
||||
r3f/ Reusable R3F 3D scenes (combat, galaxy, HUD, movement, navigation, starmap, warp)
|
||||
standalone-huds/ GameHudPrototype, PrototypeFrame
|
||||
styles/
|
||||
tailwind.css Tailwind v4 entry point
|
||||
public/
|
||||
docs/ Markdown files: vertical-slice-evaluation.md, gap-analysis.md
|
||||
assets/ Design doc (.docx), 3 concept drawings (.png)
|
||||
```
|
||||
|
||||
## Key Design Decisions
|
||||
|
||||
- Docs are **React components**, not markdown files — this allows interactive demos inline with documentation
|
||||
- The `game-slice/` prototype is a self-contained playable game that validates the full loop before backend migration
|
||||
- All 14 demos in `existing-demos/` use the R3F scenes in `r3f/`
|
||||
@@ -17,6 +17,7 @@ import { DemoGalleryPage } from "./pages/docs/DemoGalleryPage";
|
||||
import { GapAnalysisPage } from "./pages/docs/GapAnalysisPage";
|
||||
import { VerticalSliceEvaluationPage } from "./pages/docs/VerticalSliceEvaluationPage";
|
||||
import { DesignDocPage } from "./pages/docs/DesignDocPage";
|
||||
import { TodoPage } from "./pages/docs/TodoPage";
|
||||
import { StarMapDemo } from "./prototypes/existing-demos/StarMapDemo";
|
||||
import { ShipMovementDemo } from "./prototypes/existing-demos/ShipMovementDemo";
|
||||
import { WarpTravelDemo } from "./prototypes/existing-demos/WarpTravelDemo";
|
||||
@@ -56,6 +57,7 @@ export function App() {
|
||||
<Route path="gap-analysis" element={<GapAnalysisPage />} />
|
||||
<Route path="vertical-slice-evaluation" element={<VerticalSliceEvaluationPage />} />
|
||||
<Route path="design-doc" element={<DesignDocPage />} />
|
||||
<Route path="todo" element={<TodoPage />} />
|
||||
|
||||
<Route path="demos/starmap" element={<StarMapDemo />} />
|
||||
<Route path="demos/game-loop" element={<GameLoopSliceDemo />} />
|
||||
|
||||
@@ -24,6 +24,7 @@ export const navSections: NavSection[] = [
|
||||
{ path: "/docs/social", icon: "✧", label: "Progression & Social" },
|
||||
{ path: "/docs/ship-ai", icon: "◈", label: "Ship AI - Zora" },
|
||||
{ path: "/docs/roadmap", icon: "⊞", label: "Roadmap" },
|
||||
{ path: "/docs/todo", icon: "⊡", label: "Implementation Status" },
|
||||
{ path: "/docs/risks", icon: "◬", label: "Risks & Questions" },
|
||||
{ path: "/docs/gap-analysis", icon: "□", label: "Gap Analysis" },
|
||||
{ path: "/docs/vertical-slice-evaluation", icon: "▤", label: "Slice Evaluation" },
|
||||
|
||||
@@ -40,29 +40,29 @@ export function EconomyPage() {
|
||||
|
||||
return (
|
||||
<div className="mx-auto max-w-content">
|
||||
<h1 style={{ marginBottom: '8px' }}>Economy & Industry</h1>
|
||||
<h1 style={{ marginBottom: '8px' }}>Trade & Industry</h1>
|
||||
<p style={{ color: 'var(--fg-dim)', fontSize: '0.95rem', maxWidth: '680px' }}>
|
||||
Player-led economy with NPC support as an underlying demand/supply buffer. Players mine, refine,
|
||||
manufacture, and trade. NPCs provide a price floor and basic market liquidity so new players
|
||||
always have a way to earn and spend.
|
||||
Trade between stations with regional price differences. Supply what stations need and watch them grow.
|
||||
Mine ore, refine into minerals, manufacture modules and ships. The economy rewards exploration —
|
||||
discovering a profitable trade route is as valuable as finding a rich asteroid belt.
|
||||
</p>
|
||||
|
||||
<div className="mb-6 grid grid-cols-[repeat(auto-fit,minmax(180px,1fr))] gap-4" style={{ marginTop: 'var(--sp-5)' }}>
|
||||
<div className="rounded-xl border border-border bg-surface p-5 max-md:rounded-lg max-md:p-4">
|
||||
<div className="font-mono text-[1.6rem] font-bold tabular-nums text-fg-bright" style={{ color: 'var(--accent)' }}>Player-led</div>
|
||||
<div className="mt-1 text-[0.75rem] uppercase tracking-[0.05em] text-muted">Economy Model</div>
|
||||
<div className="font-mono text-[1.6rem] font-bold tabular-nums text-fg-bright" style={{ color: 'var(--accent)' }}>Trade Routes</div>
|
||||
<div className="mt-1 text-[0.75rem] uppercase tracking-[0.05em] text-muted">Core Mechanic</div>
|
||||
</div>
|
||||
<div className="rounded-xl border border-border bg-surface p-5 max-md:rounded-lg max-md:p-4">
|
||||
<div className="font-mono text-[1.6rem] font-bold tabular-nums text-fg-bright" style={{ color: 'var(--cyan)' }}>8 → 8</div>
|
||||
<div className="mt-1 text-[0.75rem] uppercase tracking-[0.05em] text-muted">Ore Types → Minerals</div>
|
||||
</div>
|
||||
<div className="rounded-xl border border-border bg-surface p-5 max-md:rounded-lg max-md:p-4">
|
||||
<div className="font-mono text-[1.6rem] font-bold tabular-nums text-fg-bright" style={{ color: 'var(--green)' }}>8+</div>
|
||||
<div className="mt-1 text-[0.75rem] uppercase tracking-[0.05em] text-muted">Manufacturable Items</div>
|
||||
<div className="font-mono text-[1.6rem] font-bold tabular-nums text-fg-bright" style={{ color: 'var(--green)' }}>Regional</div>
|
||||
<div className="mt-1 text-[0.75rem] uppercase tracking-[0.05em] text-muted">Price Differences</div>
|
||||
</div>
|
||||
<div className="rounded-xl border border-border bg-surface p-5 max-md:rounded-lg max-md:p-4">
|
||||
<div className="font-mono text-[1.6rem] font-bold tabular-nums text-fg-bright" style={{ color: 'var(--purple)' }}>2%</div>
|
||||
<div className="mt-1 text-[0.75rem] uppercase tracking-[0.05em] text-muted">Market Tax</div>
|
||||
<div className="font-mono text-[1.6rem] font-bold tabular-nums text-fg-bright" style={{ color: 'var(--purple)' }}>Dynamic</div>
|
||||
<div className="mt-1 text-[0.75rem] uppercase tracking-[0.05em] text-muted">Station Prosperity</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -91,10 +91,10 @@ export function EconomyPage() {
|
||||
</div>
|
||||
|
||||
<div className="mb-5 rounded-lg px-5 py-4 text-[0.85rem] leading-[1.5] border border-cyan/20 bg-cyan/8 text-cyan" style={{ marginBottom: 'var(--sp-5)' }}>
|
||||
<strong>Exploration and commerce are the core pillars.</strong> This walkthrough shows what a new player sees, decides,
|
||||
and experiences in their first 30 minutes — from undocking with an empty cargo hold to discovering their first price
|
||||
difference and making a profitable trade. The goal: by minute 30, the player <em>understands</em> that information asymmetry
|
||||
is the game, and they've profited from it at least once.
|
||||
<strong>Trade and exploration are the entry point.</strong> This walkthrough shows what a new captain sees, decides,
|
||||
and experiences in their first 30 minutes — from undocking with an empty cargo hold to discovering their first
|
||||
trade route and making a profitable run. The goal: by minute 30, the player <em>understands</em> that
|
||||
different stations need different things, and supplying them is how you grow — <strong>whether through mining, trading, or quests</strong>.
|
||||
</div>
|
||||
|
||||
<div style={{ marginTop: 'var(--sp-6)' }}>
|
||||
@@ -132,9 +132,9 @@ export function EconomyPage() {
|
||||
|
||||
<div className="mb-5 rounded-lg px-5 py-4 text-[0.85rem] leading-[1.5] border border-[rgba(240,160,48,0.25)] bg-[rgba(240,160,48,0.08)] text-accent" style={{ marginTop: 'var(--sp-6)' }}>
|
||||
<strong>Design intent:</strong> By minute 8, the player has discovered that prices differ between stations.
|
||||
By minute 12, they\'ve acted on that discovery and profited. By minute 30, they have a mental model of the
|
||||
economy as a landscape of opportunities, not a single "sell" button. This is the hook. If the price discovery
|
||||
moment doesn\'t feel exciting, the entire game falls flat.
|
||||
By minute 12, they've acted on that discovery and profited. By minute 30, they have a mental model of the
|
||||
galaxy as a landscape of trade routes, faction needs, and opportunities — not a single "sell" button.
|
||||
This is the hook. <strong>If the moment of discovering a trade route doesn't feel exciting, the trading game needs work.</strong>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -6,11 +6,11 @@ export function GameplayPage() {
|
||||
|
||||
return (
|
||||
<div className="mx-auto max-w-content">
|
||||
<h1 style={{ marginBottom: '8px' }}>MVP Gameplay Loop</h1>
|
||||
<h1 style={{ marginBottom: '8px' }}>Gameplay Systems</h1>
|
||||
<p style={{ color: 'var(--fg-dim)', fontSize: '0.95rem', maxWidth: '680px' }}>
|
||||
The core loop: connect → spawn → navigate → mine → inventory → station → <strong style={{ color: 'var(--accent)' }}>sell on the market</strong> → chat.
|
||||
Steps 1–7 work in Era 1 (single-player). Step 8 (Chat) requires multiplayer and ships in Era 2 (Phase 11).
|
||||
Each step is UI-driven. The player's main interface is tables, charts, and panels — not a cockpit.
|
||||
The core loop: explore → trade → quest → <strong style={{ color: 'var(--accent)' }}>fight (FTL-style)</strong> → upgrade → sail deeper.
|
||||
Every system feeds into the others. Trade earns ISK for upgrades. Quests unlock faction influence. Combat protects trade routes.
|
||||
Exploration reveals new opportunities. Steps 1–7 work in Era 1 (single-player). Multiplayer features arrive in Era 2.
|
||||
</p>
|
||||
|
||||
<div style={{ display: 'flex', gap: 'var(--sp-2)', marginBottom: 'var(--sp-6)', flexWrap: 'wrap' }}>
|
||||
@@ -20,10 +20,10 @@ export function GameplayPage() {
|
||||
{ id: 'pirates', label: 'NPC Pirates' },
|
||||
{ id: 'concord', label: 'CONCORD' },
|
||||
{ id: 'insurance', label: 'Insurance' },
|
||||
{ id: 'missions', label: 'Missions' },
|
||||
{ id: 'travel', label: '🚀 Travel & Warp' },
|
||||
{ id: 'events', label: 'World Events UX' },
|
||||
{ id: 'balancer', label: '⚖ Balancing Agent' },
|
||||
{ id: 'missions', label: 'Quests & Factions' },
|
||||
{ id: 'travel', label: 'Travel & Warp' },
|
||||
{ id: 'events', label: 'World Events' },
|
||||
{ id: 'balancer', label: 'Balancing Agent' },
|
||||
].map(t => (
|
||||
<button key={t.id} className={`inline-flex cursor-pointer items-center gap-2 rounded-lg border border-border bg-surface-raised px-4 py-2 font-body text-[0.8rem] font-medium text-fg transition-all duration-150 hover:border-border-light hover:bg-surface-hover disabled:cursor-not-allowed disabled:opacity-55 px-3 py-1 text-[0.75rem]${activeTab === t.id ? ' border-accent bg-accent font-semibold text-bg hover:bg-accent-hover' : ''}`}
|
||||
onClick={() => setActiveTab(t.id)}>{t.label}</button>
|
||||
@@ -34,14 +34,14 @@ export function GameplayPage() {
|
||||
{/* Loop steps */}
|
||||
<div style={{ marginTop: 'var(--sp-6)' }}>
|
||||
{[
|
||||
{ step: 1, title: 'Connect', desc: 'Player opens the app and connects to SpacetimeDB. Identity is established, player row loaded.', color: 'var(--cyan)' },
|
||||
{ step: 2, title: 'Spawn', desc: 'A player row and ship row exist; the ship appears in the shared star system for all subscribers.', color: 'var(--cyan)' },
|
||||
{ step: 3, title: 'Navigate (click & autopilot)', desc: 'Player clicks a point of interest — asteroid, station, hostile — and the ship automatically pilots there. No manual flight control at all. The player sets <em>intent</em>, the ship executes.', color: 'var(--green)' },
|
||||
{ step: 4, title: 'Mine (activate & wait)', desc: 'Player clicks an asteroid to approach, then activates mining modules. The ship navigates on its own. Mining runs on a timer. The decision is <em>what</em> to mine and <em>when</em>, not <em>how</em>.', color: 'var(--accent)' },
|
||||
{ step: 5, title: 'Inventory', desc: 'Ore appears in inventory panel. Quantity, type, and value visible. Player manages cargo space.', color: 'var(--purple)' },
|
||||
{ step: 6, title: 'Dock at Station', desc: 'Player docks at a station. Station UI becomes available: sell, market, refit.', color: 'var(--cyan)' },
|
||||
{ step: 7, title: 'Sell Ore', desc: 'Player sells ore through station UI for ISK (in-game currency). Simple fixed pricing for MVP; market orders later.', color: 'var(--accent)' },
|
||||
{ step: 8, title: 'Chat', desc: 'Players send and receive messages in current system. Basic rate limiting and length validation. Requires multiplayer — ships in Phase 11 (Era 2).', color: 'var(--green)' },
|
||||
{ step: 1, title: 'Spawn & Explore', desc: 'Player connects and spawns at a station in a procedurally generated sector. The map is hidden — fog of war covers unexplored regions. Nearby POIs are visible: stations, belts, signal sources. The urge to explore is immediate.', color: 'var(--cyan)' },
|
||||
{ step: 2, title: 'Navigate (click & autopilot)', desc: 'Player clicks a point of interest — asteroid, station, anomaly, signal — and the ship automatically pilots there. No manual flight. The journey IS the experience: watch the stars scroll, spot distant objects, feel the void.', color: 'var(--green)' },
|
||||
{ step: 3, title: 'Gather Resources', desc: 'Mine asteroids for ore. Salvage derelicts for components. Discover anomalies for rare materials. The decision is <em>what</em> to gather and <em>where</em> — different regions have different resources.', color: 'var(--accent)' },
|
||||
{ step: 4, title: 'Trade Between Stations', desc: 'Buy low at one station, sell high at another. Prices vary by region and faction needs. Stations that need resources pay more. Trade routes emerge naturally from exploration.', color: 'var(--purple)' },
|
||||
{ step: 5, title: 'Accept Quests', desc: 'Faction agents offer missions: deliver cargo, eliminate threats, explore sectors, escort convoys. Completing quests earns ISK, standing, and unlocks new opportunities. Helping one faction may hinder another.', color: 'var(--cyan)' },
|
||||
{ step: 6, title: 'Combat (FTL-style)', desc: 'Click a hostile → ship auto-engages → manage reactor power between Weapons/Shields/Engines/Aux. No dogfighting. The skill is tactical resource allocation. PvE pirates, bounty targets, and hostile NPCs. PvP in Era 2.', color: 'var(--red)' },
|
||||
{ step: 7, title: 'Upgrade & Customize Ship', desc: 'Use ISK to buy bigger ships, fit modules, upgrade weapons and defenses. Build the ship that suits your style: nimble trader, tough warship, or versatile explorer.', color: 'var(--accent)' },
|
||||
{ step: 8, title: 'Sail Deeper', desc: 'Venture into unexplored sectors with better resources but greater danger. Higher risk, higher reward. Faction territory, world events, and player actions shape the galaxy. Co-op multiplayer in Era 2.', color: 'var(--green)' },
|
||||
].map((s, i) => (
|
||||
<div key={i} className="mb-5 flex gap-4">
|
||||
<div className="flex min-w-10 flex-col items-center">
|
||||
|
||||
@@ -4,36 +4,36 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
export function OverviewPage() {
|
||||
return (
|
||||
<div className="mx-auto max-w-content">
|
||||
<h1 style={{ marginBottom: '8px' }}>EVE-Inspired Multiplayer Prototype</h1>
|
||||
<h1 style={{ marginBottom: '8px' }}>Open-World Space Exploration RPG</h1>
|
||||
<p style={{ color: 'var(--fg-dim)', fontSize: '1.1rem', maxWidth: '680px', marginBottom: 'var(--sp-6)' }}>
|
||||
A browser-based <strong style={{ color: 'var(--fg-bright)' }}>spreadsheet simulator</strong> in the EVE Online tradition,
|
||||
set inside a <strong style={{ color: 'var(--fg-bright)' }}>single persistent galaxy</strong> that the server simulates as a living world.
|
||||
The game is played through UI panels, market tables, inventory grids, and chat channels — not by flying a ship.
|
||||
Movement and combat are deliberately rudimentary; the depth lives in the economy, information diffusion,
|
||||
strategic decisions, and a galaxy that evolves around you through <strong style={{ color: 'var(--fg-bright)' }}>dynamic PvE events and emergent world story</strong>.
|
||||
Trade, quest, fight, or simply drift and enjoy the ambiance. A charming <strong style={{ color: 'var(--fg-bright)' }}>open-world space RPG</strong> inspired
|
||||
by the freedom and charm of Windward Horizon — set in a <strong style={{ color: 'var(--fg-bright)' }}>procedurally generated galaxy</strong> where
|
||||
every campaign is unique. Explore sectors, trade between stations, take on faction quests, mine asteroids,
|
||||
or simply cruise the void. Combat is <strong style={{ color: 'var(--fg-bright)' }}>FTL-style tactical resource management</strong> —
|
||||
no dogfighting. You are the captain who decides <em>what</em> to power and <em>when</em>, not the pilot who dodges.
|
||||
</p>
|
||||
|
||||
<div className="mb-6 grid grid-cols-[repeat(auto-fit,minmax(180px,1fr))] gap-4">
|
||||
<div className="rounded-xl border border-border bg-surface p-5 max-md:rounded-lg max-md:p-4">
|
||||
<div className="font-mono text-[1.6rem] font-bold tabular-nums text-fg-bright" style={{ color: 'var(--accent)' }}>UI-first</div>
|
||||
<div className="mt-1 text-[0.75rem] uppercase tracking-[0.05em] text-muted">Design Pillar</div>
|
||||
<div className="font-mono text-[1.6rem] font-bold tabular-nums text-fg-bright" style={{ color: 'var(--accent)' }}>Explore</div>
|
||||
<div className="mt-1 text-[0.75rem] uppercase tracking-[0.05em] text-muted">Core Pillar</div>
|
||||
</div>
|
||||
<div className="rounded-xl border border-border bg-surface p-5 max-md:rounded-lg max-md:p-4">
|
||||
<div className="font-mono text-[1.6rem] font-bold tabular-nums text-fg-bright" style={{ color: 'var(--cyan)' }}>SpacetimeDB</div>
|
||||
<div className="mt-1 text-[0.75rem] uppercase tracking-[0.05em] text-muted">Backend</div>
|
||||
</div>
|
||||
<div className="rounded-xl border border-border bg-surface p-5 max-md:rounded-lg max-md:p-4">
|
||||
<div className="font-mono text-[1.6rem] font-bold tabular-nums text-fg-bright" style={{ color: 'var(--green)' }}>~3 hrs</div>
|
||||
<div className="mt-1 text-[0.75rem] uppercase tracking-[0.05em] text-muted">Session Target</div>
|
||||
<div className="font-mono text-[1.6rem] font-bold tabular-nums text-fg-bright" style={{ color: 'var(--green)' }}>FTL Combat</div>
|
||||
<div className="mt-1 text-[0.75rem] uppercase tracking-[0.05em] text-muted">Combat Model</div>
|
||||
</div>
|
||||
<div className="rounded-xl border border-border bg-surface p-5 max-md:rounded-lg max-md:p-4">
|
||||
<div className="font-mono text-[1.6rem] font-bold tabular-nums text-fg-bright" style={{ color: 'var(--purple)' }}>Player-led</div>
|
||||
<div className="mt-1 text-[0.75rem] uppercase tracking-[0.05em] text-muted">Economy Model</div>
|
||||
</div>
|
||||
<div className="rounded-xl border border-border bg-surface p-5 max-md:rounded-lg max-md:p-4">
|
||||
<div className="font-mono text-[1.6rem] font-bold tabular-nums text-fg-bright" style={{ color: 'var(--red)' }}>Living Galaxy</div>
|
||||
<div className="font-mono text-[1.6rem] font-bold tabular-nums text-fg-bright" style={{ color: 'var(--purple)' }}>Dynamic</div>
|
||||
<div className="mt-1 text-[0.75rem] uppercase tracking-[0.05em] text-muted">World Model</div>
|
||||
</div>
|
||||
<div className="rounded-xl border border-border bg-surface p-5 max-md:rounded-lg max-md:p-4">
|
||||
<div className="font-mono text-[1.6rem] font-bold tabular-nums text-fg-bright" style={{ color: 'var(--red)' }}>Co-op</div>
|
||||
<div className="mt-1 text-[0.75rem] uppercase tracking-[0.05em] text-muted">Multiplayer</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mb-5 flex items-center gap-3 border-b border-border pb-3 max-md:flex-col max-md:items-start max-md:gap-2 max-md:[&_h1]:text-[1.35rem] max-md:[&_h2]:text-[1.35rem]">
|
||||
@@ -42,10 +42,10 @@ export function OverviewPage() {
|
||||
</div>
|
||||
|
||||
<div className="mb-5 rounded-lg px-5 py-4 text-[0.85rem] leading-[1.5] border border-cyan/20 bg-cyan/8 text-cyan">
|
||||
<strong>Primary recommendation:</strong> Build the MVP as a UI-heavy browser game — a <em>spreadsheet simulator</em>.
|
||||
The 3D scene is a strategic map layer for context, not the game itself. Players spend 90% of their time
|
||||
in tables, charts, and panels: market depth, order books, cargo manifests, fitting spreadsheets,
|
||||
route planners, and chat. The 3D viewport exists to give spatial awareness, not twitch gameplay.
|
||||
<strong>Primary inspiration:</strong> Windward Horizon's charm and freedom in a space setting. The game is an
|
||||
<em> open-world exploration RPG</em> where the player charts their own path — trader, mercenary, explorer, or drifter.
|
||||
The 3D scene is the primary viewport for spatial immersion. Panels and UI overlays handle station services, fitting, and market.
|
||||
Combat uses FTL-style power management — no dogfighting. The galaxy is procedurally generated each campaign.
|
||||
</div>
|
||||
|
||||
<h3>Core Pillars</h3>
|
||||
@@ -59,29 +59,34 @@ export function OverviewPage() {
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><span className="inline-flex items-center gap-1 whitespace-nowrap rounded-full px-2.5 py-0.5 font-mono text-[0.7rem] border border-[rgba(240,160,48,0.25)] bg-[rgba(240,160,48,0.08)] text-accent">Economy & markets</span></td>
|
||||
<td style={{ color: 'var(--fg-dim)' }}>Player-led economy with NPC support. Mining → refining → manufacturing → trade. Geographic price differences, contract markets, order books, and <strong style={{ color: 'var(--accent)' }}>information asymmetry between systems</strong> create emergent trade routes and speculative opportunities. <strong style={{ color: 'var(--accent)' }}>This IS the game.</strong></td>
|
||||
<td><span className="inline-flex items-center gap-1 whitespace-nowrap rounded-full px-2.5 py-0.5 font-mono text-[0.7rem] border border-green/25 bg-green/8 text-green">Era 1</span> <span style={{ fontSize: '0.75rem', color: 'var(--fg-dim)' }}>NPC economy, single-player mining/refining/manufacturing</span><br/><span className="inline-flex items-center gap-1 whitespace-nowrap rounded-full px-2.5 py-0.5 font-mono text-[0.7rem] border border-cyan/25 bg-cyan/8 text-cyan" style={{ fontSize: '0.65rem' }}>Era 2</span> <span style={{ fontSize: '0.75rem', color: 'var(--fg-dim)' }}>Player-to-player market, info diffusion</span></td>
|
||||
<td><span className="inline-flex items-center gap-1 whitespace-nowrap rounded-full px-2.5 py-0.5 font-mono text-[0.7rem] border border-[rgba(240,160,48,0.25)] bg-[rgba(240,160,48,0.08)] text-accent">Open-world exploration</span></td>
|
||||
<td style={{ color: 'var(--fg-dim)' }}>Procedurally generated galaxy with unique sectors every campaign. Points of interest: stations, asteroid belts, anomalies, derelicts, signal sources. <strong style={{ color: 'var(--accent)' }}>Explore to discover resources, quests, and hidden stories.</strong> The map reveals as you travel — fog of war drives the urge to see what's out there.</td>
|
||||
<td><span className="inline-flex items-center gap-1 whitespace-nowrap rounded-full px-2.5 py-0.5 font-mono text-[0.7rem] border border-green/25 bg-green/8 text-green">Era 1</span> <span style={{ fontSize: '0.75rem', color: 'var(--fg-dim)' }}>Single system with POIs, procedural generation seed</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span className="inline-flex items-center gap-1 whitespace-nowrap rounded-full px-2.5 py-0.5 font-mono text-[0.7rem] border border-cyan/25 bg-cyan/8 text-cyan">Social & multiplayer</span></td>
|
||||
<td style={{ color: 'var(--fg-dim)' }}>Local chat, delayed PMs, bounty system, emergent player-driven justice. Communication is range-based. <strong style={{ color: 'var(--accent)' }}>Priority pillar.</strong></td>
|
||||
<td><span className="inline-flex items-center gap-1 whitespace-nowrap rounded-full px-2.5 py-0.5 font-mono text-[0.7rem] border border-cyan/25 bg-cyan/8 text-cyan" style={{ fontSize: '0.65rem' }}>Era 2</span> <span style={{ fontSize: '0.75rem', color: 'var(--fg-dim)' }}>All social features require multiplayer</span></td>
|
||||
<td><span className="inline-flex items-center gap-1 whitespace-nowrap rounded-full px-2.5 py-0.5 font-mono text-[0.7rem] border border-cyan/25 bg-cyan/8 text-cyan">Trade & commerce</span></td>
|
||||
<td style={{ color: 'var(--fg-dim)' }}>Buy low at one station, sell high at another. Regional price differences driven by supply/demand and faction needs. <strong style={{ color: 'var(--accent)' }}>Trade routes are the economic backbone.</strong> Towns need resources to grow — supplying them leads to prosperity.</td>
|
||||
<td><span className="inline-flex items-center gap-1 whitespace-nowrap rounded-full px-2.5 py-0.5 font-mono text-[0.7rem] border border-green/25 bg-green/8 text-green">Era 1</span> <span style={{ fontSize: '0.75rem', color: 'var(--fg-dim)' }}>NPC economy, regional prices, trade routes</span><br/><span className="inline-flex items-center gap-1 whitespace-nowrap rounded-full px-2.5 py-0.5 font-mono text-[0.7rem] border border-cyan/25 bg-cyan/8 text-cyan" style={{ fontSize: '0.65rem' }}>Era 2</span> <span style={{ fontSize: '0.75rem', color: 'var(--fg-dim)' }}>Player-to-player market, info diffusion</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span className="inline-flex items-center gap-1 whitespace-nowrap rounded-full px-2.5 py-0.5 font-mono text-[0.7rem] border border-green/25 bg-green/8 text-green">Command-based (not action)</span></td>
|
||||
<td style={{ color: 'var(--fg-dim)' }}>Players issue high-level intentions — click a point of interest and the ship autopilots there. Click a hostile and the ship auto-engages. During combat the player manages <strong style={{ color: 'var(--fg)' }}>reactor power allocation</strong> (FTL-style) between systems. No manual flight, no aiming, no skill shots. The skill is in <strong style={{ color: 'var(--fg)' }}>what</strong> you power, not <strong style={{ color: 'var(--fg)' }}>how fast</strong> you click.</td>
|
||||
<td><span className="inline-flex items-center gap-1 whitespace-nowrap rounded-full px-2.5 py-0.5 font-mono text-[0.7rem] border border-green/25 bg-green/8 text-green">Era 1</span> <span style={{ fontSize: '0.75rem', color: 'var(--fg-dim)' }}>Core combat & movement loop</span></td>
|
||||
<td><span className="inline-flex items-center gap-1 whitespace-nowrap rounded-full px-2.5 py-0.5 font-mono text-[0.7rem] border border-green/25 bg-green/8 text-green">FTL-style combat</span></td>
|
||||
<td style={{ color: 'var(--fg-dim)' }}>No dogfighting. Click hostile → ship auto-engages → manage <strong style={{ color: 'var(--fg)' }}>reactor power allocation</strong> (FTL-style) between Weapons/Shields/Engines/Aux. The skill is in <strong style={{ color: 'var(--fg)' }}>what</strong> you power, not <strong style={{ color: 'var(--fg)' }}>how fast</strong> you click. Combat creates consequences — ship damage, loot, insurance — but it's not the focus.</td>
|
||||
<td><span className="inline-flex items-center gap-1 whitespace-nowrap rounded-full px-2.5 py-0.5 font-mono text-[0.7rem] border border-green/25 bg-green/8 text-green">Era 1</span> <span style={{ fontSize: '0.75rem', color: 'var(--fg-dim)' }}>Core combat & power management</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span className="inline-flex items-center gap-1 whitespace-nowrap rounded-full px-2.5 py-0.5 font-mono text-[0.7rem] border border-purple/25 bg-purple/8 text-purple">Ship fitting</span></td>
|
||||
<td style={{ color: 'var(--fg-dim)' }}>CPU/Power Grid slot system. High/Med/Low slots with meaningful fitting tradeoffs. Multiple ships, AI crew (post-MVP).</td>
|
||||
<td><span className="inline-flex items-center gap-1 whitespace-nowrap rounded-full px-2.5 py-0.5 font-mono text-[0.7rem] border border-green/25 bg-green/8 text-green">Era 1</span> <span style={{ fontSize: '0.75rem', color: 'var(--fg-dim)' }}>Basic fitting, single ship class</span></td>
|
||||
<td><span className="inline-flex items-center gap-1 whitespace-nowrap rounded-full px-2.5 py-0.5 font-mono text-[0.7rem] border border-purple/25 bg-purple/8 text-purple">Ship customization</span></td>
|
||||
<td style={{ color: 'var(--fg-dim)' }}>Build the ship that suits your style — tough juggernaut that can take a beating, nimble scout that rains fire from afar, or cargo hauler keeping trade routes supplied. Swap modules to change role. <strong style={{ color: 'var(--fg)' }}>Multiple ship classes from nimble interceptors to powerful cruisers.</strong></td>
|
||||
<td><span className="inline-flex items-center gap-1 whitespace-nowrap rounded-full px-2.5 py-0.5 font-mono text-[0.7rem] border border-green/25 bg-green/8 text-green">Era 1</span> <span style={{ fontSize: '0.75rem', color: 'var(--fg-dim)' }}>Basic fitting, multiple ship classes</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span className="inline-flex items-center gap-1 whitespace-nowrap rounded-full px-2.5 py-0.5 font-mono text-[0.7rem] border border-[rgba(240,160,48,0.25)] bg-[rgba(240,160,48,0.08)] text-accent">Emergent lore</span></td>
|
||||
<td style={{ color: 'var(--fg-dim)' }}>No server has the same lore as another. The galaxy is a <strong style={{ color: 'var(--fg)' }}>single persistent world</strong> with systems, planets, anomalies, and orbiting objects. A world simulation layer spawns PvE events dynamically — faction wars, space anomalies, migrations, raids — that create a <strong style={{ color: 'var(--fg)' }}>living story unique to every server</strong>. Lore evolves through both player actions and server-driven world events.</td>
|
||||
<td><span className="inline-flex items-center gap-1 whitespace-nowrap rounded-full px-2.5 py-0.5 font-mono text-[0.7rem] border border-cyan/25 bg-cyan/8 text-cyan" style={{ fontSize: '0.65rem' }}>Era 2</span> <span style={{ fontSize: '0.75rem', color: 'var(--fg-dim)' }}>Living galaxy requires world agents</span></td>
|
||||
<td><span className="inline-flex items-center gap-1 whitespace-nowrap rounded-full px-2.5 py-0.5 font-mono text-[0.7rem] border border-[rgba(240,160,48,0.25)] bg-[rgba(240,160,48,0.08)] text-accent">Dynamic world & factions</span></td>
|
||||
<td style={{ color: 'var(--fg-dim)' }}>Stations and provinces need resources to grow. Supplying them leads to prosperity. Faction leaders involve you in their agendas — helping one may hinder another. <strong style={{ color: 'var(--fg)' }}>Enough support can let a faction leader take control of a province without a single shot fired.</strong> A living galaxy that evolves through player actions and world events.</td>
|
||||
<td><span className="inline-flex items-center gap-1 whitespace-nowrap rounded-full px-2.5 py-0.5 font-mono text-[0.7rem] border border-green/25 bg-green/8 text-green">Era 1</span> <span style={{ fontSize: '0.75rem', color: 'var(--fg-dim)' }}>Basic factions, NPC agents, quests</span><br/><span className="inline-flex items-center gap-1 whitespace-nowrap rounded-full px-2.5 py-0.5 font-mono text-[0.7rem] border border-cyan/25 bg-cyan/8 text-cyan" style={{ fontSize: '0.65rem' }}>Era 2</span> <span style={{ fontSize: '0.75rem', color: 'var(--fg-dim)' }}>Living galaxy, world agents, territory</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span className="inline-flex items-center gap-1 whitespace-nowrap rounded-full px-2.5 py-0.5 font-mono text-[0.7rem] border border-cyan/25 bg-cyan/8 text-cyan">Solo or co-op</span></td>
|
||||
<td style={{ color: 'var(--fg-dim)' }}>Brave the void alone or crew with friends. The game is <strong style={{ color: 'var(--fg)' }}>built with co-op in mind</strong> — bring your crew, set sail, and experience the chaotic endgame together. Solo play is fully viable; co-op makes the late game richer.</td>
|
||||
<td><span className="inline-flex items-center gap-1 whitespace-nowrap rounded-full px-2.5 py-0.5 font-mono text-[0.7rem] border border-green/25 bg-green/8 text-green">Era 1</span> <span style={{ fontSize: '0.75rem', color: 'var(--fg-dim)' }}>Solo proof of concept</span><br/><span className="inline-flex items-center gap-1 whitespace-nowrap rounded-full px-2.5 py-0.5 font-mono text-[0.7rem] border border-cyan/25 bg-cyan/8 text-cyan" style={{ fontSize: '0.65rem' }}>Era 2</span> <span style={{ fontSize: '0.75rem', color: 'var(--fg-dim)' }}>Multiplayer, fleets, PvP</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -93,11 +98,11 @@ export function OverviewPage() {
|
||||
|
||||
<div className="grid grid-cols-2 gap-5 max-[900px]:grid-cols-1">
|
||||
<div className="mb-6 rounded-xl border border-border bg-surface p-6 max-md:rounded-lg max-md:p-4" style={{ borderLeft: '3px solid var(--accent)' }}>
|
||||
<h4 style={{ color: 'var(--accent)' }}>Spreadsheet simulator, not flight sim</h4>
|
||||
<h4 style={{ color: 'var(--accent)' }}>Exploration-first, not spreadsheet-first</h4>
|
||||
<p style={{ color: 'var(--fg-dim)', fontSize: '0.85rem', margin: 0 }}>
|
||||
90% of gameplay happens in tables, charts, and panels: market order books, cargo manifests, fitting spreadsheets,
|
||||
route planners, ship AI logs, and chat channels. The 3D viewport gives spatial awareness, not twitch gameplay.
|
||||
Movement is click-to-autopilot. Combat is click-to-engage with FTL-style power management. <strong style={{ color: 'var(--fg)' }}>The depth is in the economy and information.</strong>
|
||||
The 3D viewport IS the game. Players spend their time flying between points of interest, discovering new sectors,
|
||||
and engaging with the world. Station panels handle trading, fitting, and services — but the joy is in
|
||||
the journey, not the ledger. <strong style={{ color: 'var(--fg)' }}>Trade, quest, fight, or simply set sail and enjoy the ambiance.</strong>
|
||||
</p>
|
||||
</div>
|
||||
<div className="mb-6 rounded-xl border border-border bg-surface p-6 max-md:rounded-lg max-md:p-4">
|
||||
@@ -108,20 +113,19 @@ export function OverviewPage() {
|
||||
</p>
|
||||
</div>
|
||||
<div className="mb-6 rounded-xl border border-border bg-surface p-6 max-md:rounded-lg max-md:p-4">
|
||||
<h4 style={{ color: 'var(--green)' }}>Information is the real currency</h4>
|
||||
<h4 style={{ color: 'var(--green)' }}>Every campaign is unique</h4>
|
||||
<p style={{ color: 'var(--fg-dim)', fontSize: '0.85rem', margin: 0 }}>
|
||||
Market data propagates at the speed of player travel, not the speed of light. Knowing a price discrepancy exists
|
||||
before other traders — that's the skill. The ship AI (Zora) is a living market intelligence tool. See the
|
||||
<em> Economy → 📡 Info Diffusion</em> tab for the full model.
|
||||
Procedurally generated galaxy maps ensure no two games are alike. Fog of war hides unexplored sectors.
|
||||
Factions, resource distributions, and quest chains vary per seed. Replayability through discovery, not grind.
|
||||
</p>
|
||||
</div>
|
||||
<div className="mb-6 rounded-xl border border-border bg-surface p-6 max-md:rounded-lg max-md:p-4">
|
||||
<h4 style={{ color: 'var(--purple)' }}>Movement & combat are not action</h4>
|
||||
<h4 style={{ color: 'var(--purple)' }}>FTL combat — captain, not pilot</h4>
|
||||
<p style={{ color: 'var(--fg-dim)', fontSize: '0.85rem', margin: 0 }}>
|
||||
The player never pilots the ship directly. Click a destination → ship autopilots. Click a hostile → ship auto-engages.
|
||||
The player never directly flies or aims. Click a destination → ship autopilots. Click a hostile → ship auto-engages.
|
||||
During combat, the player manages <strong style={{ color: 'var(--fg)' }}>reactor power allocation</strong> (FTL-style: weapons/shields/engines/aux)
|
||||
and <strong style={{ color: 'var(--fg)' }}>subsystem targeting</strong>. That's it. Ship destruction
|
||||
is an economic event (ISK sink, insurance payout, loot drop), not a competitive action moment. ISK (symbol ₢) is the canonical in-game currency.
|
||||
and <strong style={{ color: 'var(--fg)' }}>subsystem targeting</strong>. You are the chief engineer deciding where
|
||||
the reactor output goes — not the pilot or gunner.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -133,20 +137,19 @@ export function OverviewPage() {
|
||||
|
||||
<div className="mb-6 rounded-xl border border-border bg-surface p-6 max-md:rounded-lg max-md:p-4 border-l-[3px] border-l-accent" style={{ padding: 'var(--sp-6) var(--sp-8)' }}>
|
||||
<div style={{ fontFamily: 'var(--font-mono)', fontSize: '0.85rem', color: 'var(--fg-dim)', lineHeight: 2 }}>
|
||||
<span style={{ color: 'var(--cyan)' }}>Connect</span> → <span style={{ color: 'var(--accent)' }}>Spawn Ship</span> →{' '}
|
||||
<span style={{ color: 'var(--green)' }}>Navigate</span> →{' '}
|
||||
<span style={{ color: 'var(--purple)' }}>Mine</span> →{' '}
|
||||
<span style={{ color: 'var(--fg-bright)' }}>Inventory</span> →{' '}
|
||||
<span style={{ color: 'var(--cyan)' }}>Station</span> →{' '}
|
||||
<span style={{ color: 'var(--accent)' }}>Sell Ore</span> →{' '}
|
||||
<span style={{ color: 'var(--green)' }}>Chat</span>
|
||||
<span style={{ color: 'var(--cyan)' }}>Spawn</span> → <span style={{ color: 'var(--accent)' }}>Explore</span> →{' '}
|
||||
<span style={{ color: 'var(--green)' }}>Trade</span> →{' '}
|
||||
<span style={{ color: 'var(--purple)' }}>Quest</span> →{' '}
|
||||
<span style={{ color: 'var(--fg-bright)' }}>Fight</span> →{' '}
|
||||
<span style={{ color: 'var(--cyan)' }}>Upgrade Ship</span> →{' '}
|
||||
<span style={{ color: 'var(--accent)' }}>Sail Deeper</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mb-5 rounded-lg px-5 py-4 text-[0.85rem] leading-[1.5] border border-cyan/20 bg-cyan/8 text-cyan" style={{ marginBottom: 'var(--sp-5)' }}>
|
||||
<strong>The real loop is economic.</strong> Connect → gather information → identify opportunity → act on it → profit.
|
||||
The "mine → sell" cycle is the entry point. The endgame is inter-regional arbitrage, supply chain management,
|
||||
manufacturing empires, and market manipulation — all driven by <strong>information diffusion between systems</strong>.
|
||||
<strong>The real loop is adventure.</strong> Spawn → explore the unknown → discover opportunities → act on them → grow your ship and reputation → sail into deeper, riskier space.
|
||||
The "mine → sell" cycle is the entry point. The endgame is about faction influence, rare discoveries, commanding powerful ships,
|
||||
and shaping the galaxy through your choices — <strong>whether by trade, combat, or diplomacy</strong>.
|
||||
</div>
|
||||
|
||||
<h3 style={{ marginTop: 'var(--sp-6)' }}>Minimum Viable Screens</h3>
|
||||
@@ -193,9 +196,9 @@ export function OverviewPage() {
|
||||
</div>
|
||||
|
||||
<div className="mb-5 rounded-lg px-5 py-4 text-[0.85rem] leading-[1.5] border border-cyan/20 bg-cyan/8 text-cyan" style={{ marginBottom: 'var(--sp-5)' }}>
|
||||
<strong>Decision: Hybrid diegetic + panel approach.</strong>
|
||||
The game uses <strong>two distinct view modes</strong> depending on the player's state. This resolves the ambiguity
|
||||
between the gamehud demo (which renders diegetic overlays on a 3D viewport) and the spec's description of traditional panels.
|
||||
<strong>Decision: Hybrid immersive + panel approach.</strong>
|
||||
The game uses <strong>two distinct view modes</strong> depending on the player's state. When in space, the 3D viewport
|
||||
is the primary experience with diegetic HUD overlays. When docked at a station, traditional panel UI handles services.
|
||||
Both are correct — they apply to different contexts.
|
||||
</div>
|
||||
|
||||
@@ -267,13 +270,13 @@ export function OverviewPage() {
|
||||
</div>
|
||||
|
||||
<div className="mb-5 rounded-lg px-5 py-4 text-[0.85rem] leading-[1.5] border border-[rgba(240,160,48,0.25)] bg-[rgba(240,160,48,0.08)] text-accent">
|
||||
<strong>Why not all-diegetic or all-panel?</strong>
|
||||
A fully diegetic HUD (Dead Space style) works for immersion but is terrible for spreadsheet gameplay — you can't read
|
||||
an order book through a holographic visor. A fully panel UI (traditional MMO) loses the spatial awareness that makes
|
||||
space feel like space. The hybrid approach keeps the best of both: diegetic immersion during the action, panel efficiency
|
||||
during the economy game. The key insight is that <strong>the game alternates between two distinct cognitive modes</strong> —
|
||||
reactive (in-space, monitoring health/modules/overview) and analytical (docked, reading tables/planning routes).
|
||||
Each view mode is optimized for its cognitive mode.
|
||||
<strong>Why this hybrid approach?</strong>
|
||||
A fully diegetic HUD (Dead Space style) works for immersion but makes station services clunky — buying cargo through
|
||||
holographic menus is painful. A fully panel UI (traditional MMO) loses the spatial immersion that makes space feel
|
||||
like space. The hybrid keeps the best of both: immersive 3D exploration and combat, efficient panel-based station services.
|
||||
<strong>The game alternates between two modes</strong> —
|
||||
reactive (in-space, monitoring health/modules/threats) and analytical (docked, trading/fitting/planning).
|
||||
Each view mode is optimized for its mode.
|
||||
</div>
|
||||
|
||||
<div className="mb-5 flex items-center gap-3 border-b border-border pb-3 max-md:flex-col max-md:items-start max-md:gap-2 max-md:[&_h1]:text-[1.35rem] max-md:[&_h2]:text-[1.35rem]" style={{ marginTop: 'var(--sp-8)' }}>
|
||||
@@ -282,20 +285,20 @@ export function OverviewPage() {
|
||||
</div>
|
||||
|
||||
<div className="mb-5 rounded-lg px-5 py-4 text-[0.85rem] leading-[1.5] border border-cyan/20 bg-cyan/8 text-cyan" style={{ marginBottom: 'var(--sp-5)' }}>
|
||||
<strong>The first 30 minutes teach the game through doing, not reading.</strong> New players learn by playing a guided
|
||||
mission sequence that introduces each system naturally. There is no separate "tutorial mode" \u2014 the tutorial IS the game.
|
||||
See Economy \u2192 First 30 Minutes tab for the full moment-by-moment walkthrough.
|
||||
<strong>The first 30 minutes teach the game through adventure, not reading.</strong> New players learn by playing a guided
|
||||
mission sequence that introduces each system naturally — undocking, navigating, mining, trading, and their first combat encounter.
|
||||
There is no separate "tutorial mode" — the tutorial IS the game.
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 gap-5 max-[900px]:grid-cols-1" style={{ marginBottom: 'var(--sp-6)' }}>
|
||||
<div className="mb-6 rounded-xl border border-border bg-surface p-6 max-md:rounded-lg max-md:p-4" style={{ borderLeft: '3px solid var(--cyan)' }}>
|
||||
<h4 style={{ color: 'var(--cyan)' }}>Guided Mission Sequence</h4>
|
||||
<ul style={{ color: 'var(--fg-dim)', fontSize: '0.85rem', margin: 0, paddingLeft: 'var(--sp-5)' }}>
|
||||
<li><strong style={{ color: 'var(--fg)' }}>Mission 1:</strong> "Welcome, Pilot" \u2014 undock, warp to belt, mine 100 ore, dock, sell. Teaches: navigation, mining, market.</li>
|
||||
<li><strong style={{ color: 'var(--fg)' }}>Mission 2:</strong> "Armed and Ready" \u2014 accept kill mission, engage NPC frigate, manage power allocation, collect bounty. Teaches: combat, insurance.</li>
|
||||
<li><strong style={{ color: 'var(--fg)' }}>Mission 3:</strong> "Supply Chain" \u2014 refine ore, manufacture a module, fit it to ship. Teaches: industry, fitting.</li>
|
||||
<li><strong style={{ color: 'var(--fg)' }}>Mission 4:</strong> "Price Watcher" \u2014 fly to second station, compare prices, sell at the better one. Teaches: price discovery, trade routes.</li>
|
||||
<li><strong style={{ color: 'var(--fg)' }}>Mission 5:</strong> "Your AI Companion" \u2014 Zora introduces herself, explains her modules, offers first market tip. Teaches: Zora, AI modules.</li>
|
||||
<li><strong style={{ color: 'var(--fg)' }}>Mission 1:</strong> "Welcome, Captain" — undock, navigate to asteroid belt, mine 100 ore, dock, sell. Teaches: navigation, mining, market.</li>
|
||||
<li><strong style={{ color: 'var(--fg)' }}>Mission 2:</strong> "First Contact" — encounter an NPC hostile, manage FTL-style power allocation, survive the fight. Teaches: combat, damage, repair.</li>
|
||||
<li><strong style={{ color: 'var(--fg)' }}>Mission 3:</strong> "Supply Run" — accept a trade quest from a faction agent, deliver goods to another station, earn ISK and standing. Teaches: trade routes, factions.</li>
|
||||
<li><strong style={{ color: 'var(--fg)' }}>Mission 4:</strong> "The Bigger Ship" — earn enough ISK to buy a new ship class, fit it with modules. Teaches: ship acquisition, fitting.</li>
|
||||
<li><strong style={{ color: 'var(--fg)' }}>Mission 5:</strong> "Into the Unknown" — explore an uncharted sector, discover a hidden anomaly, encounter a world event. Teaches: exploration, discovery, the wider galaxy.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="mb-6 rounded-xl border border-border bg-surface p-6 max-md:rounded-lg max-md:p-4" style={{ borderLeft: '3px solid var(--green)' }}>
|
||||
|
||||
@@ -5,72 +5,72 @@ export function RoadmapPage() {
|
||||
const eras = [
|
||||
{
|
||||
id: 'solo',
|
||||
title: 'Era 1 — Single-Player Proof of Concept',
|
||||
subtitle: 'Validate core loops locally. SpacetimeDB runs on the local machine from Phase 0 — there is no localStorage. One browser window, one player, one simulated galaxy.',
|
||||
title: 'Era 1 — Single-Player Open-World RPG',
|
||||
subtitle: 'Validate the core adventure loop locally. SpacetimeDB runs on the local machine from Phase 0 — there is no localStorage. One browser window, one captain, one procedurally generated galaxy to explore.',
|
||||
accent: 'var(--accent)',
|
||||
phases: [
|
||||
{
|
||||
num: '0',
|
||||
title: 'Local Skeleton',
|
||||
goal: 'Vite app with local SpacetimeDB instance, game state manager, tick loop, and a single rendered star system.',
|
||||
doneWhen: 'App boots, connects to local SpacetimeDB instance. Shows a star system with a station and 3 asteroids. Game state updates on a local tick (60fps render, 1Hz sim tick). All persistence through SpacetimeDB — no localStorage.',
|
||||
title: 'Local Skeleton & Star System',
|
||||
goal: 'Vite app with local SpacetimeDB instance, rendered star system with station and asteroids. Player can connect and see the void.',
|
||||
doneWhen: 'App boots, connects to local SpacetimeDB instance. Shows a star system with a station and 3 asteroids. Ship visible in 3D viewport. Game state persists in SpacetimeDB — no localStorage.',
|
||||
status: 'current',
|
||||
},
|
||||
{
|
||||
num: '1',
|
||||
title: 'Movement & Commands',
|
||||
goal: 'Click-to-move autopilot with local path resolution. Ship accelerates, cruises, decelerates.',
|
||||
doneWhen: 'Click an asteroid or station. Ship plots a course and moves there with smooth interpolation. ETA display updates. Warp-to for distant objects works.',
|
||||
title: 'Navigation & Exploration',
|
||||
goal: 'Click-to-navigate autopilot with smooth ship movement. Warp-to for distant objects. Explore POIs within a system.',
|
||||
doneWhen: 'Click an asteroid, station, or anomaly. Ship plots a course and moves there with smooth interpolation. ETA display updates. Warp-to for distant objects works. Player can freely navigate the star system.',
|
||||
status: 'upcoming',
|
||||
},
|
||||
{
|
||||
num: '2',
|
||||
title: 'Mining & Inventory',
|
||||
goal: 'Asteroid mining cycle, ore extraction, cargo hold, and jettison.',
|
||||
doneWhen: 'Approach asteroid, start mining. Mining cycle shows progress. Ore appears in cargo. Cargo full warning. Can jettison into a can.',
|
||||
title: 'Mining, Inventory & Trade',
|
||||
goal: 'Asteroid mining cycle, ore extraction, cargo hold. NPC market for buying/selling goods. Regional price differences between stations.',
|
||||
doneWhen: 'Approach asteroid, start mining. Mining cycle shows progress. Ore appears in cargo. Dock at station, sell ore for ISK. Fly to another station — prices are different. Buy low / sell high works.',
|
||||
status: 'upcoming',
|
||||
},
|
||||
{
|
||||
num: '3',
|
||||
title: 'Combat — FTL Power Allocation',
|
||||
goal: 'Auto-engage combat with reactor power management between weapons / shields / engines.',
|
||||
doneWhen: 'Target a hostile NPC. Ship auto-engages. Player shifts reactor power between 3 subsystems (FTL-style). Power allocation visibly changes combat outcome. Ship can be destroyed.',
|
||||
goal: 'Auto-engage combat with reactor power management between weapons / shields / engines. Encounter NPC pirates at belts and anomalies.',
|
||||
doneWhen: 'Target a hostile NPC at a belt or anomaly. Ship auto-engages. Player shifts reactor power between subsystems (FTL-style). Power allocation visibly changes combat outcome. Ship can be destroyed. NPC pirates drop loot and bounty.',
|
||||
status: 'upcoming',
|
||||
},
|
||||
{
|
||||
num: '4',
|
||||
title: 'Ship Fitting',
|
||||
goal: 'CPU / Power Grid slot system. High / Med / Low racks with modules that change ship behavior.',
|
||||
doneWhen: 'Dock at station. Open fitting screen. Equip weapons in high slots, shield booster in mid, cargo expander in low. Fitting affects combat and mining stats. Invalid fits rejected (insufficient CPU/PG). AI module slot type added to fitting schema.',
|
||||
title: 'Ship Customization & Upgrades',
|
||||
goal: 'Multiple ship classes (scout, hauler, warship). Module fitting with High/Med/Low slots. CPU/PG constraints. Buy new ships at stations.',
|
||||
doneWhen: 'Dock at station. Open fitting screen. Equip weapons in high slots, shield booster in mid, cargo expander in low. Fitting affects combat and trade stats. Can buy a new ship class. Invalid fits rejected (insufficient CPU/PG).',
|
||||
status: 'upcoming',
|
||||
},
|
||||
{
|
||||
num: '5',
|
||||
title: 'Refining & Manufacturing',
|
||||
goal: 'Refine ore into minerals at a station. Use minerals to manufacture modules and ammo.',
|
||||
doneWhen: 'Dock with ore. Refine at station facility (with yield efficiency). Minerals stored locally. Open manufacturing tab, select a blueprint, queue a job. Job completes after sim time. Product appears in hangar.',
|
||||
title: 'Faction Quests & Dynamic World',
|
||||
goal: 'NPC agents offer quests (kill, courier, mining, exploration). Faction standing system. Station prosperity responds to player supply. Dynamic world events spawn.',
|
||||
doneWhen: 'Talk to NPC agent at station. Accept a quest (deliver cargo, kill pirates, explore anomaly). Complete quest for ISK + standing. Standing unlocks better quests and prices. Supplying a station increases its prosperity. World events spawn in explored systems.',
|
||||
status: 'upcoming',
|
||||
},
|
||||
{
|
||||
num: '6',
|
||||
title: 'NPC Economy Sim',
|
||||
goal: 'Simulated NPC market with supply/demand. Prices react to player trades. Regional price differences.',
|
||||
doneWhen: 'Sell ore at a station. Price adjusts (supply increases, price drops). Fly to another system, price is different. Buy low / sell high works. Market history table shows price movement.',
|
||||
title: 'Industry & Economy Depth',
|
||||
goal: 'Refining ore into minerals. Manufacturing modules and items. Full NPC market with supply/demand. Price history and regional differences.',
|
||||
doneWhen: 'Dock with ore. Refine at station. Minerals appear in hangar. Open manufacturing tab, select a blueprint, queue a job. Job completes. Product appears. Sell on NPC market. Prices react to trades. Different stations have different prices.',
|
||||
status: 'upcoming',
|
||||
},
|
||||
{
|
||||
num: '7',
|
||||
title: 'Single-Player Polish',
|
||||
goal: 'Complete HUD, notifications, empty states, tutorial hints, and save/load.',
|
||||
doneWhen: 'Full game loop is playable solo: mine → refine → manufacture → fit → fight → trade. HUD shows all relevant info. SpacetimeDB persists all state (ships, inventory, market, skills) — no localStorage. No dead-end states. Tier 0 Zora: status readouts, basic shield warnings, bare-bones soul state vector in SpacetimeDB. Lightweight exploration events spawn in visited systems.',
|
||||
title: 'Single-Player Polish & Procedural Galaxy',
|
||||
goal: 'Procedurally generated multi-system galaxy. Fog of war. Full HUD. Notifications. Tutorial sequence. Ship AI companion (Zora Tier 0). Save/load.',
|
||||
doneWhen: 'Full game loop is playable solo: explore → mine → trade → quest → fight → upgrade → explore deeper. Procedural galaxy generates unique systems each campaign. Fog of war reveals as you travel. HUD shows all relevant info. Tutorial guides new players through first 30 minutes. SpacetimeDB persists all state.',
|
||||
status: 'future',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'multi',
|
||||
title: 'Era 2 — Multiplayer Environment',
|
||||
subtitle: 'Promote local SpacetimeDB to a shared server. Add multiplayer networking, social systems, and the full living galaxy simulation. Multiple players, one persistent world.',
|
||||
title: 'Era 2 — Multiplayer & Living Galaxy',
|
||||
subtitle: 'Promote local SpacetimeDB to a shared server. Add multiplayer co-op, social systems, PvP, and the full living galaxy simulation. Multiple captains, one persistent universe.',
|
||||
accent: 'var(--cyan)',
|
||||
phases: [
|
||||
{
|
||||
@@ -181,15 +181,15 @@ export function RoadmapPage() {
|
||||
<div className="mx-auto max-w-content">
|
||||
<h1 style={{ marginBottom: '8px' }}>Development Roadmap</h1>
|
||||
<p style={{ color: 'var(--fg-dim)', fontSize: '0.95rem', maxWidth: '720px' }}>
|
||||
Two eras, sixteen phases. <strong style={{ color: 'var(--fg)' }}>Era 1</strong> proves the game is fun as a single-player simulation with a local
|
||||
SpacetimeDB instance — the same persistence architecture as multiplayer, just one player. <strong style={{ color: 'var(--fg)' }}>Era 2</strong> promotes
|
||||
that local SpacetimeDB to a shared server and adds social systems, the living galaxy, and multiplayer combat.
|
||||
Two eras, sixteen phases. <strong style={{ color: 'var(--fg)' }}>Era 1</strong> proves the game is fun as a single-player open-world space RPG
|
||||
with a local SpacetimeDB instance — exploration, trading, FTL-style combat, ship customization, and faction quests.
|
||||
<strong style={{ color: 'var(--fg)' }}>Era 2</strong> promotes that local SpacetimeDB to a shared server and adds multiplayer, social systems, the living galaxy, and co-op play.
|
||||
Each phase has a verifiable done-when condition. Integration gates between phase groups ensure every system works together before advancing.
|
||||
</p>
|
||||
|
||||
<div className="mb-5 rounded-lg px-5 py-4 text-[0.85rem] leading-[1.5] border border-cyan/20 bg-cyan/8 text-cyan" style={{ marginTop: 'var(--sp-4)', maxWidth: '720px' }}>
|
||||
<strong>Why single-player first with local SpacetimeDB?</strong> Networking is the biggest source of bugs and complexity.
|
||||
By validating that mining, combat, fitting, and the economy are fun locally — using the <em>same</em> SpacetimeDB
|
||||
By validating that exploration, trading, combat, fitting, and faction quests are fun locally — using the <em>same</em> SpacetimeDB
|
||||
persistence that will serve multiplayer — we de-risk the entire project. There is no localStorage; SpacetimeDB is the
|
||||
persistence layer from day 1. When Era 2 begins, the question is only "how do we share this server?" — not
|
||||
"is this game fun?" or "will the persistence migration work?"
|
||||
@@ -205,35 +205,37 @@ export function RoadmapPage() {
|
||||
</p>
|
||||
<div className="grid grid-cols-2 gap-5 max-[900px]:grid-cols-1" style={{ marginBottom: 'var(--sp-6)' }}>
|
||||
<div className="mb-6 rounded-xl border border-border bg-surface p-6 max-md:rounded-lg max-md:p-4" style={{ borderLeft: '3px solid var(--accent)' }}>
|
||||
<h4 style={{ color: 'var(--accent)' }}>Gate 1 — Core Loop (after Phase 2)</h4>
|
||||
<h4 style={{ color: 'var(--accent)' }}>Gate 1 — Exploration & Trade Loop (after Phase 2)</h4>
|
||||
<p style={{ color: 'var(--fg-dim)', fontSize: '0.85rem', margin: '0 0 var(--sp-2) 0' }}>
|
||||
Navigate to asteroid → mine → fill cargo → dock → sell ore. The complete economic loop runs in a single session
|
||||
without errors. SpacetimeDB persists the session — closing the browser and reopening restores state.
|
||||
Navigate to asteroid → mine → fill cargo → dock → sell ore → navigate to another station → discover price difference → trade.
|
||||
The complete exploration and trade loop runs in a single session without errors. The galaxy feels alive and explorable.
|
||||
SpacetimeDB persists the session — closing the browser and reopening restores state.
|
||||
</p>
|
||||
<div style={{ fontFamily: 'var(--font-mono)', fontSize: '0.72rem', color: 'var(--muted)' }}>Phases covered: 0, 1, 2</div>
|
||||
</div>
|
||||
<div className="mb-6 rounded-xl border border-border bg-surface p-6 max-md:rounded-lg max-md:p-4" style={{ borderLeft: '3px solid var(--red)' }}>
|
||||
<h4 style={{ color: 'var(--red)' }}>Gate 2 — Combat + Fitting (after Phase 4)</h4>
|
||||
<h4 style={{ color: 'var(--red)' }}>Gate 2 — Combat + Customization (after Phase 4)</h4>
|
||||
<p style={{ color: 'var(--fg-dim)', fontSize: '0.85rem', margin: '0 0 var(--sp-2) 0' }}>
|
||||
Fit a ship at station → undock → encounter NPC pirate → manage power allocation → destroy or be destroyed →
|
||||
insurance payout (if destroyed) → refit at station. Combat and fitting form a closed loop with economic consequences.
|
||||
Customize a ship at station → undock → encounter NPC pirate → manage FTL power allocation → destroy or be destroyed →
|
||||
collect loot → buy upgrades → try a different ship class. Combat and ship customization form a satisfying adventure loop.
|
||||
</p>
|
||||
<div style={{ fontFamily: 'var(--font-mono)', fontSize: '0.72rem', color: 'var(--muted)' }}>Phases covered: 0–4</div>
|
||||
</div>
|
||||
<div className="mb-6 rounded-xl border border-border bg-surface p-6 max-md:rounded-lg max-md:p-4" style={{ borderLeft: '3px solid var(--green)' }}>
|
||||
<h4 style={{ color: 'var(--green)' }}>Gate 3 — Full Economy (after Phase 6)</h4>
|
||||
<h4 style={{ color: 'var(--green)' }}>Gate 3 — Full Adventure Loop (after Phase 6)</h4>
|
||||
<p style={{ color: 'var(--fg-dim)', fontSize: '0.85rem', margin: '0 0 var(--sp-2) 0' }}>
|
||||
Mine ore → refine → manufacture a module → fit it → use it in combat → sell excess minerals across systems at different prices.
|
||||
The complete production chain and NPC market work as an integrated system. Price differences between stations are discoverable.
|
||||
Explore → mine ore → refine → manufacture a module → fit it → fight pirates → accept faction quest → deliver goods →
|
||||
earn standing → unlock better missions → sell excess across stations at different prices.
|
||||
The complete adventure: exploration, economy, industry, and faction systems work as an integrated whole.
|
||||
</p>
|
||||
<div style={{ fontFamily: 'var(--font-mono)', fontSize: '0.72rem', color: 'var(--muted)' }}>Phases covered: 0–6</div>
|
||||
</div>
|
||||
<div className="mb-6 rounded-xl border border-border bg-surface p-6 max-md:rounded-lg max-md:p-4" style={{ borderLeft: '3px solid var(--cyan)' }}>
|
||||
<h4 style={{ color: 'var(--cyan)' }}>Gate 4 — Era 1 Complete (after Phase 7)</h4>
|
||||
<p style={{ color: 'var(--fg-dim)', fontSize: '0.85rem', margin: '0 0 var(--sp-2) 0' }}>
|
||||
Full solo game loop with all systems integrated: mine → refine → manufacture → fit → fight → trade → repeat.
|
||||
HUD, notifications, Zora Tier 0, exploration events, and missions all work without dead ends. A new player
|
||||
can learn the game in one session. SpacetimeDB state survives restart.
|
||||
Full solo game with all systems integrated: explore → mine → trade → quest → fight → customize → sail deeper.
|
||||
Procedurally generated galaxy. Fog of war. HUD, notifications, Zora Tier 0, world events, tutorial sequence.
|
||||
A new player can learn the game in one session and want to keep going. SpacetimeDB state survives restart.
|
||||
</p>
|
||||
<div style={{ fontFamily: 'var(--font-mono)', fontSize: '0.72rem', color: 'var(--muted)' }}>Phases covered: 0–7 (all Era 1)</div>
|
||||
</div>
|
||||
@@ -248,8 +250,9 @@ export function RoadmapPage() {
|
||||
<div className="mb-6 rounded-xl border border-border bg-surface p-6 max-md:rounded-lg max-md:p-4" style={{ borderLeft: '3px solid var(--fg-dim)' }}>
|
||||
<h4 style={{ color: 'var(--fg-dim)' }}>Gate 6 — Launch Ready (after Phase 15)</h4>
|
||||
<p style={{ color: 'var(--fg-dim)', fontSize: '0.85rem', margin: '0 0 var(--sp-2) 0' }}>
|
||||
Fresh player can: create account, complete tutorial, mine ore, fit ship, survive PvE, make a trade, join a corp,
|
||||
participate in a world event — all without crashes or dead ends. Server handles 50 concurrent. Full game loop validated.
|
||||
Fresh player can: create account, complete tutorial, explore their first system, mine and trade, survive a PvE encounter,
|
||||
customize their ship, accept and complete a faction quest, join a crew with friends — all without crashes or dead ends.
|
||||
Server handles 50 concurrent players. Full game loop validated.
|
||||
</p>
|
||||
<div style={{ fontFamily: 'var(--font-mono)', fontSize: '0.72rem', color: 'var(--muted)' }}>Phases covered: 0–15 (all)</div>
|
||||
</div>
|
||||
|
||||
@@ -81,11 +81,11 @@ export function ShipsPage() {
|
||||
|
||||
return (
|
||||
<div className="mx-auto max-w-content">
|
||||
<h1 style={{ marginBottom: '8px' }}>Ships & Fitting System</h1>
|
||||
<h1 style={{ marginBottom: '8px' }}>Ships & Customization</h1>
|
||||
<p style={{ color: 'var(--fg-dim)', fontSize: '0.95rem', maxWidth: '680px' }}>
|
||||
Ships are the player's primary asset. Each ship has a slot layout with CPU and Power Grid limits
|
||||
that constrain what modules can be fitted. Players own multiple ships and can assign AI crew to
|
||||
pilot them on autonomous tasks.
|
||||
Build the ship that suits your style — a tough juggernaut that can take a beating, a nimble scout that rains fire from afar,
|
||||
or a cargo hauler keeping trade routes supplied. Swap out weapons for extra armor, or add mining lasers to become an industrial powerhouse.
|
||||
Each ship has a slot layout with CPU and Power Grid limits that constrain what modules can be fitted.
|
||||
</p>
|
||||
|
||||
{/* Tab navigation */}
|
||||
|
||||
922
apps/docs/src/pages/docs/TodoPage.tsx
Normal file
922
apps/docs/src/pages/docs/TodoPage.tsx
Normal file
@@ -0,0 +1,922 @@
|
||||
// @ts-nocheck
|
||||
import * as React from 'react';
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
|
||||
const LAST_UPDATED = '2026-06-02';
|
||||
const BACKEND_TABLES_IMPLEMENTED = 9;
|
||||
const BACKEND_TABLES_DESIGNED = 56;
|
||||
const BACKEND_REDUCERS_IMPLEMENTED = 12;
|
||||
const BACKEND_REDUCERS_DESIGNED = 40;
|
||||
|
||||
type Phase = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7';
|
||||
type Layer = 'backend' | 'frontend' | 'scene' | 'prototype';
|
||||
type Status = 'done' | 'partial' | 'missing' | 'blocked';
|
||||
|
||||
interface TodoItem {
|
||||
id: string;
|
||||
title: string;
|
||||
phase: Phase;
|
||||
layer: Layer;
|
||||
status: Status;
|
||||
desc: string;
|
||||
detail?: string;
|
||||
files?: string;
|
||||
blockedBy?: string[];
|
||||
}
|
||||
|
||||
const STATUS_COLORS: Record<Status, string> = {
|
||||
done: 'var(--green)',
|
||||
partial: 'var(--accent)',
|
||||
missing: 'var(--red)',
|
||||
blocked: 'var(--muted)',
|
||||
};
|
||||
|
||||
const STATUS_LABELS: Record<Status, string> = {
|
||||
done: 'DONE',
|
||||
partial: 'PARTIAL',
|
||||
missing: 'MISSING',
|
||||
blocked: 'BLOCKED',
|
||||
};
|
||||
|
||||
const LAYER_LABELS: Record<Layer, string> = {
|
||||
backend: 'SpacetimeDB',
|
||||
frontend: 'Game UI',
|
||||
scene: '3D Scene',
|
||||
prototype: 'Prototype Ready',
|
||||
};
|
||||
|
||||
const items: TodoItem[] = [
|
||||
// ── PHASE 0: LOCAL SKELETON ──
|
||||
{
|
||||
id: 'P0-B1',
|
||||
title: 'Player identity & connection',
|
||||
phase: '0',
|
||||
layer: 'backend',
|
||||
status: 'done',
|
||||
desc: 'Player table, connectPlayer, renamePlayer, ping reducers. Auth token persistence.',
|
||||
files: 'services/spacetimedb/src/index.ts:143-218',
|
||||
},
|
||||
{
|
||||
id: 'P0-B2',
|
||||
title: 'World seeding (single system)',
|
||||
phase: '0',
|
||||
layer: 'backend',
|
||||
status: 'done',
|
||||
desc: 'seedWorld creates Solace system, station, 2 POIs. Hardcoded constants.',
|
||||
files: 'services/spacetimedb/src/index.ts:138-141, 458-500',
|
||||
},
|
||||
{
|
||||
id: 'P0-B3',
|
||||
title: 'Ship state & wallet',
|
||||
phase: '0',
|
||||
layer: 'backend',
|
||||
status: 'done',
|
||||
desc: 'Ship table (position, flightMode, dockedStationId, cargoCapacity). Wallet table with ISK.',
|
||||
files: 'services/spacetimedb/src/index.ts:28-45, 93-100',
|
||||
},
|
||||
{
|
||||
id: 'P0-B4',
|
||||
title: 'Server event logging',
|
||||
phase: '0',
|
||||
layer: 'backend',
|
||||
status: 'done',
|
||||
desc: 'ServerEvent table. Every reducer writes a typed event.',
|
||||
files: 'services/spacetimedb/src/index.ts:114-123, 580-588',
|
||||
},
|
||||
{
|
||||
id: 'P0-F1',
|
||||
title: 'SpacetimeDB client connection',
|
||||
phase: '0',
|
||||
layer: 'frontend',
|
||||
status: 'done',
|
||||
desc: 'Connection lifecycle, table subscriptions, auth token, re-render triggers.',
|
||||
files: 'apps/game/src/spacetime/client.ts, useSpacetimeConnection.ts, useGameSession.ts',
|
||||
},
|
||||
{
|
||||
id: 'P0-F2',
|
||||
title: 'Game shell layout',
|
||||
phase: '0',
|
||||
layer: 'frontend',
|
||||
status: 'partial',
|
||||
desc: 'Three-column responsive layout with left/right sidebars and center 3D viewport. Missing: center panel area is empty (hidden on large screens). No loading/splash screen.',
|
||||
detail: 'Middle column <section> is hidden lg:block with no content. No station mode panel swap. Inline "Pilot" info should be its own component.',
|
||||
files: 'apps/game/src/GameShell.tsx:70',
|
||||
},
|
||||
{
|
||||
id: 'P0-F3',
|
||||
title: 'Connection panel',
|
||||
phase: '0',
|
||||
layer: 'frontend',
|
||||
status: 'done',
|
||||
desc: 'Connection status, identity, transport/reducer messages, pilot name input, rename/ping.',
|
||||
files: 'apps/game/src/ui/ConnectionPanel.tsx',
|
||||
},
|
||||
{
|
||||
id: 'P0-S1',
|
||||
title: '3D space scene foundation',
|
||||
phase: '0',
|
||||
layer: 'scene',
|
||||
status: 'partial',
|
||||
desc: 'R3F Canvas, environment (stars, fog, lights), station mesh, asteroid mesh, ship mesh. All clickable.',
|
||||
detail: 'Missing: camera controls (no orbit/zoom/pan — fixed position). No sun/star light source. No nebulae. Grid plane is debug-only.',
|
||||
files: 'apps/game/src/scene/',
|
||||
},
|
||||
{
|
||||
id: 'P0-S2',
|
||||
title: 'Ship mesh with engine glow',
|
||||
phase: '0',
|
||||
layer: 'scene',
|
||||
status: 'partial',
|
||||
desc: 'Cone+box+sphere ship. Engine glow changes by flightMode. Bob/roll animation.',
|
||||
detail: 'Missing: no damage state visualization, no shield bubble, no warp animation, no mining laser beam (only flat Line), no module hardpoints visible.',
|
||||
files: 'apps/game/src/scene/ShipMesh.tsx',
|
||||
},
|
||||
|
||||
// ── PHASE 1: NAVIGATION & EXPLORATION ──
|
||||
{
|
||||
id: 'P1-B1',
|
||||
title: 'Approach operation (start + complete)',
|
||||
phase: '1',
|
||||
layer: 'backend',
|
||||
status: 'done',
|
||||
desc: 'Timed approach with 5s duration. Validates undocked, target selected, target in system. Position update on complete.',
|
||||
files: 'services/spacetimedb/src/index.ts:248-299',
|
||||
},
|
||||
{
|
||||
id: 'P1-B2',
|
||||
title: 'Target selection',
|
||||
phase: '1',
|
||||
layer: 'backend',
|
||||
status: 'done',
|
||||
desc: 'selectTarget validates POI exists and is in current system.',
|
||||
files: 'services/spacetimedb/src/index.ts:236-246',
|
||||
},
|
||||
{
|
||||
id: 'P1-B3',
|
||||
title: 'Warp travel between systems',
|
||||
phase: '1',
|
||||
layer: 'backend',
|
||||
status: 'missing',
|
||||
desc: 'No stargate table, no warp sequence, no jump mechanics. Ship is locked to single system (Solace).',
|
||||
blockedBy: ['P5-B3'],
|
||||
},
|
||||
{
|
||||
id: 'P1-B4',
|
||||
title: 'Stargate network',
|
||||
phase: '1',
|
||||
layer: 'backend',
|
||||
status: 'missing',
|
||||
desc: 'No stargate table. No gate activation range, jump cooldown, gate cloak. Design describes full stargate mechanics.',
|
||||
},
|
||||
{
|
||||
id: 'P1-F1',
|
||||
title: 'Mini star map (SVG)',
|
||||
phase: '1',
|
||||
layer: 'frontend',
|
||||
status: 'done',
|
||||
desc: '2D SVG top-down system map showing POIs, ship position, operation lines, click-to-select.',
|
||||
files: 'apps/game/src/ui/MiniStarMap.tsx',
|
||||
},
|
||||
{
|
||||
id: 'P1-F2',
|
||||
title: 'Target panel with POI list',
|
||||
phase: '1',
|
||||
layer: 'frontend',
|
||||
status: 'partial',
|
||||
desc: 'Shows selected target and clickable POI list.',
|
||||
detail: 'Missing: no distance to target, no spatial grouping, no range info, no sortable overview-style list.',
|
||||
files: 'apps/game/src/ui/TargetPanel.tsx',
|
||||
},
|
||||
{
|
||||
id: 'P1-F3',
|
||||
title: 'Command rail (contextual actions)',
|
||||
phase: '1',
|
||||
layer: 'frontend',
|
||||
status: 'partial',
|
||||
desc: 'Bottom-fixed action bar with contextual buttons and progress bars for operations.',
|
||||
detail: 'Missing: no abort/cancel operation, no warp/jump commands, no combat commands, no station service buttons, keyboard shortcut hints not visible.',
|
||||
files: 'apps/game/src/ui/CommandRail.tsx',
|
||||
},
|
||||
{
|
||||
id: 'P1-F4',
|
||||
title: 'Keyboard shortcuts',
|
||||
phase: '1',
|
||||
layer: 'frontend',
|
||||
status: 'partial',
|
||||
desc: 'U=undock, D=dock, A=approach, M=mine, 1-9=select target.',
|
||||
detail: 'Missing: no shortcut for sell, refine, fit, combat, warp. No modifier keys. No shortcut discovery overlay.',
|
||||
files: 'apps/game/src/ui/useKeyboardShortcuts.ts',
|
||||
},
|
||||
{
|
||||
id: 'P1-S1',
|
||||
title: 'Ship position interpolation during approach',
|
||||
phase: '1',
|
||||
layer: 'scene',
|
||||
status: 'done',
|
||||
desc: 'Lerp-based smooth movement from current position to target during approach operation.',
|
||||
files: 'apps/game/src/scene/GameSpaceScene.tsx',
|
||||
},
|
||||
{
|
||||
id: 'P1-S2',
|
||||
title: 'Camera controls (orbit, zoom, pan)',
|
||||
phase: '1',
|
||||
layer: 'scene',
|
||||
status: 'missing',
|
||||
desc: 'Camera is fixed at [8,9,44] with gentle sine drift. No OrbitControls, no zoom, no user camera interaction.',
|
||||
},
|
||||
{
|
||||
id: 'P1-S3',
|
||||
title: 'Warp/travel visual effects',
|
||||
phase: '1',
|
||||
layer: 'scene',
|
||||
status: 'missing',
|
||||
desc: 'No warp tunnel effect, no gate jump animation, no system transition. Prototype has a full warp sequence demo.',
|
||||
files: 'Prototype ref: apps/docs/src/prototypes/existing-demos/WarpTravelDemo.tsx',
|
||||
},
|
||||
|
||||
// ── PHASE 2: MINING, INVENTORY & TRADE ──
|
||||
{
|
||||
id: 'P2-B1',
|
||||
title: 'Mining operation (start + complete)',
|
||||
phase: '2',
|
||||
layer: 'backend',
|
||||
status: 'done',
|
||||
desc: 'Timed mining with 6s duration. Validates undocked, at asteroid belt, cargo not full. Adds 1000 Veldspar to cargo.',
|
||||
files: 'services/spacetimedb/src/index.ts:326-409',
|
||||
},
|
||||
{
|
||||
id: 'P2-B2',
|
||||
title: 'Cargo/inventory system',
|
||||
phase: '2',
|
||||
layer: 'backend',
|
||||
status: 'partial',
|
||||
desc: 'CargoItem table with stacking. Capacity tracking.',
|
||||
detail: 'Missing: only "ore" category used. No mineral, module, loot, commodity categories. No jettison. No item splitting.',
|
||||
files: 'services/spacetimedb/src/index.ts:79-91',
|
||||
},
|
||||
{
|
||||
id: 'P2-B3',
|
||||
title: 'NPC ore market (sell only)',
|
||||
phase: '2',
|
||||
layer: 'backend',
|
||||
status: 'partial',
|
||||
desc: 'sellOreToNpcMarket validates docked, ore category, quantity. Credits wallet.',
|
||||
detail: 'Missing: only 1 ore type (Veldspar) at fixed 12 ISK. No NPC buy orders for minerals/modules. No sell-side NPC. No dynamic pricing. No regional variation. Prices hardcoded in both backend AND frontend.',
|
||||
files: 'services/spacetimedb/src/index.ts:411-456',
|
||||
},
|
||||
{
|
||||
id: 'P2-B4',
|
||||
title: 'Dynamic NPC pricing (supply/demand)',
|
||||
phase: '2',
|
||||
layer: 'backend',
|
||||
status: 'missing',
|
||||
desc: 'Design describes full NPC pricing algorithm with EMA, demand pressure, regional seeds, anti-arbitrage. Nothing implemented.',
|
||||
},
|
||||
{
|
||||
id: 'P2-B5',
|
||||
title: 'Regional price differences',
|
||||
phase: '2',
|
||||
layer: 'backend',
|
||||
status: 'missing',
|
||||
desc: 'Single system only. No way for prices to differ between stations.',
|
||||
blockedBy: ['P1-B3', 'P5-B3'],
|
||||
},
|
||||
{
|
||||
id: 'P2-F1',
|
||||
title: 'Cargo panel',
|
||||
phase: '2',
|
||||
layer: 'frontend',
|
||||
status: 'partial',
|
||||
desc: 'Displays cargo items with name, quantity, category, unit price.',
|
||||
detail: 'Missing: no jettison button, no item stacking/splitting, no item details, no ore-type filtering.',
|
||||
files: 'apps/game/src/ui/CargoPanel.tsx',
|
||||
},
|
||||
{
|
||||
id: 'P2-F2',
|
||||
title: 'NPC market panel',
|
||||
phase: '2',
|
||||
layer: 'frontend',
|
||||
status: 'partial',
|
||||
desc: 'Sell ore UI with quantity input, max button, payout preview. Only visible when docked.',
|
||||
detail: 'Missing: only Veldspar. Prices hardcoded client-side in NPC_PRICES constant. No buy orders, no order book, no price history, no charts.',
|
||||
files: 'apps/game/src/ui/NpcMarketPanel.tsx:5-7',
|
||||
},
|
||||
{
|
||||
id: 'P2-F3',
|
||||
title: 'Wallet panel',
|
||||
phase: '2',
|
||||
layer: 'frontend',
|
||||
status: 'partial',
|
||||
desc: 'Shows ISK balance.',
|
||||
detail: 'Missing: no transaction history, no income/expenditure breakdown.',
|
||||
files: 'apps/game/src/ui/WalletPanel.tsx',
|
||||
},
|
||||
{
|
||||
id: 'P2-F4',
|
||||
title: 'Ship status panel',
|
||||
phase: '2',
|
||||
layer: 'frontend',
|
||||
status: 'partial',
|
||||
desc: 'Flight mode badge, hull/shield/speed bars, position, system, operation countdown.',
|
||||
detail: 'HARDCODED: hullPct=100 always (line 44), shieldPct=Math.random() (line 45), cargoPct always 0 (line 46), speed labels are hardcoded strings (lines 32-42). No armor layer. No capacitor. No power allocation. No module activation indicators.',
|
||||
files: 'apps/game/src/ui/ShipStatusPanel.tsx:44-46',
|
||||
},
|
||||
{
|
||||
id: 'P2-S1',
|
||||
title: 'Asteroid rendering (per-belt clusters)',
|
||||
phase: '2',
|
||||
layer: 'scene',
|
||||
status: 'partial',
|
||||
desc: '3 asteroids per belt with hardcoded offsets, tumble animation, clickable.',
|
||||
detail: 'Missing: all identical geometry/color. No ore type differentiation. No depletion state. No mining laser beam (flat Line only).',
|
||||
files: 'apps/game/src/scene/AsteroidMesh.tsx, GameSpaceScene.tsx:120-124',
|
||||
},
|
||||
{
|
||||
id: 'P2-S2',
|
||||
title: 'Mining laser beam visual',
|
||||
phase: '2',
|
||||
layer: 'scene',
|
||||
status: 'missing',
|
||||
desc: 'Only a flat amber Line drawn during mining. No beam/particle effect connecting ship to asteroid.',
|
||||
},
|
||||
|
||||
// ── PHASE 3: COMBAT — FTL POWER ALLOCATION ──
|
||||
{
|
||||
id: 'P3-B1',
|
||||
title: 'NPC pirate entity system',
|
||||
phase: '3',
|
||||
layer: 'backend',
|
||||
status: 'missing',
|
||||
desc: 'No npc_entities, npc_class_templates, or loot_tables. Design describes full NPC spawning, AI behavior, state machine (IDLE→AGGRO→COMBAT→FLEE→DEAD).',
|
||||
},
|
||||
{
|
||||
id: 'P3-B2',
|
||||
title: 'Combat encounter state',
|
||||
phase: '3',
|
||||
layer: 'backend',
|
||||
status: 'missing',
|
||||
desc: 'No combat session, no damage resolution, no shield/armor/hull tracking, no weapon cycling.',
|
||||
},
|
||||
{
|
||||
id: 'P3-B3',
|
||||
title: 'FTL power allocation (weapons/shields/engines/aux)',
|
||||
phase: '3',
|
||||
layer: 'backend',
|
||||
status: 'missing',
|
||||
desc: 'Design describes 4 subsystems with powered/unpowered behavior, reroute timing (1.5-3s), and failure modes. Nothing implemented.',
|
||||
},
|
||||
{
|
||||
id: 'P3-B4',
|
||||
title: 'Ship health model (shield/armor/hull)',
|
||||
phase: '3',
|
||||
layer: 'backend',
|
||||
status: 'missing',
|
||||
desc: 'Ship table has no health columns. Design describes 3 HP pools with different damage resistance.',
|
||||
},
|
||||
{
|
||||
id: 'P3-B5',
|
||||
title: 'Bounty & loot drop system',
|
||||
phase: '3',
|
||||
layer: 'backend',
|
||||
status: 'missing',
|
||||
desc: 'No bounty ISK awards, no loot tables, no wreck/loot containers. Design describes full bounty tiers and module drops.',
|
||||
},
|
||||
{
|
||||
id: 'P3-B6',
|
||||
title: 'Ship destruction & respawn',
|
||||
phase: '3',
|
||||
layer: 'backend',
|
||||
status: 'missing',
|
||||
desc: 'No death mechanic, no respawn, no insurance payout. Design describes rookie frigate respawn, loot drops, insurance.',
|
||||
},
|
||||
{
|
||||
id: 'P3-F1',
|
||||
title: 'Combat HUD (target lock, power allocation, damage)',
|
||||
phase: '3',
|
||||
layer: 'frontend',
|
||||
status: 'missing',
|
||||
desc: 'No combat UI at all. Design describes target lock reticle, power allocation bars (W/S/E/Aux), shield/armor/hull wheel, capacitor gauge, weapon timer, combat log.',
|
||||
files: 'Prototype ref: apps/docs/src/prototypes/existing-demos/CombatDemo.tsx, game-slice/ui/SliceCombatStage.tsx',
|
||||
},
|
||||
{
|
||||
id: 'P3-S1',
|
||||
title: 'Combat 3D scene (projectiles, shields, explosions)',
|
||||
phase: '3',
|
||||
layer: 'scene',
|
||||
status: 'missing',
|
||||
desc: 'No NPC ships rendered, no projectiles, no shield effects, no explosions, no damage numbers.',
|
||||
files: 'Prototype ref: apps/docs/src/prototypes/r3f/combat/CombatScene.tsx',
|
||||
},
|
||||
|
||||
// ── PHASE 4: SHIP CUSTOMIZATION & UPGRADES ──
|
||||
{
|
||||
id: 'P4-B1',
|
||||
title: 'Ship types catalog (multiple classes)',
|
||||
phase: '4',
|
||||
layer: 'backend',
|
||||
status: 'missing',
|
||||
desc: 'Only 1 hardcoded "Starter Frigate". Design describes 5 classes (Frigate through Battleship) with full stat tables.',
|
||||
},
|
||||
{
|
||||
id: 'P4-B2',
|
||||
title: 'Module catalog & fitting system',
|
||||
phase: '4',
|
||||
layer: 'backend',
|
||||
status: 'missing',
|
||||
desc: 'No modules_catalog, no ship_fittings table. Design describes High/Med/Low slot types, CPU/PG constraints, module categories.',
|
||||
},
|
||||
{
|
||||
id: 'P4-B3',
|
||||
title: 'Fit/unfit module reducers',
|
||||
phase: '4',
|
||||
layer: 'backend',
|
||||
status: 'missing',
|
||||
desc: 'No reducers for module management. Design validates CPU/PG budget, slot type matching.',
|
||||
},
|
||||
{
|
||||
id: 'P4-B4',
|
||||
title: 'Ship purchase/acquisition',
|
||||
phase: '4',
|
||||
layer: 'backend',
|
||||
status: 'missing',
|
||||
desc: 'No ship buying, no hangar storage, no ship switching. Design describes NPC market, hangar, and rookie frigate policy.',
|
||||
},
|
||||
{
|
||||
id: 'P4-F1',
|
||||
title: 'Fitting screen UI',
|
||||
phase: '4',
|
||||
layer: 'frontend',
|
||||
status: 'missing',
|
||||
desc: 'No fitting UI. Design describes slot layout with drag-and-drop, CPU/PG bars, module catalog.',
|
||||
files: 'Prototype ref: apps/docs/src/prototypes/existing-demos/FittingDemo.tsx, game-slice/ui/SliceFittingService.tsx',
|
||||
},
|
||||
{
|
||||
id: 'P4-F2',
|
||||
title: 'Ship purchase screen',
|
||||
phase: '4',
|
||||
layer: 'frontend',
|
||||
status: 'missing',
|
||||
desc: 'No ship shop, no hangar view, no ship comparison UI.',
|
||||
},
|
||||
|
||||
// ── PHASE 5: FACTION QUESTS & DYNAMIC WORLD ──
|
||||
{
|
||||
id: 'P5-B1',
|
||||
title: 'Faction & standing system',
|
||||
phase: '5',
|
||||
layer: 'backend',
|
||||
status: 'missing',
|
||||
desc: 'No factions table, no player standing, no loyalty points. Design describes -10 to +10 standing with faction consequences.',
|
||||
},
|
||||
{
|
||||
id: 'P5-B2',
|
||||
title: 'NPC agents & mission templates',
|
||||
phase: '5',
|
||||
layer: 'backend',
|
||||
status: 'missing',
|
||||
desc: 'No npc_agents, mission_templates, active_missions tables. Design describes 6 mission types (kill, courier, mining, survey, escort, trade) with 4 reward tiers.',
|
||||
},
|
||||
{
|
||||
id: 'P5-B3',
|
||||
title: 'Procedural galaxy generation',
|
||||
phase: '5',
|
||||
layer: 'backend',
|
||||
status: 'missing',
|
||||
desc: 'Single hardcoded system (Solace). Design describes seeded RNG galaxy with MST stargate topology, regions, constellations.',
|
||||
files: 'Prototype ref: apps/docs/src/prototypes/existing-demos/GalaxyDemo.tsx',
|
||||
},
|
||||
{
|
||||
id: 'P5-B4',
|
||||
title: 'Station prosperity (dynamic world impact)',
|
||||
phase: '5',
|
||||
layer: 'backend',
|
||||
status: 'missing',
|
||||
desc: 'No station prosperity, no resource demand model. Design describes stations growing when supplied, faction leaders taking provinces.',
|
||||
},
|
||||
{
|
||||
id: 'P5-B5',
|
||||
title: 'World events (anomalies, faction conflicts)',
|
||||
phase: '5',
|
||||
layer: 'backend',
|
||||
status: 'missing',
|
||||
desc: 'No event spawning, no participation tracking, no galaxy story log. Design describes 6 event categories with 3 notification tiers.',
|
||||
},
|
||||
{
|
||||
id: 'P5-F1',
|
||||
title: 'Agent/mission panel',
|
||||
phase: '5',
|
||||
layer: 'frontend',
|
||||
status: 'missing',
|
||||
desc: 'No NPC agent list, no available missions, no mission tracker, no standing display.',
|
||||
},
|
||||
{
|
||||
id: 'P5-F2',
|
||||
title: 'Galaxy map (multi-system)',
|
||||
phase: '5',
|
||||
layer: 'frontend',
|
||||
status: 'missing',
|
||||
desc: 'Only single-system SVG map exists. No multi-system navigation, no stargate routes, no faction overlay.',
|
||||
files: 'Prototype ref: apps/docs/src/prototypes/existing-demos/StarMapDemo.tsx',
|
||||
},
|
||||
|
||||
// ── PHASE 6: INDUSTRY & ECONOMY DEPTH ──
|
||||
{
|
||||
id: 'P6-B1',
|
||||
title: 'Refining (ore → minerals)',
|
||||
phase: '6',
|
||||
layer: 'backend',
|
||||
status: 'missing',
|
||||
desc: 'No refineOre reducer, no mineral item types. Design describes 8 ore types refining to 8 minerals with skill-based yield (50-95%).',
|
||||
files: 'Prototype ref: apps/docs/src/prototypes/game-slice/sliceEconomy.ts',
|
||||
},
|
||||
{
|
||||
id: 'P6-B2',
|
||||
title: 'Manufacturing (minerals → modules/ships)',
|
||||
phase: '6',
|
||||
layer: 'backend',
|
||||
status: 'missing',
|
||||
desc: 'No blueprints, no manufacturing_jobs, no production chain. Design describes 5-tier chain: Ore → Mineral → Component → Module → Ship.',
|
||||
},
|
||||
{
|
||||
id: 'P6-B3',
|
||||
title: 'Multiple ore types',
|
||||
phase: '6',
|
||||
layer: 'backend',
|
||||
status: 'missing',
|
||||
desc: 'Only Veldspar. Design describes 8 ore types (Veldspar, Scordite, Pyroxeres, Kernite, Omber, Jaspet, Hemorphite, Arkonor).',
|
||||
},
|
||||
{
|
||||
id: 'P6-F1',
|
||||
title: 'Refining UI',
|
||||
phase: '6',
|
||||
layer: 'frontend',
|
||||
status: 'missing',
|
||||
desc: 'No refining interface. Design describes batch processing with yield preview.',
|
||||
files: 'Prototype ref: apps/docs/src/prototypes/existing-demos/RefiningDemo.tsx, game-slice/ui/SliceRefiningService.tsx',
|
||||
},
|
||||
{
|
||||
id: 'P6-F2',
|
||||
title: 'Manufacturing UI',
|
||||
phase: '6',
|
||||
layer: 'frontend',
|
||||
status: 'missing',
|
||||
desc: 'No manufacturing tab. Design describes blueprint selection, job queue, material requirements.',
|
||||
},
|
||||
{
|
||||
id: 'P6-F3',
|
||||
title: 'Market with order book & price history',
|
||||
phase: '6',
|
||||
layer: 'frontend',
|
||||
status: 'missing',
|
||||
desc: 'No order book, no charts, no bid/ask spread. Only flat NPC buy for ore.',
|
||||
files: 'Prototype ref: apps/docs/src/prototypes/existing-demos/MarketDemo.tsx',
|
||||
},
|
||||
|
||||
// ── PHASE 7: POLISH & PROCEDURAL GALAXY ──
|
||||
{
|
||||
id: 'P7-B1',
|
||||
title: 'XP & skill progression',
|
||||
phase: '7',
|
||||
layer: 'backend',
|
||||
status: 'missing',
|
||||
desc: 'No skills_catalog, no XP awards. Design describes 5 skills (Mining, Industry, Trade, Gunnery, Navigation) with level 0-5.',
|
||||
files: 'Prototype ref: apps/docs/src/prototypes/existing-demos/ProgressionDemo.tsx',
|
||||
},
|
||||
{
|
||||
id: 'P7-B2',
|
||||
title: 'Tutorial objective chain',
|
||||
phase: '7',
|
||||
layer: 'backend',
|
||||
status: 'missing',
|
||||
desc: 'No objective tracking. Prototype has 7-objective tutorial chain.',
|
||||
files: 'Prototype ref: apps/docs/src/prototypes/game-slice/sliceObjectives.ts',
|
||||
},
|
||||
{
|
||||
id: 'P7-B3',
|
||||
title: 'Zora ship AI (Tier 0)',
|
||||
phase: '7',
|
||||
layer: 'backend',
|
||||
status: 'missing',
|
||||
desc: 'No Zora state, no soul depth, no personality axes, no module gating.',
|
||||
files: 'Prototype ref: apps/docs/src/prototypes/existing-demos/ZoraDemo.tsx',
|
||||
},
|
||||
{
|
||||
id: 'P7-B4',
|
||||
title: 'CONCORD / law enforcement',
|
||||
phase: '7',
|
||||
layer: 'backend',
|
||||
status: 'missing',
|
||||
desc: 'No security status, no CONCORD response, no criminal flagging.',
|
||||
},
|
||||
{
|
||||
id: 'P7-B5',
|
||||
title: 'Insurance system',
|
||||
phase: '7',
|
||||
layer: 'backend',
|
||||
status: 'missing',
|
||||
desc: 'No insurance policies, no coverage tiers, no payout on death.',
|
||||
},
|
||||
{
|
||||
id: 'P7-F1',
|
||||
title: 'Tutorial / onboarding flow',
|
||||
phase: '7',
|
||||
layer: 'frontend',
|
||||
status: 'missing',
|
||||
desc: 'No guided mission sequence, no skip option, no Zora hints.',
|
||||
},
|
||||
{
|
||||
id: 'P7-F2',
|
||||
title: 'Full Flight Mode HUD (diegetic)',
|
||||
phase: '7',
|
||||
layer: 'frontend',
|
||||
status: 'missing',
|
||||
desc: 'No diegetic HUD overlays on 3D viewport. Design describes curved shield/armor bars, module rack, overview panel, targeting reticle, capacitor gauge.',
|
||||
files: 'Prototype ref: apps/docs/src/prototypes/existing-demos/GameHudDemo.tsx',
|
||||
},
|
||||
{
|
||||
id: 'P7-F3',
|
||||
title: 'Station Mode panel UI',
|
||||
phase: '7',
|
||||
layer: 'frontend',
|
||||
status: 'missing',
|
||||
desc: 'No station service menu. No docked-mode panel swap. GameShell shows same panels regardless of dock/flight state.',
|
||||
},
|
||||
{
|
||||
id: 'P7-F4',
|
||||
title: 'Event feed with categories',
|
||||
phase: '7',
|
||||
layer: 'frontend',
|
||||
status: 'partial',
|
||||
desc: 'Basic event log exists (12 items, no pagination).',
|
||||
detail: 'Missing: no color coding by event type, no filtering, no combat vs market vs system categorization, no click-to-zoom.',
|
||||
files: 'apps/game/src/ui/EventFeed.tsx',
|
||||
},
|
||||
{
|
||||
id: 'P7-F5',
|
||||
title: 'Fog of war / map reveal',
|
||||
phase: '7',
|
||||
layer: 'frontend',
|
||||
status: 'missing',
|
||||
desc: 'No fog of war mechanic. All POIs visible immediately in current system.',
|
||||
},
|
||||
|
||||
// ── CROSS-CUTTING / INFRASTRUCTURE ──
|
||||
{
|
||||
id: 'X-B1',
|
||||
title: 'Scheduled agents (timed server logic)',
|
||||
phase: '0',
|
||||
layer: 'backend',
|
||||
status: 'missing',
|
||||
desc: 'All game logic is reducer-call driven. No timed agents for: NPC spawning, combat ticks, economy ticks, world events, balancing.',
|
||||
},
|
||||
{
|
||||
id: 'X-F1',
|
||||
title: 'Hardcoded system/station references',
|
||||
phase: '1',
|
||||
layer: 'frontend',
|
||||
status: 'partial',
|
||||
desc: 'Client subscribes to hardcoded "solace" system and "solace-prime" station. useGameSession hardcodes these lookups.',
|
||||
detail: 'client.ts:77-78, useGameSession.ts:129-130. Must be replaced with dynamic system lookup once multi-system exists.',
|
||||
files: 'apps/game/src/spacetime/client.ts:77-78',
|
||||
},
|
||||
{
|
||||
id: 'X-F2',
|
||||
title: 'Operation auto-completion (client polling)',
|
||||
phase: '1',
|
||||
layer: 'frontend',
|
||||
status: 'partial',
|
||||
desc: 'GameSpaceScene polls Date.now() at 120ms intervals to detect operation completion and fire completeApproach/completeMiningCycle.',
|
||||
detail: 'Works but is client-driven. Design recommends server-authoritative completion via scheduled reducers.',
|
||||
files: 'apps/game/src/scene/GameSpaceScene.tsx',
|
||||
},
|
||||
{
|
||||
id: 'X-F3',
|
||||
title: 'Ambient traffic / other entities',
|
||||
phase: '2',
|
||||
layer: 'frontend',
|
||||
status: 'missing',
|
||||
desc: 'No other ships visible in space. Prototype has 4 ambient entities (3 friendly + 1 hostile) with orbital movement.',
|
||||
files: 'Prototype ref: apps/docs/src/prototypes/game-slice/ui/SliceFlightStage.tsx:78-92',
|
||||
},
|
||||
];
|
||||
|
||||
const PHASE_LABELS: Record<Phase, string> = {
|
||||
'0': 'Phase 0 — Local Skeleton',
|
||||
'1': 'Phase 1 — Navigation & Exploration',
|
||||
'2': 'Phase 2 — Mining, Inventory & Trade',
|
||||
'3': 'Phase 3 — Combat (FTL Power Allocation)',
|
||||
'4': 'Phase 4 — Ship Customization & Upgrades',
|
||||
'5': 'Phase 5 — Faction Quests & Dynamic World',
|
||||
'6': 'Phase 6 — Industry & Economy Depth',
|
||||
'7': 'Phase 7 — Polish & Procedural Galaxy',
|
||||
};
|
||||
|
||||
export function TodoPage() {
|
||||
const [filterPhase, setFilterPhase] = useState<string>('all');
|
||||
const [filterLayer, setFilterLayer] = useState<string>('all');
|
||||
const [filterStatus, setFilterStatus] = useState<string>('all');
|
||||
|
||||
const filtered = useMemo(() => {
|
||||
return items.filter(item => {
|
||||
if (filterPhase !== 'all' && item.phase !== filterPhase) return false;
|
||||
if (filterLayer !== 'all' && item.layer !== filterLayer) return false;
|
||||
if (filterStatus !== 'all' && item.status !== filterStatus) return false;
|
||||
return true;
|
||||
});
|
||||
}, [filterPhase, filterLayer, filterStatus]);
|
||||
|
||||
const counts = useMemo(() => {
|
||||
const byStatus = { done: 0, partial: 0, missing: 0, blocked: 0 };
|
||||
const byPhase: Record<string, { done: number; partial: number; missing: number; blocked: number; total: number }> = {};
|
||||
items.forEach(item => {
|
||||
byStatus[item.status]++;
|
||||
if (!byPhase[item.phase]) byPhase[item.phase] = { done: 0, partial: 0, missing: 0, blocked: 0, total: 0 };
|
||||
byPhase[item.phase][item.status]++;
|
||||
byPhase[item.phase].total++;
|
||||
});
|
||||
return { byStatus, byPhase };
|
||||
}, []);
|
||||
|
||||
const grouped = useMemo(() => {
|
||||
const groups: Record<string, TodoItem[]> = {};
|
||||
filtered.forEach(item => {
|
||||
const key = item.phase === '0' && item.id.startsWith('X-') ? 'cross' : item.phase;
|
||||
if (!groups[key]) groups[key] = [];
|
||||
groups[key].push(item);
|
||||
});
|
||||
return groups;
|
||||
}, [filtered]);
|
||||
|
||||
const phaseOrder = ['0', '1', '2', '3', '4', '5', '6', '7', 'cross'];
|
||||
const sortedGroups = phaseOrder.filter(p => grouped[p]).map(p => ({
|
||||
key: p,
|
||||
label: p === 'cross' ? 'Cross-Cutting / Infrastructure' : PHASE_LABELS[p as Phase],
|
||||
items: grouped[p],
|
||||
}));
|
||||
|
||||
return (
|
||||
<div className="mx-auto max-w-content">
|
||||
<h1 style={{ marginBottom: '8px' }}>Implementation Status</h1>
|
||||
<p style={{ color: 'var(--fg-dim)', fontSize: '0.95rem', maxWidth: '720px' }}>
|
||||
Living TODO document tracking what's built vs. what's designed. Auto-generated from codebase review on {LAST_UPDATED}.
|
||||
Each item maps to a specific phase, layer, and file reference.
|
||||
</p>
|
||||
|
||||
<div className="mb-6 grid grid-cols-[repeat(auto-fit,minmax(150px,1fr))] gap-4" style={{ marginTop: 'var(--sp-5)' }}>
|
||||
<div className="rounded-xl border border-border bg-surface p-5 max-md:rounded-lg max-md:p-4">
|
||||
<div className="font-mono text-[1.6rem] font-bold tabular-nums" style={{ color: 'var(--green)' }}>{counts.byStatus.done}</div>
|
||||
<div className="mt-1 text-[0.75rem] uppercase tracking-[0.05em] text-muted">Done</div>
|
||||
</div>
|
||||
<div className="rounded-xl border border-border bg-surface p-5 max-md:rounded-lg max-md:p-4">
|
||||
<div className="font-mono text-[1.6rem] font-bold tabular-nums" style={{ color: 'var(--accent)' }}>{counts.byStatus.partial}</div>
|
||||
<div className="mt-1 text-[0.75rem] uppercase tracking-[0.05em] text-muted">Partial</div>
|
||||
</div>
|
||||
<div className="rounded-xl border border-border bg-surface p-5 max-md:rounded-lg max-md:p-4">
|
||||
<div className="font-mono text-[1.6rem] font-bold tabular-nums" style={{ color: 'var(--red)' }}>{counts.byStatus.missing}</div>
|
||||
<div className="mt-1 text-[0.75rem] uppercase tracking-[0.05em] text-muted">Missing</div>
|
||||
</div>
|
||||
<div className="rounded-xl border border-border bg-surface p-5 max-md:rounded-lg max-md:p-4">
|
||||
<div className="font-mono text-[1.6rem] font-bold tabular-nums" style={{ color: 'var(--muted)' }}>{counts.byStatus.blocked}</div>
|
||||
<div className="mt-1 text-[0.75rem] uppercase tracking-[0.05em] text-muted">Blocked</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mb-6 rounded-lg px-5 py-4 text-[0.85rem] leading-[1.5] border border-cyan/20 bg-cyan/8 text-cyan">
|
||||
<strong>Backend coverage:</strong> {BACKEND_TABLES_IMPLEMENTED} / {BACKEND_TABLES_DESIGNED} tables ({Math.round(BACKEND_TABLES_IMPLEMENTED / BACKEND_TABLES_DESIGNED * 100)}%).
|
||||
{BACKEND_REDUCERS_IMPLEMENTED} / {BACKEND_REDUCERS_DESIGNED} reducers ({Math.round(BACKEND_REDUCERS_IMPLEMENTED / BACKEND_REDUCERS_DESIGNED * 100)}%).
|
||||
All 14 interactive demos and the full game-slice prototype live in <code>apps/docs/src/prototypes/</code> using localStorage — these serve as reference implementations for migration into the SpacetimeDB backend.
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'flex', gap: 'var(--sp-2)', marginBottom: 'var(--sp-6)', flexWrap: 'wrap' }}>
|
||||
<select
|
||||
value={filterPhase}
|
||||
onChange={e => setFilterPhase(e.target.value)}
|
||||
className="rounded-lg border border-border bg-surface-raised px-3 py-1.5 font-mono text-[0.75rem] text-fg"
|
||||
>
|
||||
<option value="all">All Phases</option>
|
||||
{Object.entries(PHASE_LABELS).map(([k, v]) => <option key={k} value={k}>{v}</option>)}
|
||||
<option value="cross">Cross-Cutting</option>
|
||||
</select>
|
||||
<select
|
||||
value={filterLayer}
|
||||
onChange={e => setFilterLayer(e.target.value)}
|
||||
className="rounded-lg border border-border bg-surface-raised px-3 py-1.5 font-mono text-[0.75rem] text-fg"
|
||||
>
|
||||
<option value="all">All Layers</option>
|
||||
{Object.entries(LAYER_LABELS).map(([k, v]) => <option key={k} value={k}>{v}</option>)}
|
||||
</select>
|
||||
<select
|
||||
value={filterStatus}
|
||||
onChange={e => setFilterStatus(e.target.value)}
|
||||
className="rounded-lg border border-border bg-surface-raised px-3 py-1.5 font-mono text-[0.75rem] text-fg"
|
||||
>
|
||||
<option value="all">All Status</option>
|
||||
{Object.entries(STATUS_LABELS).map(([k, v]) => <option key={k} value={k}>{v}</option>)}
|
||||
</select>
|
||||
<span style={{ color: 'var(--muted)', fontSize: '0.75rem', lineHeight: '2' }}>
|
||||
{filtered.length} / {items.length} items
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{sortedGroups.map(group => {
|
||||
const phaseCounts = group.key !== 'cross' ? counts.byPhase[group.key] : null;
|
||||
const donePct = phaseCounts ? Math.round(((phaseCounts.done + phaseCounts.partial * 0.5) / phaseCounts.total) * 100) : null;
|
||||
|
||||
return (
|
||||
<div key={group.key} style={{ marginBottom: 'var(--sp-8)' }}>
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: 'var(--sp-3)',
|
||||
marginBottom: 'var(--sp-4)',
|
||||
paddingBottom: 'var(--sp-2)',
|
||||
borderBottom: '2px solid var(--border)',
|
||||
}}>
|
||||
<h2 style={{ margin: 0, fontSize: '1rem', flex: 1 }}>{group.label}</h2>
|
||||
{phaseCounts && (
|
||||
<div style={{ display: 'flex', gap: 'var(--sp-3)', alignItems: 'center' }}>
|
||||
<span style={{ fontFamily: 'var(--font-mono)', fontSize: '0.7rem', color: 'var(--green)' }}>{phaseCounts.done} done</span>
|
||||
<span style={{ fontFamily: 'var(--font-mono)', fontSize: '0.7rem', color: 'var(--accent)' }}>{phaseCounts.partial} partial</span>
|
||||
<span style={{ fontFamily: 'var(--font-mono)', fontSize: '0.7rem', color: 'var(--red)' }}>{phaseCounts.missing + phaseCounts.blocked} missing</span>
|
||||
<div style={{
|
||||
width: '80px',
|
||||
height: '6px',
|
||||
borderRadius: '3px',
|
||||
background: 'var(--surface-raised)',
|
||||
overflow: 'hidden',
|
||||
}}>
|
||||
<div style={{
|
||||
width: `${donePct}%`,
|
||||
height: '100%',
|
||||
borderRadius: '3px',
|
||||
background: donePct > 70 ? 'var(--green)' : donePct > 30 ? 'var(--accent)' : 'var(--red)',
|
||||
}} />
|
||||
</div>
|
||||
<span style={{ fontFamily: 'var(--font-mono)', fontSize: '0.7rem', color: 'var(--fg-dim)' }}>{donePct}%</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="w-full border-collapse" style={{ overflowX: 'auto' }}>
|
||||
<table className="w-full border-collapse text-[0.85rem] max-md:block max-md:overflow-x-auto max-md:rounded-lg max-md:border max-md:border-border max-md:[&_thead]:table max-md:[&_tbody]:table max-md:[&_thead]:min-w-[680px] max-md:[&_tbody]:min-w-[680px] [&_th]:whitespace-nowrap [&_th]:border-b [&_th]:border-border [&_th]:px-4 [&_th]:py-3 [&_th]:text-left [&_th]:font-mono [&_th]:text-[0.7rem] [&_th]:uppercase [&_th]:tracking-[0.06em] [&_th]:text-muted [&_td]:border-b [&_td]:border-border [&_td]:px-4 [&_td]:py-3 [&_td]:font-mono [&_td]:text-[0.8rem] [&_td]:text-fg [&_tr:hover_td]:bg-surface-raised">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Status</th>
|
||||
<th>Layer</th>
|
||||
<th>Title</th>
|
||||
<th>Details</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{group.items.map(item => (
|
||||
<tr key={item.id}>
|
||||
<td style={{ color: 'var(--muted)', fontSize: '0.7rem' }}>{item.id}</td>
|
||||
<td>
|
||||
<span style={{
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
gap: '4px',
|
||||
padding: '2px 8px',
|
||||
borderRadius: 'var(--radius-pill)',
|
||||
fontSize: '0.65rem',
|
||||
fontWeight: 600,
|
||||
fontFamily: 'var(--font-mono)',
|
||||
background: item.status === 'done' ? 'rgba(34,197,94,0.1)' : item.status === 'partial' ? 'rgba(240,160,48,0.1)' : item.status === 'blocked' ? 'var(--surface-raised)' : 'rgba(239,68,68,0.1)',
|
||||
color: STATUS_COLORS[item.status],
|
||||
border: `1px solid ${STATUS_COLORS[item.status]}33`,
|
||||
}}>
|
||||
{STATUS_LABELS[item.status]}
|
||||
</span>
|
||||
</td>
|
||||
<td style={{ color: 'var(--fg-dim)', fontSize: '0.7rem' }}>{LAYER_LABELS[item.layer]}</td>
|
||||
<td style={{ fontWeight: 500, fontFamily: 'var(--font-body)', color: 'var(--fg)' }}>{item.title}</td>
|
||||
<td>
|
||||
<div style={{ color: 'var(--fg-dim)', fontSize: '0.8rem', fontFamily: 'var(--font-body)' }}>{item.desc}</div>
|
||||
{item.detail && (
|
||||
<div style={{ color: 'var(--accent)', fontSize: '0.75rem', marginTop: '4px', padding: '4px 8px', background: 'rgba(240,160,48,0.06)', borderRadius: '4px', borderLeft: '2px solid var(--accent)' }}>
|
||||
{item.detail}
|
||||
</div>
|
||||
)}
|
||||
{item.files && (
|
||||
<div style={{ color: 'var(--muted)', fontSize: '0.65rem', marginTop: '4px', fontFamily: 'var(--font-mono)' }}>
|
||||
{item.files}
|
||||
</div>
|
||||
)}
|
||||
{item.blockedBy && (
|
||||
<div style={{ color: 'var(--muted)', fontSize: '0.65rem', marginTop: '4px' }}>
|
||||
Blocked by: {item.blockedBy.join(', ')}
|
||||
</div>
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
21
apps/docs/src/prototypes/AGENTS.md
Normal file
21
apps/docs/src/prototypes/AGENTS.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# apps/docs/src/prototypes/ — Interactive Prototypes
|
||||
|
||||
Browser-based prototypes that validate game subsystems before backend migration. All run in-browser with localStorage — no SpacetimeDB connection.
|
||||
|
||||
## Structure
|
||||
|
||||
| Directory | Description |
|
||||
|-----------|-------------|
|
||||
| `game-slice/` | Full MVP loop prototype (undock → navigate → mine → dock → refine → fit → sell → combat) |
|
||||
| `existing-demos/` | 14 standalone demos, each validating one game subsystem |
|
||||
| `r3f/` | Reusable React Three Fiber 3D scenes shared across demos |
|
||||
| `standalone-huds/` | HUD prototype frames and wrappers |
|
||||
|
||||
## Relationship to Production Code
|
||||
|
||||
Prototypes are **reference implementations**. When a system is ready for production, the prototype logic migrates:
|
||||
1. State management (localStorage) → SpacetimeDB tables
|
||||
2. Event sourcing → SpacetimeDB reducers
|
||||
3. UI components → `apps/game/src/ui/` components
|
||||
|
||||
The game-slice prototype has the richest implementation of combat, fitting, refining, skills, objectives, and Zora — all of which need backend tables before they can migrate.
|
||||
22
apps/docs/src/prototypes/existing-demos/AGENTS.md
Normal file
22
apps/docs/src/prototypes/existing-demos/AGENTS.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# apps/docs/src/prototypes/existing-demos/ — Standalone Game Demos
|
||||
|
||||
14 interactive demo components, each validating one game subsystem. Linked from the docs Demo Gallery page.
|
||||
|
||||
| Demo | File | Validates |
|
||||
|------|------|-----------|
|
||||
| MVP Loop Slice | `GameLoopSliceDemo.tsx` | Full playable game loop via game-slice prototype |
|
||||
| Star Map | `StarMapDemo.tsx` | Era 2 galaxy map with multi-system view, warp routes |
|
||||
| Ship Movement | `ShipMovementDemo.tsx` | Sub-warp movement model |
|
||||
| Warp Travel | `WarpTravelDemo.tsx` | Warp sequence (align → accelerate → cruise → exit) |
|
||||
| Combat | `CombatDemo.tsx` | 3D combat with power allocation, projectiles, subsystem damage |
|
||||
| Market | `MarketDemo.tsx` | Full order book with bid/ask spread, price history, ~20 commodities |
|
||||
| Ship Fitting | `FittingDemo.tsx` | Module fitting with CPU/PG constraints, slot types |
|
||||
| Refining | `RefiningDemo.tsx` | Ore-to-mineral refining + manufacturing recipes |
|
||||
| Skill Progression | `ProgressionDemo.tsx` | XP curve, skill levels, training queue |
|
||||
| Bounty | `BountyDemo.tsx` | Bounty tiers, kill feed, player-placed bounties |
|
||||
| Game HUD | `GameHudDemo.tsx` | Flight mode diegetic overlays on 3D scene |
|
||||
| Chat | `ChatDemo.tsx` | 4 channels with light-speed delay simulation |
|
||||
| Zora Tier 0 | `ZoraDemo.tsx` | Deterministic template engine with soul depth progression |
|
||||
| Galaxy Generator | `GalaxyDemo.tsx` | Seeded RNG galaxy generation with MST stargate topology |
|
||||
|
||||
All demos use the shared R3F scenes in `../r3f/`.
|
||||
42
apps/docs/src/prototypes/game-slice/AGENTS.md
Normal file
42
apps/docs/src/prototypes/game-slice/AGENTS.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# apps/docs/src/prototypes/game-slice/ — MVP Loop Prototype
|
||||
|
||||
A self-contained, playable implementation of the full MVP game loop using localStorage for persistence. This is the **most complete gameplay implementation** in the repo — every other game system prototype feeds into or from this slice.
|
||||
|
||||
## Core Files
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `types.ts` | Full type system: 8 flight modes, 19 event types, combat modules, skills, objectives, Zora state |
|
||||
| `gameSliceState.ts` | Event sourcing engine: `applySliceEvent()` handles 19 event types, localStorage persistence, XP awards |
|
||||
| `sliceController.ts` | Action gating: `getContextualSliceActions()` returns enabled/disabled actions with reasons |
|
||||
| `sliceObjectives.ts` | 7-objective tutorial chain: undock → navigate → mine → dock → refine → fit → sell (+ optional combat) |
|
||||
| `sliceWorld.ts` | World constants: 2 POIs (station + belt), travel durations, ship stats |
|
||||
| `sliceEconomy.ts` | Cargo management (upsert/remove/clamp), refining (Veldspar → Tritanium + Pyerite), selling |
|
||||
| `sliceNavigationBridge.ts` | Bridge between game-slice state and warp travel sessions |
|
||||
| `useGameSliceSession.ts` | React hook: reads/writes localStorage, exposes session + event dispatcher |
|
||||
| `useSliceController.ts` | React hook: derives contextual actions and computed facts from session |
|
||||
| `SeamlessGameLoopSlice.tsx` | Root component: composes all stages with mode-based rendering |
|
||||
|
||||
## UI Components (`ui/`)
|
||||
|
||||
22 components covering every game state:
|
||||
- Station: `SliceStationStage`, `SliceStationPanel`
|
||||
- Flight: `SliceFlightStage` (with ambient traffic entities, context menus)
|
||||
- Travel: `SliceTravelStage`
|
||||
- Mining: `SliceMiningStage`
|
||||
- Combat: `SliceCombatStage`
|
||||
- Services: `SliceServicesStage`, `SliceRefiningService`, `SliceFittingService`, `SliceMarketService`
|
||||
- Shell: `SliceShell`, `SliceTopBar`, `SliceActionRail`, `SliceObjectiveTracker`
|
||||
- Shared: `SliceModuleRack`, `SliceShipStatus`, `SliceCargoPanel`, `SliceEventLog`, `SliceProgressBar`, `SliceStage`, `SliceDemoLinks`, `sliceStyles`
|
||||
|
||||
## Systems Implemented (not yet in production)
|
||||
|
||||
| System | Status | Production Target |
|
||||
|--------|--------|-------------------|
|
||||
| Refining (ore → minerals) | Working | Phase 6 |
|
||||
| Fitting (module slots + CPU/PG) | Working | Phase 4 |
|
||||
| Combat (FTL power allocation) | Working | Phase 3 |
|
||||
| XP/Skills (5 skills, level 0-5) | Working | Phase 7 |
|
||||
| Objective chain (tutorial) | Working | Phase 7 |
|
||||
| Zora modules (personality + soul depth) | Partial | Phase 7 |
|
||||
| Multi-system travel (5 systems) | Working | Phase 5 |
|
||||
14
apps/docs/src/prototypes/r3f/AGENTS.md
Normal file
14
apps/docs/src/prototypes/r3f/AGENTS.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# apps/docs/src/prototypes/r3f/ — Reusable 3D Scenes
|
||||
|
||||
Shared React Three Fiber scenes used by the demos in `../existing-demos/` and the game-slice prototype.
|
||||
|
||||
| Directory | Contains |
|
||||
|-----------|----------|
|
||||
| `combat/` | Combat scene, combat state machine, combat math (damage, range, tracking) |
|
||||
| `galaxy/` | Galaxy generation and visualization |
|
||||
| `hud/` | Diegetic HUD elements for flight mode |
|
||||
| `movement/` | Ship movement and interpolation |
|
||||
| `navigation/` | Travel session management, route planning |
|
||||
| `shared/` | Common utilities, camera controls, lighting |
|
||||
| `starmap/` | Star map 3D visualization |
|
||||
| `warp/` | Warp tunnel and warp sequence effects |
|
||||
Reference in New Issue
Block a user