# Vertical Slice Evaluation

**Date:** 2026-05-31  
**Scope:** Compare the current playable game implementation against the MVP Loop Slice demo and the core single-player roadmap goals.

---

## Executive Assessment

The project has a strong vertical-slice prototype in the docs app, but the standalone game app is still a Phase 0 technical shell. The MVP Loop Slice demonstrates the intended solo loop and connects many previously standalone demos through a shared browser session. The actual game app connects to SpacetimeDB, creates/subscribes to starter rows, and exposes connection/reducer status, but it does not yet implement the playable slice loop.

In practical terms:

- **Design/demo confidence is high.** The docs app proves the target loop and system UX at prototype fidelity.
- **Runtime implementation readiness is early.** The game app has connection plumbing and starter persistence only.
- **The main gap is migration from prototype state to authoritative game state.** The loop exists in localStorage and React state, not in SpacetimeDB tables/reducers.
- **Phase 0 is partially complete.** SpacetimeDB connectivity, starter player/ship/system/station rows, and reducer invocation exist. The rendered star system, tick loop, 3D scene, and gameplay commands are not yet present in the game app.

---

## Baselines Compared

### Intended Core Game Vertical Slice

The roadmap defines the core game as a single-player adventure using local SpacetimeDB from day one. The minimum full loop is:

1. Boot the game and connect to local SpacetimeDB.
2. Render a single star system with station and asteroids.
3. Undock.
4. Navigate to an asteroid belt.
5. Mine ore into cargo.
6. Return and dock.
7. Refine ore.
8. Fit or confirm a module.
9. Sell goods on a market.
10. Optionally run a combat trial.
11. Persist state through SpacetimeDB, not localStorage.

### Docs-App MVP Loop Slice

The docs app already implements a connected prototype of that loop:

- Session/objective flow: `apps/docs/src/prototypes/game-slice/sliceObjectives.ts`
- Local session state and event reducer: `apps/docs/src/prototypes/game-slice/gameSliceState.ts`
- Action gating and contextual commands: `apps/docs/src/prototypes/game-slice/sliceController.ts`
- Runtime controller: `apps/docs/src/prototypes/game-slice/useSliceController.ts`
- Loop shell/UI composition: `apps/docs/src/prototypes/game-slice/SeamlessGameLoopSlice.tsx`

It validates the user-facing flow, command availability, objective tracking, event log, cargo, station services, fitting handoff, market selling, XP awards, Zora observation events, and optional combat branch.

Its explicit limitation is architectural: it uses local browser persistence and fake/deterministic data. It does not validate backend authority, persistence model, multiplayer path, generated bindings, or SpacetimeDB reducer design.

### Standalone Game App

The standalone game app currently validates the connection path:

- SpacetimeDB connection lifecycle: `apps/game/src/spacetime/useSpacetimeConnection.ts`
- Subscription/read facade: `apps/game/src/spacetime/usePlayerSession.ts`
- Flight console shell: `apps/game/src/GameShell.tsx`
- Starter backend module: `services/spacetimedb/src/index.ts`

The backend currently provides:

- `player`
- `ship`
- `system`
- `station`
- `server_event`
- `connectPlayer`
- `renamePlayer`
- `seedWorld`
- `ping`

This is useful and necessary, but it is not yet the playable vertical slice.

---

## Alignment Matrix

