← all games

action-roguelite-gpt-5-unknown-2 — GAME.md

# Vector Wake game manifest

## Directory strategy

The project uses feature-first organization:

```text
src/
├── scenes/
├── features/
│   ├── combat/
│   ├── floor/
│   ├── progression/
│   ├── run/
│   └── ui/
├── content/
├── dev/
└── shared/
```

`scenes/` owns lifecycle composition. Each feature folder owns its model, behavior, and presentation. `shared/` contains only input-device tracking, geometry helpers, and color constants used by at least two features.

## Scene graph

| Scene | Responsibility | Edges |
|---|---|---|
| `TitleScene` | Preload the shared manifest, show premise, controls, seed, persistent achievements, and start focus. | `Start` → `RunScene` with the displayed seed. |
| `RunScene` | Own one run, the floor graph, persistent player entity, room lifecycle, combat, rewards, overlays, HUD, audio state, and Inspector extension. | Player death or boss defeat → `ResultScene`. |
| `ResultScene` | Show failed or successful summary, bank the small persistent result, and offer retry or new seed. | `Retry seed` → `RunScene`; `New signal` → `RunScene`; `Title` → `TitleScene`. |

`RunHud` owns one reusable modal panel for pause, choice, shop, and build states. `RunScene` reads one `overlay` union to gate gameplay input and route menu actions. Enemy, player, and projectile components only read the narrow `overlaysGameplay` flag.

## Entities and components

| Entity | Component | One responsibility |
|---|---|---|
| `run-state` | `RunFlow` | Advance rooms, manage overlay focus, rewards, transition guards, win/loss, and room-owned entity lists. |
| `run-state` | `RunStateProbe` | Serialize deterministic run facts for Inspector checks. |
| `player` | `PlayerController` | Convert movement, aim, and held primary input into player state and ability intents. |
| `player` | `Interactor` | Focus the nearest eligible special-room terminal and dispatch the shared interact action. |
| `player` | `Abilities` | Admit cannon, dash, and pulse activations and own cooldowns. |
| `player` | `AbilityDriverComponent` | Buffer and forward mapped input actions to `Abilities`. |
| `player` | `PlayerEntity` | Read upgrade flags, spawn attacks, apply movement, and own ship, engine, shield, and hit-flash presentation. |
| `enemy-*` | `EnemyBrain` | Run role-specific telegraph, attack, recovery, and boss phase states. |
| `enemy-*` | `SteeringAgent` | Produce role movement from seek, arrive, flee, and containment behavior. |
| `enemy-*` | `EnemyEntity` | Apply damage/status, report death, expose HP, and own a child hull rotated 90° from steering heading to account for the ships' authored up-facing axis. |
| `projectile-*` | `ProjectileMotion` | Move one pooled projectile, test collisions, handle bounce/lifetime, and return it to the pool. |
| `terminal-*` | `Interactable` | Expose one treasure, shop, or recovery prompt and open its one-shot action. |
| `attack-telegraph` | `GraphicsComponent` + `FadeAndDestroy` | Draw an attack's real line or radial geometry and expire with the wind-up. |
| `relay-arena` | `ArenaGateView` | Draw arena bounds and gates from current room state. |
| `minimap` | `RunHud` | Draw discovery state and special nodes from the live floor graph. |
| `run-hud` | `RunHud` | Show hull, ability cooldown, salvage, repair kits, key, room type, seed, prompts, menus, and current input hints. |
| `particles-*` | `ParticleEmitterComponent` | Reuse one configured hit, trail, smoke, or reward emitter. |

## Communication

Direct references carry synchronous run ownership:

- `RunScene` owns `FloorGraph`, player, projectile pool, emitters, HUD, minimap state, and overlay state.
- `PlayerEntity` calls the owned projectile pool and run scene through `RunWorld`.
- `EnemyBrain` reads the stable player transform and calls the owned projectile pool.
- HUD and minimap read current state from `RunScene`.

The interaction addon supplies `InteractionFocusChangedEvent`; other run-local facts use direct owner callbacks. Scene transitions pass a small `RunResult` object to `ResultScene`.

## Input actions and bindings

| Action | Keyboard/mouse | Gamepad |
|---|---|---|
| Move | WASD or arrows | Left stick |
| Aim | Pointer | Right stick |
| Fire | Left mouse or Space | Right trigger |
| Dash | Shift | A |
| Pulse | Right mouse or Q | Left shoulder |
| Interact | E | X |
| Build view | Tab | Y |
| Pause | Escape | Start |
| Menu navigation | Arrows or WASD | D-pad or left stick |
| Confirm | Enter or Space | A |
| Cancel | Escape or Backspace | B |
| Reroll seed on title | R | X |

Gameplay actions belong to the `gameplay` input group. Menu actions remain available while an overlay is open.

## Asset manifest

`src/content/assets.ts` is the only asset-handle list. Every copied file appears in that manifest and in at least one scene or effect. Paths are base-relative under `assets/`.

The asset categories, IDs, authors, metadata, and runtime treatment are recorded in `ASSET-PLAN.md`. Background sheets render at their native aspect ratio, authored effects use an appropriate blend mode, and audio gains come from the library's LUFS and true-peak measurements.

## Run-owned model

The build view includes a focused “use repair kit” action, so world interaction and healing never compete for E/X.

`RunScene` stores:

- numeric seed and `FloorGraph`
- current, visited, discovered, and cleared room IDs
- hull and maximum hull
- run seconds, kills, damage dealt, damage taken, and rooms cleared
- owned circuit IDs and derived synergy IDs
- current overlay and focused choice
- fresh `Inventory` with salvage, repair kits, and relay key
- a WIP core `EntityPool` and room-owned entity bookkeeping

A new run constructs every field again. No prior run object is reused.

## Persistent save shape

One `createStore` document named `vector-wake.progression` stores:

```ts
{
  runs: number;
  wins: number;
  bestRooms: number;
  unlockedGhostCapacitor: boolean;
  achievements: string[];
}
```

The store contains no health, inventory, room, upgrade, cooldown, or active-ability state.

## Roguelite conventions used

- Generate a seeded graph before furnishing rooms.
- Separate run power from persistent variety.
- Lock combat-room gates until clear and keep cleared rooms empty on backtrack.
- Offer one of three readable circuits at five or more reward beats.
- Guarantee one recovery route and a required boss key from the elite.
- Reset all temporary state on restart.

## Shooter conventions used

- Aim is always visible and remains stable when the right stick returns to rest.
- Player and enemy bullets have different silhouettes, colors, trails, and sounds.
- Every projectile has a hit, expiry, or bounds end.
- Major attacks show their true damage geometry before activation.
- Player damage preserves control and grants a short readable invulnerability window.
- Projectiles are pooled from the start.

## Verification handoff

The Inspector extension namespace is `vector-wake`. It exposes:

- `state()` for the run-state snapshot
- `validateGraph()` for reachability and bidirectional connections
- `clearRoom()` to finish the current non-boss encounter
- `grantUpgrade(id)` to test circuits and synergies
- `grantInventory(item, quantity)` to test inventory use and reset
- `damagePlayer(amount)` to test i-frames, shield behavior, and the failed ending
- `defeatBoss()` to test completion and persistence

`RunStateProbe.serialize()` must report enough state for the same checks through the normal Inspector component snapshot.