1
0
Fork 0
mirror of https://github.com/imjasonh/nescript synced 2026-07-08 08:55:38 +00:00

docs: add docs/pong.gif demo to README

Record a 6-second gif of examples/pong.nes running in jsnes and
embed it alongside docs/platformer.gif and docs/war.gif as the
third project demo. The gif opens on Pong's title menu (CPU VS
CPU / 1 PLAYER / 2 PLAYERS) — warmup = 4 frames keeps the menu
as the thumbnail the way war's recording does, and then the
headless autopilot advances to gameplay partway through the
clip.

- docs/pong.gif committed (128 KB)
- README.md links it under the war demo
- scripts/pre-commit rebuilds it when examples/pong* or the
  recorder/harness change
- .github/workflows/ci.yml fails if the committed copy is stale
- CLAUDE.md and tests/emulator/record_gif.mjs reference the new
  gif in the "how to regenerate" sections

https://claude.ai/code/session_0134F5uwDEVTes2Ee9S7JeXy
This commit is contained in:
Claude 2026-04-16 10:44:57 +00:00
parent 21b91f6398
commit 6d9ebc7d7b
No known key found for this signature in database
6 changed files with 48 additions and 21 deletions

View file

@ -176,6 +176,19 @@ jobs:
echo "::error file=docs/war.gif::committed docs/war.gif is stale; rerun \`node tests/emulator/record_gif.mjs war 360 2 docs/war.gif 4\` and commit the new gif" echo "::error file=docs/war.gif::committed docs/war.gif is stale; rerun \`node tests/emulator/record_gif.mjs war 360 2 docs/war.gif 4\` and commit the new gif"
exit 1 exit 1
fi fi
- name: Verify docs/pong.gif is up to date
# Same contract as the platformer and war gifs: the README
# embeds docs/pong.gif as the third project demo. Pong's
# title screen (CPU VS CPU / 1 PLAYER / 2 PLAYERS menu) is
# the gif thumbnail, so warmup = 4 keeps it in frame before
# the autopilot advances to gameplay.
working-directory: tests/emulator
run: |
node record_gif.mjs pong 360 2 /tmp/pong.gif 4
if ! cmp -s ../../docs/pong.gif /tmp/pong.gif; then
echo "::error file=docs/pong.gif::committed docs/pong.gif is stale; rerun \`node tests/emulator/record_gif.mjs pong 360 2 docs/pong.gif 4\` and commit the new gif"
exit 1
fi
- name: Upload actual + diff PNGs on failure - name: Upload actual + diff PNGs on failure
if: failure() if: failure()
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4

View file

