The highlights shoot themselves: one command, seven vertical clips
`python3 tools/capture.py` fills promo/clips/ with 1080x1920 h264/aac takes of the moments the campaign plan (item 4) already named — transition, horde, flamer, mopboy, death on the gore side, boss and match on the zombie-tennis side. capture.py serves the repo with tools/clips.js injected, opens a throwaway-profile Chrome and converts each POSTed webm with ffmpeg; clips.js stages every scene through the real doors on window.T and drives it with the reachability soak's own mediocre autopilot. Nothing is faked for the camera. The game gains four names on window.T (start, intoSplatter, startHorde, sendBoy) and nothing else: the frame is pinned by the canvas box rather than the window, RES 4 comes from lowPower 0 plus device-scale-factor 3, and the audio is tapped by making BaseAudioContext's `destination` a gain node — so audio.js needs no master bus for a tool that ships to nobody. tools/ and promo/clips/ are ignored by git and docker alike. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
296d34d8ca
commit
491f3b97f1
7 files changed
+338
-5
No files matched your search
+28
-2
@@ -3553,8 +3553,34 @@ never an interstitial. An interstitial after death would land exactly in the "on
|
||||
Clips the game already contains: the transition (the flagship), a boss walking on, the ball boy
|
||||
calmly mopping blood, a flame ball starting an epidemic across a lined-up wave, parrying a boss's
|
||||
volley back into him, a horde, the death + run summary.
|
||||
A capture helper on `window.T` to jump straight into a given beat (the transition timeline is on
|
||||
`G.transT`) would make clean takes cheap — not yet built.
|
||||
**THE CAPTURE RIG IS BUILT (2026-08-18): `python3 tools/capture.py` and the folder fills up.**
|
||||
`tools/capture.py` serves the repo with `tools/clips.js` injected, opens a throwaway-profile
|
||||
Chrome, and the page stages each highlight through `window.T`, records it, POSTs the webm back;
|
||||
ffmpeg writes 1080x1920 h264/aac into `promo/clips/`. Named scenes shoot alone
|
||||
(`python3 tools/capture.py horde boss`). Seven scenes exist and the list in `clips.js` is the
|
||||
place to add one — the gore side is `transition` (the flagship: four seconds of ordinary tennis
|
||||
before the turn), `horde`, `flamer`, `mopboy`, `death`, and the zombie-tennis side is `boss` and
|
||||
`match`. Nothing is faked for the camera: every clip enters through the same doors a player does
|
||||
(`T.start`, `T.intoSplatter`, `startHorde`, `startBossFight`, `startMatch`), and the two pilots
|
||||
are deliberately mediocre — the tennis one IS the reachability soak's from `test.js`.
|
||||
Four things it learned the hard way, none of them obvious:
|
||||
- **The clip is the canvas BACKING STORE, not the window.** Chrome opened maximised and ignored
|
||||
`--window-size`, and `resizeTo` did nothing; the frame is pinned instead by giving the canvas a
|
||||
9:16 CSS box, which `render.js` measures (`cv.clientWidth`) through its ResizeObserver.
|
||||
- **`TUNE.lowPower` defaults ON and caps `RES` at 3**, so the recording came out 810x1440 and
|
||||
needed a blurry 1.33x upscale. The rig sets it to 0; with `--force-device-scale-factor=3` the
|
||||
backing store is exactly 1080x1920 and no filter ever touches a pixel.
|
||||
- **Audio has no master bus** — every voice in `audio.js` connects straight to `ac.destination` —
|
||||
so the rig makes `destination` itself a gain node fanning to the speakers AND to a
|
||||
`MediaStreamDestination`, patched on `BaseAudioContext.prototype` (not `AudioContext`'s) before
|
||||
the game module boots. No refactor of the game for a tool that ships to nobody.
|
||||
- **One page load per scene.** A fresh boot is the only teardown guaranteed correct, and it costs
|
||||
a second: the page reloads itself into the next scene and POSTs `/done` when the list is empty.
|
||||
`tools/` is in neither the Dockerfile COPY nor the image, and `promo/clips/` is git- and
|
||||
docker-ignored: the footage is a local build product, not a deployed asset.
|
||||
Still hand-work after the rig: the name mark on screen (item 5 wants it in EVERY clip), any
|
||||
cutting, and the caption. Skipped deliberately — a burned-in watermark is a taste decision and
|
||||
ffmpeg `drawtext` needs a font file the repo does not have in a `drawtext`-friendly format.
|
||||
5. **How a viewer actually reaches the game — the name does the work, not the link.** TikTok and
|
||||
Instagram have no clickable caption links, so the bio link costs two taps (profile, then link) and
|
||||
converts in the single-digit percents. YouTube Shorts descriptions and pinned comments DO click,
|
||||
|
||||
Reference in new issue
Block a user