Both examples gain --screenshot PATH and --screenshot-frame N. The capture sits
between the world being drawn and the frame being presented, because
SDL_RenderPresent is where the target stops being readable, and it works under
the dummy video driver and the software renderer like the rest of the headless
path does.
`cmake --build build --target docs_game_figures` regenerates
docs/images/sidescroller.png and docs/images/jrpg.png by running each game to a
chosen frame. Same contract as docs_screenshots: deliberate, never part of a
build, because the PNGs are tracked. There is no --check counterpart, and the
target says why -- the sidescroller drives its physics from the wall clock, so a
byte comparison would fail for reasons that have nothing to do with the
documentation.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KzBDV2fqgnUAcqCKqKvc71
cell_solid and feet_blocked go, and so does the prediction in the player's
movementlogicfunc. That prediction was only ever exact because the town has zero
gravity and zero drag -- v is t, so `x + tx * dt` is where the step lands. A map
with gravity would have had to fold ey in as well, which is the game
re-implementing the integrator. Resolution runs after the move now, so there is
nothing to predict.
The map's decoration layer carries `collidable`, which retires JRPG_LAYER_SOLID:
akgl_TilemapLayer has no name member, so the game and the map had to agree on an
index out of band and inserting a layer in Tiled broke it.
The edge of the world is not on any layer, so it is four static proxies covering
the outer ring plus a tile of overhang -- one pool slot per side instead of a
hundred solid tiles, and the first use of the static-proxy path in either
example. They carry LAYER_STATIC explicitly: shape_box defaults a shape to
LAYER_ACTOR, and a wall left on that layer is a wall everything walks through.
Only the player gets a shape. NPCs stand still and are spoken to; the follower
is a child snapped to its parent every step.
Verified against the old implementation with the demo script rewritten to hold
one direction: holding left into a building stops the player at x=122 with both,
and holding up into the map's edge stops them at y=-4 with both.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KzBDV2fqgnUAcqCKqKvc71
A pure rename plus link rewrite and nothing else. Collision is a pluggable
subsystem with two implementations, shapes, a response hook and a tile binding;
that is a chapter, and burying it inside the physics chapter is the shape this
manual otherwise avoids -- rendering and drawing are 8 and 9, spritesheets and
characters and actors are 10, 11 and 12.
Kept separate from writing the chapter because **nothing validates a
cross-reference target.** The example harness reads fenced blocks; it does not
follow links. A rename mixed into five hundred lines of new prose is not
reviewable, and a broken link would land silently. As its own commit it is
reviewable as a rename, and a grep for dangling `](NN-` targets is clean.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>