@ -22,28 +22,31 @@ re-derive the project conventions from scratch.
tmp path and fails if the committed version differs, pointing at tmp path and fails if the committed version differs, pointing at
the exact `cargo run -- build examples/<name>.ne` to run. The the exact `cargo run -- build examples/<name>.ne` to run. The
pre-commit hook under `scripts/pre-commit` catches this locally. pre-commit hook under `scripts/pre-commit` catches this locally.
- **`docs/platformer.gif` and `docs/war.gif` are committed** and - **`docs/platformer.gif`, `docs/war.gif`, and `docs/pong.gif` are
embedded in the top-level README as the project demos. `gifenc` + committed** and embedded in the top-level README as the project
`jsnes` are deterministic, so each gif's bytes are a function of demos. `gifenc` + `jsnes` are deterministic, so each gif's bytes
the compiler, the runtime, the harness, and the underlying `.ne` are a function of the compiler, the runtime, the harness, and
source(s). Any change to those that affects the first ~6 seconds the underlying `.ne` source(s). Any change to those that affects
of observable gameplay must be followed by regenerating the the first ~6 seconds of observable gameplay must be followed by
affected gif: regenerating the affected gif:
```bash ```bash
node tests/emulator/record_gif.mjs platformer 360 2 docs/platformer.gif node tests/emulator/record_gif.mjs platformer 360 2 docs/platformer.gif
node tests/emulator/record_gif.mjs war 360 2 docs/war.gif 4 node tests/emulator/record_gif.mjs war 360 2 docs/war.gif 4
node tests/emulator/record_gif.mjs pong 360 2 docs/pong.gif 4
``` ```
(The trailing `4` on the war command is the warmup-frames (The trailing `4` on the war and pong commands is the
override — war's title menu is the gif thumbnail, so we don't warmup-frames override — both open on a title menu that we want
skip past it the way the platformer recording does.) Commit the as the gif thumbnail, so we don't skip past it the way the
regenerated gif in the same change. CI's `emulator` job renders platformer recording does.) Commit the regenerated gif in the
fresh gifs and fails if either committed copy doesn't byte-match. same change. CI's `emulator` job renders fresh gifs and fails if
The pre-commit hook rebuilds whichever gif is affected when any committed copy doesn't byte-match. The pre-commit hook
`platformer.ne`, `platformer.nes`, any file under `examples/war/`, rebuilds whichever gif is affected when `platformer.ne`,
`war.ne`, `war.nes`, `record_gif.mjs`, or `harness.html` is `platformer.nes`, any file under `examples/war/`, `war.ne`,
staged (and `tests/emulator/node_modules` is installed). `war.nes`, any file under `examples/pong/`, `pong.ne`,
`pong.nes`, `record_gif.mjs`, or `harness.html` is staged (and
`tests/emulator/node_modules` is installed).
- `docs/future-work.md` lists the remaining gaps. If you implement - `docs/future-work.md` lists the remaining gaps. If you implement
something from that file, update the doc in the same PR. something from that file, update the doc in the same PR.

View file

@ -12,6 +12,10 @@ _Source: [`examples/platformer.ne`](examples/platformer.ne)_
_Source: [`examples/war.ne`](examples/war.ne)_ _Source: [`examples/war.ne`](examples/war.ne)_
![Pong demo](docs/pong.gif)
_Source: [`examples/pong.ne`](examples/pong.ne)_
## Quick Start ## Quick Start
```bash ```bash

BIN
docs/pong.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

View file

@ -86,4 +86,9 @@ if [ $recorder_or_harness_changed -eq 1 ] || \
check_gif war 4 || exit 1 check_gif war 4 || exit 1
fi fi
if [ $recorder_or_harness_changed -eq 1 ] || \
echo "$changed_files" | grep -qE '^examples/pong(\.(ne|nes)|/[^/]+\.ne)$'; then
check_gif pong 4 || exit 1
fi
echo "All pre-commit checks passed." echo "All pre-commit checks passed."

View file

@ -6,6 +6,7 @@
// Examples: // Examples:
// node record_gif.mjs platformer 360 2 docs/platformer.gif // node record_gif.mjs platformer 360 2 docs/platformer.gif
// node record_gif.mjs war 360 2 docs/war.gif 4 // node record_gif.mjs war 360 2 docs/war.gif 4
// node record_gif.mjs pong 360 2 docs/pong.gif 4
// //
// The recorder drives `harness.html` via puppeteer, collects one // The recorder drives `harness.html` via puppeteer, collects one
// canvas frame every `stride` NES frames for `frames` total, and // canvas frame every `stride` NES frames for `frames` total, and
@ -20,14 +21,15 @@
// recording uses 4 instead because that demo opens on its menu and // recording uses 4 instead because that demo opens on its menu and
// we want the title screen to be the gif's thumbnail. // we want the title screen to be the gif's thumbnail.
// //
// IMPORTANT: `docs/platformer.gif` and `docs/war.gif` are committed // IMPORTANT: `docs/platformer.gif`, `docs/war.gif`, and
// and embedded in the README. Any change to the compiler, the // `docs/pong.gif` are committed and embedded in the README. Any
// runtime, the harness, or the underlying `.ne` source that alters // change to the compiler, the runtime, the harness, or the
// the gameplay you see in the first ~6 seconds of either demo must // underlying `.ne` source that alters the gameplay you see in the
// be followed by // first ~6 seconds of any of the three demos must be followed by
// //
// node tests/emulator/record_gif.mjs platformer 360 2 docs/platformer.gif // node tests/emulator/record_gif.mjs platformer 360 2 docs/platformer.gif
// node tests/emulator/record_gif.mjs war 360 2 docs/war.gif 4 // node tests/emulator/record_gif.mjs war 360 2 docs/war.gif 4
// node tests/emulator/record_gif.mjs pong 360 2 docs/pong.gif 4
// //
// committed alongside the source change. The CI `emulator` job // committed alongside the source change. The CI `emulator` job
// regenerates both gifs and fails if the committed copies are stale — // regenerates both gifs and fails if the committed copies are stale —