| Slice expectation | Demo status | Game app status | Gap |
|---|---:|---:|---|
| App boots | Yes | Yes | Mostly aligned. |
| Local SpacetimeDB connection | No | Partial | Game connects, but the slice does not use it. |
| Starter player identity | No | Yes | Present in game shell only. |
| Starter ship row | No | Yes | Present, but no position/mode/cargo/fitting state. |
| Single star system | Yes, fake/system data | Partial | Backend has one system and station; no asteroid rows or scene rendering. |
| Station and asteroids visible | Yes | No | Game shell displays data cards only. |
| 60fps render / 1Hz sim tick | Prototype timers only | No | No authoritative sim tick or render scene in game app. |
| Undock/dock | Yes | No | Needs reducers, row state, and UI commands. |
| Local movement / approach target | Yes | No | Needs target/position model and movement reducer/tick. |
| Warp/travel handoff | Yes in demos | No | Needs backend travel operation model. |
| Mining cycle | Yes | No | Needs asteroid/cargo/mining operation tables and reducers. |
| Cargo and inventory | Yes | No | Needs authoritative inventory schema. |
| Refining | Yes | No | Needs station service reducer and inventory transaction. |
| Fitting | Yes | No | Needs module catalog, ship fitting rows, CPU/PG validation. |
| Market selling | Yes | No | Needs market/order/transaction state, even if NPC-only first. |
| Combat trial | Yes | No | Needs NPC entity/combat reducer loop. |
| Objective tracker | Yes | No | Needs game app UI or server-backed tutorial/objective state. |
| Event log | Yes | Partial | Game has server events, but not gameplay events. |
| Skills/XP | Yes | No | Needs skill rows and XP reducer. |
| Zora Tier 0 hooks | Yes | No | Needs backend state and game UI hooks. |
| Persistence | localStorage | Partial SpacetimeDB | Game persists starter rows only; slice state still localStorage. |

---

## What Lines Up Well

### 1. The vertical slice is coherent

The MVP Loop Slice is not just a gallery of isolated screens. It has a real objective chain:

`undock -> navigate_to_belt -> mine_ore -> dock_at_station -> refine_ore -> fit_module -> sell_goods -> combat_trial`

That is the correct shape for Gate 4 and gives implementation a clear target.

### 2. Command gating is already well modeled

The slice controller has concrete command availability rules: dock only at stations, mine only at belts, services only while docked, market only with sellable cargo, refining only with enough ore, and busy-state blocking while operations run. These are exactly the rules that should become server-side validation in reducers.

### 3. The game app has the right backend direction

The game app already uses SpacetimeDB bindings, reducer calls, subscriptions, identity, and server event rows. This lines up with the roadmap decision to avoid localStorage as the final persistence layer.

### 4. The demo gallery honestly documents limitations

The docs already distinguish UX validation from production implementation. That makes the remaining work clearer: the problem is not unknown design, it is backend-backed integration.

---

## Key Gaps

### 1. The demo and the game app use different state models

The MVP Loop Slice stores a rich `GameSliceSession` in localStorage. The game app stores only starter identity, ship, system, station, and event rows in SpacetimeDB.

This creates the largest implementation gap. Nearly every field in the slice session needs either a backend table, a derived client view, or an explicit decision that it remains client-only.

Important missing authoritative state includes:

- current ship mode: station, flight, travel, mining, docking, combat
- ship position and current point of interest
- docked station state
- active operation with start time and duration
- selected target
- cargo and cargo capacity
- fitted modules
- wallet
- skills and XP
- objectives/tutorial progress
- Zora module/state hooks

### 2. Phase 0 rendering is not implemented in the game app

The roadmap says Phase 0 is done when the app shows a star system with a station and three asteroids, updates local state on a tick, and persists through SpacetimeDB. The current game app is a useful diagnostic console, but it does not render the playable space scene or asteroid targets.

### 3. Backend schema is intentionally minimal

The backend module currently supports connection and starter world creation. It does not yet contain the tables required for the slice loop:

- points of interest or asteroid belts
- inventory/cargo
- wallet transactions
- mining operations
- refining jobs
- module catalog
- ship fittings
- market orders or NPC buy prices
- skills
- objectives/tutorial state
- NPCs/combat state

### 4. Reducers do not yet represent gameplay commands

The current reducers are connection/admin-level:

- `connectPlayer`
- `renamePlayer`
- `seedWorld`
- `ping`

The slice needs command reducers such as:

