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.
# Eight-stage campaign expansion
Historical verification before the enemy-platoon release. See
[the release notes](release-verification.md) for current counts and checks.
Updated 2026-09-23. The campaign now has eight stages, twelve starting soldiers,
a 250-soldier cap, ×2/×3 gates and faster volleys. The left-offset camera remains.
## Routes
Travel time excludes each warden fight. Enemy totals exclude the warden.
| Stage | Route | Length | Travel time | Enemies |
| --- | --- | ---: | ---: | ---: |
| 1 | The causeway | 900 m | 90 s | 198 |
| 2 | Red freight | 1080 m | 103 s | 252 |
| 3 | Last platform | 1260 m | 115 s | 396 |
| 4 | Iron crossing | 1440 m | 125 s | 456 |
| 5 | Ember viaduct | 1620 m | 135 s | 660 |
| 6 | Siege express | 1800 m | 144 s | 735 |
| 7 | Blackrock pass | 1980 m | 152 s | 972 |
| 8 | The citadel | 2160 m | 160 s | 1080 |
Each route contains four to eleven combat sectors with rotated recruitment lanes,
multiplier choices, single/double barricades and extra crossfire formations.
Final recruits, damage and rapid fire prepare the squad for the arena. Boss fans
cap at nine projectiles to preserve escape space. Boss health rises from 6000 to
25000. Every soldier contributes one projectile per volley: every 0.22 seconds,
or 0.09 seconds during rapid fire.
The picker uses two rows of four stage buttons, with a horizontally scrollable
row in the shortest narrow frames. Labels announce locked stages. The compact
layout initially expanded beyond 240 pixels because of CSS Grid intrinsic sizing;
constraining the grid track and briefing minimum width fixed it.
Existing three-stage save values still parse and retain their scores, padding the
new stages with zeroes. Unlocks continue sequentially. An old final-stage record
does not contain a completion flag, so the game does not infer that stage four
should be unlocked from a score alone. The host still owns persistence scope;
this change does not bypass storage isolation across builds.
## Checks
- `pnpm verify`: six guidance checks, strict type-check and single-file build pass.
- `soyli check`: passes with the current build and selected cover/clip.
- `pnpm test:game`: sixteen tests pass, including all eight complete routes,
250 independent firing soldiers, track bounds, dense content throughout each
extended route, bounded boss spreads and legacy progress validation.
- `pnpm test:conformance`: five pass, zero fail, five skip. Signed manifest, wire
evidence and lifecycle remain unmeasured by this local-directory invocation.
- Browser smoke: 200×160, 240×280, 320×560, 900×600 and 2400×1200 pass in dark and
light themes. Keyboard, undersize/focus pause and explicit resume pass. Touch
drag, hold, cancel, release and pause pass at 390×844, 360×640 and 844×390.
The real host injects storage, theme and config. No browser errors observed.
- Full browser campaign: all eight stages completed through real pointer input
and virtual animation time, without altering live game state. The test reads
the stage layout locally to plan movement; the game still executes its own
movement, collisions, firing, scoring and unlock logic in the host iframe.
It reached 250 soldiers, captured desktop and portrait formations, and verified
the eighth-stage unlock after reload. No browser runtime errors occurred.
| Stage | Score | Survivors |
| --- | ---: | ---: |
| 1 | 21700 | 250 |
| 2 | 24450 | 250 |
| 3 | 29350 | 250 |
| 4 | 40450 | 250 |
| 5 | 52100 | 250 |
| 6 | 59850 | 250 |
| 7 | 77900 | 250 |
| 8 | 79850 | 230 |
At 200 or more soldiers, 52440 JavaScript animation callbacks measured a median
2.7 ms and 95th percentile 3.5 ms on this machine. These are simulation and draw
submission timings using a retained native performance clock, not GPU completion
or physical-device frame-rate measurements. Results are in ignored
`.napplet-space/qa/campaign-results.json`.
## Preview
The selected cover, `preview-campaign.png`, is a real 900×600 capture at 250
soldiers. The 390×844 counterpart is in ignored
`.napplet-space/qa/squad-250-portrait.png`. Earlier preview files are preserved.
The new eight-second landscape recording starts the run at (480, 431), then
holds ArrowRight from 4400–4820 ms to take the opening multiplier. It shows
12 → 36 → 72 soldiers. The recorder supplies the actual built artifact hash.
Portrait video remains unavailable in the documented recorder.
The 960×600 clip is 8.96 seconds including the recorder's final frame. Its contact
sheet was inspected, and full playback reached the end in the host Listing view.
The selected cover also loaded successfully there.
## Coverage limits
Chromium viewport/touch emulation is covered; physical iOS/Android devices and
actual-device audio are not. No dependencies, assets or host capabilities were
added. No direct network or browser-storage paths were introduced. This is a
local development update, not a published release.
