Back to City Breaker
SOURCE / PINNED RELEASE

Made of little things.

City Breaker

Release
94d2b8664b10…
Author-recorded commit
df23103cbcc1…
License
LICENSE
Author’s source reference
nostr://npub1sj2vketepqw9v6fmge5fdzuj7atj9sv6qv2jss05n2z6rl64lcfqumdsnt/wss%3A%2F%2Fgit.napplet.soy%2F/n-cf8b858653e

Archive hash verified: eeeed725668c1ece…. The source-to-build association is the author’s claim; it has not been independently rebuilt.

docs/city-breaker-brief.md
# City Breaker — project brief

```
d-tag / deployment name: city-breaker
new build or port:       new build on the napplet boilerplate
single-purpose job:      a 60-day strategic bombing campaign sim with a flown action layer
must-have flows:         new campaign → HQ map → plan raid (target, time, route, package)
                         → fly (or command from the bunker) → BDA debrief → … → end report
optional flows:          resume a saved campaign (needs `storage`); host settings for
                         volume / screen effects / text size (needs `config`)
visual direction:        see below
form factor:             900×600 and larger is the home; works at 320×560 portrait,
                         landscape phones and full screen; below 300×260 a notice
target runtime:          any NIP-5D shell; no domains are hard requirements
known gaps:              none needed from the NAPs track
```

Full design prompt: [city-breaker-prompt.md](city-breaker-prompt.md).

## NAP domains

| Domain    | Use                                   | Required | Fallback when absent                          |
| --------- | ------------------------------------- | -------- | --------------------------------------------- |
| `storage` | campaign save (`city-breaker-save-v1`) | no       | campaign runs in memory; title screen says so |
| `config`  | volume, screen-effects, text size     | no       | defaults (and `prefers-reduced-motion`)       |
| `theme`   | not used — app-owned palette          | no       | n/a                                           |

No Nostr reads or publishes, no relay, no network. All audio is synthesized with
Web Audio; all art is drawn on canvas.

## Visual direction

**Character.** A Cold War operations room: DEFCON-like phosphor vectors on black,
clinical numbers, and then — only in the mission view and only over the target — fire,
flak, searchlights and smoke. The contrast between the calm vector world and the
hell over Hafenstadt is the aesthetic; the horror comes from the counters.

**Main surfaces.**
- *Strategic map:* near-black field with range rings, a radar sweep, glowing amber
  district blocks (glow = power; they dim as the grid dies), pale civil blocks, red
  hexagon SAM sites with range rings (dashed when intel is stale), animated supply
  dots that stop where a line is cut and reroute over the pontoon, drifting smoke.
- *Mission view:* top-down 2.5D. Altitude lifts aircraft off their shadows. Simple
  vector silhouettes; pooled particles (≤ 900) with additive light for flashes,
  fire, tracers and chaff. Night darkens the ground and lights the city.
- *Debrief:* grainy black-and-white strike photos with grease-pencil marks, and the
  enemy's newspaper on cream newsprint in a serif face — the only warm paper in the game.

**Interface.** Monospace throughout; uppercase small-caps labels with letter
spacing; 1px cyan hairlines, 2px radii; amber for commands and the living city,
red for hostile/loss, green for the goal line. Controls are ≥ 36px (≥ 44px on touch).

**Tokens.** `--bg #03080a`, `--fg #bfe9f2`, `--cyan #5fd3ff`, `--amber #ffb347`,
`--red #ff4a3a`, `--green #7dffa0`, `--paper #e9e3d2`. The canvas renderers use the
same values.

**Theme policy.** App-owned (`FOLLOW_HOST_THEME = false`). Host theme data never
recolors the map, HUD or gameplay colors.

**Proof frames.** Night raid over the burning city with searchlights and a SAM
launch at 900×600 (listing cover); HQ map at 320×560; mission with touch stick at
390×844 and 844×390; the size notice at 200×160.

## Controls

Keyboard: ←/→ or A/D steer · ↑/↓ or W/S climb/dive · Shift/Ctrl throttle · Space fire /
release bombs · F secondary (Atoll, guided-bomb steering uses the arrows) · C chaff ·
T time ×1/×2/×4 · M map · P pause · R hand the raid to the AI.
Crew stations: B bomb doors · Q release mode (train / salvo / single) · V pathfinder marker flare ·
G (hold) tail turret · E extinguisher · H backup hydraulics · K isolate fuel leak · 1/2/3 formation
(tight / normal / loose) · L legend.
Touch: stick bottom-left; CHAFF / ALT / FIRE bottom-right; DOORS / MODE / MARK / GUN / FIX / FORM
above them; ×speed, MAP, legend, pause, AI top.

Flight hazards: terrain (hills to ~600 m, radar-altimeter tone below 250 m), fuel and leaks,
engine fires that explode if ignored, hung bombs, missiles that can be beamed (Doppler notch),
bombs from a higher wave falling through your formation.

## Balancing

Every number is in `src/game/config.ts` (`CONFIG`). Headless harnesses:

```bash
ESB=node_modules/.pnpm/esbuild@0.25.12/node_modules/esbuild/bin/esbuild
$ESB scripts/balance.ts --bundle --platform=node --format=esm --outfile=/tmp/cb-balance.mjs
node /tmp/cb-balance.mjs bottleneck   # or: area | factory  — full 60-day AI campaign
$ESB scripts/player.ts --bundle --platform=node --format=esm --outfile=/tmp/cb-player.mjs
node /tmp/cb-player.mjs power full FAB-500 med   # scripted player raid
```