- `undock`
- `dock`
- `selectTarget`
- `startApproach`
- `completeMovement` or server tick movement resolution
- `startMining`
- `stopMining`
- `completeMiningCycle`
- `refineOre`
- `fitModule`
- `unfitModule`
- `sellItemToNpcMarket`
- `startCombatTrial`
- `resolveCombatTick`

### 5. The demo validates flow, not balance or backend correctness

The slice has deterministic prices, deterministic refining, simplified XP, and simplified combat. It proves the player journey, but not the production economy, exploit resistance, transaction safety, concurrent updates, or server authority.

### 6. Naming and world setup are not fully unified

The game shell seeds `solace` / `solace-prime` / "Solace Prime Orbital". The slice defaults to `sol` / `sol-station-0` / "Jita IV - Moon 4". This is acceptable for prototypes, but it will create migration friction if not unified before gameplay reducers are added.

### 7. Existing standalone demos are only partially integrated

The docs note that several demos can consume the slice session, but core effects still remain demo-local. For example, fitting can update slice modules and combat can emit victory, but the final game still needs one authoritative source of truth where fitting affects mining/combat stats and combat affects wallet/cargo/ship state.

---

## Phase Readiness

### Phase 0 - Local Skeleton

**Status:** Partially implemented.

Done:

- pnpm workspace exists.
- standalone game app exists.
- SpacetimeDB module exists.
- generated/placeholder bindings are committed.
- client attempts connection and handles unavailable backend clearly.
- starter player, ship, system, station, and events exist.

Remaining:

- render a star system in the game app.
- add station plus three asteroid targets to backend state.
- add local simulation tick concept.
- persist position/mode/state through SpacetimeDB.
- replace diagnostic-only console with first playable flight shell.

### Phase 1 - Movement & Commands

**Status:** Prototyped, not implemented in game app.

The movement demo and slice validate UX, target selection, approach, ETA/progress, and arrival. The game app needs backend-backed target state, command reducers, and client interpolation.

### Phase 2 - Mining & Inventory

**Status:** Prototyped, not implemented in game app.

The slice validates mining cycles and cargo filling. The game app needs inventory rows, asteroid/belt rows, mining operation state, cargo capacity, and transaction-safe ore insertion.

### Phase 3 - Combat

**Status:** Prototyped, not implemented in game app.

The demo validates power allocation and combat feel. The game app needs NPC entities, combat session state, damage resolution, ship health, loot, bounty payout, and failure/death handling.

### Phase 4 - Fitting

**Status:** Prototyped, not implemented in game app.

The fitting demo validates module constraints and UI feel. The game app needs module catalog rows, fitted module rows, CPU/PG validation in reducers, and stat derivation that affects mining/combat.

### Phase 5 - Refining & Manufacturing

**Status:** Refining prototyped; manufacturing not in slice runtime.

The slice supports ore-to-mineral refining. Manufacturing remains a later implementation gap for the full economy loop.

### Phase 6 - NPC Economy Sim

**Status:** Market surface prototyped; backend economy not implemented.

The market demo validates presentation and selling flow. The game app needs NPC price state, transaction reducers, market history, and later regional differences/diffusion.

### Phase 7 - Single-Player Polish

**Status:** Design-ready, implementation not started in game app.

Tutorial/objectives, events, Zora Tier 0, accessibility, persistence, and polish are documented/prototyped in parts, but not integrated into the standalone game.

---

## Recommended Implementation Path

### Step 1 - Promote the slice state into a backend contract

Create a mapping document or code comments that classify each `GameSliceSession` field as:

- persisted backend state
- derived client state
- temporary UI state
- prototype-only state to delete

This prevents blindly copying localStorage structure into SpacetimeDB while still preserving the proven flow.

### Step 2 - Finish Phase 0 in the game app

Add the smallest playable world:

- one system
- one station
- three asteroid/belt POIs
- one starter ship with position, mode, and docked state
- a 3D or 2.5D in-space view
- a simple read-only HUD showing authoritative rows
- a 1Hz server/sim update path or explicit reducer-driven operation completion

