mirror of
https://github.com/imjasonh/nescript
synced 2026-07-08 00:45: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:
parent
21b91f6398
commit
6d9ebc7d7b
6 changed files with 48 additions and 21 deletions
13
.github/workflows/ci.yml
vendored
13
.github/workflows/ci.yml
vendored
|
|
@ -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"
|
||||
exit 1
|
||||
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
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@v4
|
||||
|
|
|
|||
35
CLAUDE.md
35
CLAUDE.md
|
|
@ -22,28 +22,31 @@ re-derive the project conventions from scratch.
|
|||
tmp path and fails if the committed version differs, pointing at
|
||||
the exact `cargo run -- build examples/<name>.ne` to run. The
|
||||
pre-commit hook under `scripts/pre-commit` catches this locally.
|
||||
- **`docs/platformer.gif` and `docs/war.gif` are committed** and
|
||||
embedded in the top-level README as the project demos. `gifenc` +
|
||||
`jsnes` are deterministic, so each gif's bytes are a function of
|
||||
the compiler, the runtime, the harness, and the underlying `.ne`
|
||||
source(s). Any change to those that affects the first ~6 seconds
|
||||
of observable gameplay must be followed by regenerating the
|
||||
affected gif:
|
||||
- **`docs/platformer.gif`, `docs/war.gif`, and `docs/pong.gif` are
|
||||
committed** and embedded in the top-level README as the project
|
||||
demos. `gifenc` + `jsnes` are deterministic, so each gif's bytes
|
||||
are a function of the compiler, the runtime, the harness, and
|
||||
the underlying `.ne` source(s). Any change to those that affects
|
||||
the first ~6 seconds of observable gameplay must be followed by
|
||||
regenerating the affected gif:
|
||||
|
||||
```bash
|
||||
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 pong 360 2 docs/pong.gif 4
|
||||
```
|
||||
|
||||
(The trailing `4` on the war command is the warmup-frames
|
||||
override — war's title menu is the gif thumbnail, so we don't
|
||||
skip past it the way the platformer recording does.) Commit the
|
||||
regenerated gif in the same change. CI's `emulator` job renders
|
||||
fresh gifs and fails if either committed copy doesn't byte-match.
|
||||
The pre-commit hook rebuilds whichever gif is affected when
|
||||
`platformer.ne`, `platformer.nes`, any file under `examples/war/`,
|
||||
`war.ne`, `war.nes`, `record_gif.mjs`, or `harness.html` is
|
||||
staged (and `tests/emulator/node_modules` is installed).
|
||||
(The trailing `4` on the war and pong commands is the
|
||||
warmup-frames override — both open on a title menu that we want
|
||||
as the gif thumbnail, so we don't skip past it the way the
|
||||
platformer recording does.) Commit the regenerated gif in the
|
||||
same change. CI's `emulator` job renders fresh gifs and fails if
|
||||
any committed copy doesn't byte-match. The pre-commit hook
|
||||
rebuilds whichever gif is affected when `platformer.ne`,
|
||||
`platformer.nes`, any file under `examples/war/`, `war.ne`,
|
||||
`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
|
||||
something from that file, update the doc in the same PR.
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,10 @@ _Source: [`examples/platformer.ne`](examples/platformer.ne)_
|
|||
|
||||
_Source: [`examples/war.ne`](examples/war.ne)_
|
||||
|
||||

|
||||
|
||||
_Source: [`examples/pong.ne`](examples/pong.ne)_
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
|
|
|
|||
BIN
docs/pong.gif
Normal file
BIN
docs/pong.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 129 KiB |
|
|
@ -86,4 +86,9 @@ if [ $recorder_or_harness_changed -eq 1 ] || \
|
|||
check_gif war 4 || exit 1
|
||||
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."
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
// Examples:
|
||||
// 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 pong 360 2 docs/pong.gif 4
|
||||
//
|
||||
// The recorder drives `harness.html` via puppeteer, collects one
|
||||
// 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
|
||||
// we want the title screen to be the gif's thumbnail.
|
||||
//
|
||||
// IMPORTANT: `docs/platformer.gif` and `docs/war.gif` are committed
|
||||
// and embedded in the README. Any change to the compiler, the
|
||||
// runtime, the harness, or the underlying `.ne` source that alters
|
||||
// the gameplay you see in the first ~6 seconds of either demo must
|
||||
// be followed by
|
||||
// IMPORTANT: `docs/platformer.gif`, `docs/war.gif`, and
|
||||
// `docs/pong.gif` are committed and embedded in the README. Any
|
||||
// change to the compiler, the runtime, the harness, or the
|
||||
// underlying `.ne` source that alters the gameplay you see in the
|
||||
// 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 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
|
||||
// regenerates both gifs and fails if the committed copies are stale —
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue