Back to Rail Game
SOURCE / PINNED RELEASE

Made of little things.

Rail Game

Release
ccdd5b913413…
Author-recorded commit
ddf0122b6acc…
License
LICENSE
Author’s source reference
nostr://npub1n8ga89w8h6tvwamxusfyzexw8gjy84yxu9rxgnmk955cxtml4ujswzxydd/wss%3A%2F%2Fgit.napplet.soy%2F/n-91ec90c6fdf

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

README.md
# Rail Game

A small geometric squad runner: steer down a straight track, recruit soldiers,
collect multipliers and upgrades, dodge barriers, and defeat eight wardens.
Stages span 900–2,160 meters, with 690–2,730 enemy soldiers per stage and squads of up to 250 soldiers. The camera
sits behind and to the left, looking down a slightly diagonal track. Built with
TypeScript and a projected Canvas scene, without external game assets.

## Play locally

```bash
soyli dev
```

Open the printed URL to play inside the real napplet sandbox. Read
[the workspace guide](docs/napplet-space.md) for the installed toolchain and host.
The project is already scaffolded; `soyli setup` prepares dependencies if needed.

- Move with **A/D**, **←/→**, drag on the track, or hold the on-screen arrows.
- Shooting is automatic. Every soldier contributes a projectile.
- Cyan gates recruit soldiers; green gates multiply the squad (maximum 250).
- Gold pickups increase damage. Violet pickups give 10 seconds of rapid fire.
  A blue shield absorbs one hit.
- Shoot coral enemies. Avoid striped barriers: they also block your shots.
- **P**, **Escape**, or the pause button pauses. Focus loss and very small frames
  pause automatically; resume explicitly when ready.
- Clear a stage to unlock the next. Each stage starts with twelve soldiers and
  fresh upgrades. Sound is off by default; use ♪ or the host's Settings panel.

The frame supports portrait and landscape layouts. Below 240×280 it pauses and
shows a resize notice. Runtime themes apply to the canvas and interface.

## Boundaries and implementation

No account or network is needed. `storage`, `theme`, and `config` are optional SDK
features. Storage saves unlocked stages and best scores; when unavailable or
denied, records remain in memory for the session. The host controls persistence
scope, which can change with a new build. There are no relay escape hatches or
hard NAP requirements.

- `src/game.ts`: fixed-step simulation, stage sequences, collisions and upgrades.
- `src/renderer.ts`: projection and geometric drawing; the visual layer to replace
  when introducing modeled assets.
- `src/main.ts`: input, HUD, sound, lifecycle and optional host integrations.
- `src/progress.ts`: validation and merging of saved progress.
- `config.schema.json`: sound and reduced-effects settings.

The build remains the upstream single-file Vite substrate. The output is
`dist/index.html`; the napplet uses no external runtime assets.

## Verify

```bash
pnpm verify                 # guidance + types + game regressions + build
pnpm test:game              # combat, upgrades, persistence and all eight stages
pnpm test:conformance       # built app in the reference iframe
soyli check                 # built app in the soyLI host
node tests/browser-smoke.mjs http://127.0.0.1:PORT/
node tests/browser-campaign.mjs http://127.0.0.1:PORT/
node tests/capture-preview.mjs http://127.0.0.1:PORT/
```

The browser smoke test uses Chromium from the installed conformance toolchain.
It checks exact frame sizes and both themes in the real host, keyboard steering,
touch drag/hold/cancellation, and pause/resume. Its temporary viewport fixture
expands the existing injected iframe to the browser viewport; it does not replace
the host runtime. Captures and results go in ignored `.napplet-space/qa/`.

The campaign test plays all eight stages through real pointer input with
accelerated animation time, reaches 250 soldiers, checks live resizing, and
verifies unlocks after reload. It records heavy-scene JavaScript frame timings.
The capture script plays to a full squad and saves real landscape and portrait
images in `.napplet-space/promotion/`, checking that the resized canvas repainted.

See [verification and capture notes](docs/release-verification.md) for observed
results and remaining device coverage. Publishing is a separate creator action.

## Agent guidance

Follow [AGENTS.md](AGENTS.md), [the design brief](docs/game-spec.md), and the
installed napplet skills. For another environment, install the official skills:

```bash
npx skills add napplet/napplet
```