Rewrite both tutorials as tutorials

They read as design commentary: why a choice was made, what the previous state
of the project was, which library defect a line works around. That is useful to
somebody who already knows the library and useless to somebody trying to build a
game, which is who a tutorial is for.

Both chapters now open with a screenshot of what the reader is building and a
numbered list of the steps to get there, and each step is its own section: what
you are trying to achieve, the code that achieves it, and the two or three things
about that code that are easy to get wrong. Chapter 20 starts from first
principles -- what a sprite, a character, an actor and a tilemap are, and the
four error macros -- and chapter 21 assumes it and covers what a top-down game
adds.

Where a line exists because of a defect, the line comes first and the defect
comes after it, with a pointer to the TODO entry that will remove the need. A
reader who is copying code should not have to read an apology before they can use
it.

The library's own history is gone from both. That belongs in the design chapters
and in git.

Two new docs_examples setups stage the tutorials' own art, so the sprite and
character files a reader is shown are loaded exactly as printed rather than
through a generic fixture. `json excerpt=` is new for the same reason: a Tiled
object is now quoted out of the real map instead of being retyped. Excerpts
across docs/ go from 91 to 137.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KzBDV2fqgnUAcqCKqKvc71
This commit is contained in:
2026-08-02 08:51:39 -04:00
parent 0972472cfa
commit 6553da812c
6 changed files with 1758 additions and 1095 deletions

View File

@@ -38,6 +38,7 @@ rather than a free pass.
| `c wrap=NAME` | The same, with `tests/docs_preludes/NAME.pre` before it and `NAME.post` after |
| `c run=NAME` | Wrapped in `NAME`, **linked against `akgl` and run headless**. Must exit 0 and must not report an unhandled or ignored error |
| `c excerpt=PATH` | Must still appear in `PATH`, ignoring comments and whitespace. **Not compiled** |
| `json excerpt=PATH` | The same check against an asset file, for a fragment too large to show whole |
| `c screenshot=NAME` | Compiled as an `akglframe` body, and the source of `docs/images/NAME.png`. Optionally `size=WxH` |
| `json kind=KIND` | Written to a file and loaded through libakgl's own loader. `KIND` is `sprite`, `character`, `tilemap` or `properties` |
| `output` | The **exact stdout** of the runnable block above it, compared byte for byte |
@@ -156,8 +157,16 @@ the `KINDS` table in `tools/docs_checkjson.c` loads them:
| Setup | What it stages | What loads it |
|---|---|---|
| `setup=spritesheet` | `./spritesheet.png`, a 12x8 grid of 48x48 frames | the `sprite` row's `prepare` |
| `setup=character` | `./sprites/*.json` plus a sheet, named `hero standing left` and `hero walking left` | the `character` row's `prepare` |
| `setup=tilemap` | `./sprites/*.json`, `./characters/testcharacter.json`, and `assets/tileset.png` | the `tilemap` row's `prepare` |
| `setup=sidescroller` | every PNG and sprite file from `docs/tutorials/assets/sidescroller`, in `./` and `./sprites` | both rows' `prepare` |
| `setup=jrpg` | the same, from `docs/tutorials/assets/jrpg` | both rows' `prepare` |
The last two are how the tutorials show a reader a *real* asset file rather than a
generic one. A beginner following chapter 20 or 21 types what is on the page, so
what is on the page has to be a file that loads — the setup stages the tutorial's
own art so the block on the page is the block in the repository.
Those names are a contract between the setup script and the chapter using it.
Change one and change the other, in the same commit. `assets/tileset.png` is