Acceptance check: open the game app, connect to local SpacetimeDB, and see the starter system represented visually rather than only as data cards.

### Step 3 - Port the command rail one command at a time

Use the slice action gating as the implementation source for server validation. Add reducers in this order:

1. `undock`
2. `selectTarget`
3. `startApproach`
4. `dock`
5. `startMining`
6. `stopMining`
7. `refineOre`
8. `fitModule`
9. `sellItemToNpcMarket`
10. `startCombatTrial`

Each reducer should produce a `server_event` row so the current game shell remains useful while the UI evolves.

### Step 4 - Add the minimum schema for Gate 1

For the first integrated gate, implement only what is needed for:

`navigate to asteroid -> mine -> fill cargo -> dock -> sell ore`

Minimum tables/fields:

- ship location/mode/position/docked state
- points of interest
- cargo/inventory
- wallet
- active operation
- market NPC buy price or station commodity price
- event log

Avoid implementing manufacturing, full market depth, skills, Zora, or combat until Gate 1 works end to end.

### Step 5 - Replace localStorage handoff with SpacetimeDB-backed session state

The docs slice can continue to exist as a UX reference, but the standalone game should become the source of truth for vertical-slice progress. Once equivalent reducers exist, either:

- point the docs slice at the same backend for live validation, or
- freeze it as an archived prototype and move active work into `apps/game`.

### Step 6 - Add focused verification

Add tests at the reducer/logic level before broad UI tests:

- connecting creates one player and one starter ship
- repeated connect is idempotent
- undock changes docked state and mode
- movement cannot start while docked
- docking only works at a station POI
- mining only works at a belt and respects cargo capacity
- refining consumes ore and creates minerals
- selling removes inventory and increases wallet
- invalid fitting is rejected

---

## Open Decisions

1. **Which app is the product surface?**  
   Recommendation: `apps/game` should become the product surface; `apps/docs` remains design/prototype reference.

2. **How much of the slice UI should be ported?**  
   Recommendation: port the interaction model and command gating, not the localStorage architecture.

3. **Should Phase 0 include Three.js immediately?**  
   Recommendation: yes, if the target is a space game with Flight Mode as a first-class surface. The docs already have reusable R3F scene pieces that can guide the implementation.

4. **What is the canonical starter world?**  
   Recommendation: choose one naming/id set before adding gameplay reducers. Prefer production-neutral IDs over inherited EVE names.

5. **Server tick vs. reducer-scheduled completion?**  
   Recommendation: for early phases, reducer-driven operations with authoritative timestamps are enough. Add a scheduler/tick once NPCs, economy, and combat need autonomous progression.

---

## Priority Work List

### Immediate

1. Decide canonical starter system/station/POI IDs.
2. Add backend POI/asteroid state.
3. Add ship mode, position, docked state, wallet, and cargo state.
4. Build the game app's first visual system scene.
5. Add `undock`, `dock`, and `startApproach` reducers.

### Next

1. Add mining operation and cargo reducers.
2. Add station sell/refine reducers.
3. Port the command rail/objective tracker into `apps/game`.
4. Add reducer tests for Gate 1.
5. Run a manual Gate 1 playtest.

### Later

1. Fitting with CPU/PG validation.
2. Combat trial with NPC state and loot.
3. Skills/XP progression.
4. Zora Tier 0 backend state.
5. Manufacturing and deeper NPC economy.

---

## Bottom Line

The game lines up well with the vertical slice at the design and prototype level, but not yet at the playable implementation level. The docs app has already answered "what should the first loop feel like?" The standalone game app is now ready to answer "can that loop run against authoritative SpacetimeDB state?"

The next milestone should be a narrow Gate 1 implementation in `apps/game`: connect, undock, approach asteroid, mine ore, dock, and sell. That is the shortest path from demo confidence to a real playable vertical slice.
