← all games

arena-shooter-fable-max — GAME.md

# NEON BREACH — game manifest

Top-down arena shooter. One 1280×720 arena, three waves, neon-on-dark procedural art (no asset files).

## Scene stack

- `MenuScene` (`src/scenes/MenuScene.ts`) — title (glow + per-glyph wave), controls card, blinking start prompt, drifting enemy silhouettes over the arena floor. Any click or Enter pushes `GameScene` with a fade.
- `GameScene` (`src/scenes/GameScene.ts`) — the run. Spawns camera (`fitTo` the arena rect), floor deco, 4 static wall colliders, `Player`, `Crosshair`, `Hud`, `DangerVignette`, `WaveDirector`. Adds bloom to `world`/`fx` layers and a scene-wide chromatic aberration (pulsed on damage). Hides the OS cursor while active.
- `GameOverScene` (`src/scenes/GameOverScene.ts`) — overlay (`transparentBelow`, pauses the game below). Scrim + stats card (score, kills, wave, accuracy, time), RETRY / MENU buttons, Enter = retry.

Layers (GameScene): `floor` −10, `world` 0, `fx` 10 (world-space) · `overlay` 150, `hud` 200 (screen-space).

## Entities

| Entity | File | Notes |
|---|---|---|
| `Player` | `entities/Player.ts` | Dynamic body, circle r15. `PlayerController`: WASD smoothed movement (285 px/s), mouse aim (hull rotates), hold-to-fire blaster (8.3/s, alternating muzzles, spread, recoil), Space/Shift dash (950 px/s, 0.16 s, i-frames, 1.5 s cooldown, afterimage ghosts), 1.1 s i-frames + blink on hit, knockback, hitstop, death via `PlayerDied`. |
| `Bullet` | `entities/Bullet.ts` | Sensor circle, CCD, 820 px/s, 0.9 s lifetime. Hits `Enemy` (damage 1 + knockback) or walls; sparks on impact. |
| `Enemy` | `entities/Enemy.ts` | Kinds: `chaser` (2 hp, dart, wobble-seek), `dasher` (3 hp, chevron, windup blink → locked dash), `splitter` (6 hp, hexagon, slow; splits into 2 minis), `mini` (1 hp, fast). `EnemyCore` owns hp/knockback/death (burst + ring + hitstop + score popup + 12 % pickup drop). Enemy–enemy separation steering. |
| `SpawnPortal` | `entities/SpawnPortal.ts` | 0.85 s rotating telegraph ring, then spawns its enemy. |
| `Pickup` | `entities/Pickup.ts` | +1 HP (or +100 score at full HP), bobs, blinks before 9 s expiry. |
| `Crosshair` | `entities/Crosshair.ts` | Reticle at pointer world pos, spins, kicks on fire. |
| `Hud` / `DangerVignette` | `entities/Hud.ts` | UISurfaces: hull pips (TL), wave + enemy counter (TC), score (TR), dash meter (BL). Red edge vignette breathing at ≤2 HP. |
| `WaveDirector` | `entities/WaveDirector.ts` | Wave state machine + banners + victory/defeat sequences + `arena` inspector extension. |

## Waves

| Wave | Composition | Speed mult |
|---|---|---|
| 1 | 8 chasers | 1.0 |
| 2 | 12 chasers + 3 dashers | 1.18 |
| 3 | 15 chasers + 5 dashers + 2 splitters | 1.35 |

Wave-clear bonus +250. Spawn portals stagger 0.38–0.55 s apart, ≥260 px from the player.

## Input actions (`src/main.ts`)

`up/down/left/right` = WASD + arrows · `fire` = MouseLeft · `dash` = Space, ShiftLeft · `confirm` = Enter.

## State

Reactive store `run` (`src/stores.ts`): hp, wave, totalWaves, remaining, score, dashRatio, kills, shotsFired, shotsHit. Reset per run. No save system — nothing persists.

## Assets

None on disk. Particle textures are runtime-registered (`fx-soft`, `fx-spark` in `src/fx.ts`); all shapes are `GraphicsComponent` draws; SFX are WebAudio-synthesized (`src/sfx.ts`); fonts are system stacks.

## Debug / verification surface

`window.__yage__.inspector.getExtension("arena")`: `state()`, `killAll()`, `spawn(kind)`, `setHp(n)`. Engine runs with `debug: true`; DebugPlugin overlay on backtick.