Close out the collision conversion in TODO.md

§6 item 39 is done: both listings and both tutorials are on SOLID,
COLLISION 2 and RCOLLISION. Record the two traps the conversion turned up
that no error reports -- BUMP's mask is by sprite number, so the artwork
game's balls are bits 16, 32 and 64; and a bare SOLID after the fill loop
retires the rectangles it was meant to precede.

§6 item 38 and §9 item 9 carried statements the work since made false.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EwxGB6TdoVvZ11KQQME9cL
This commit is contained in:
2026-08-02 13:15:02 -04:00
parent a01554d304
commit 766b0f0dd6

51
TODO.md
View File

@@ -2244,35 +2244,35 @@ each is here so the reasoning does not have to be reconstructed.
naive all-pairs sweep at 0.7% of a frame at 64 actors and 11% at 256, so the crossover is
well above anything a Commodore-shaped sprite budget will reach.
Also still open at the seam: the contact is computed and discarded. §6 item 40 and the
BASIC surface built on it are what consume it.
What remains is only the pairing seam above. The contact itself is consumed:
`akbasic_collision_service()` pulls it per sprite and the `RCOLLISION` fields are what both
breakout games now bounce on.
39. **Convert the breakout listings and chapters 17 and 18 to the collision verbs.** This is the
payoff, and it is deliberately not part of the integration commit.
39. ~~**Convert the breakout listings and chapters 17 and 18 to the collision verbs.**~~
**Done.** Both games and both tutorials now register their bricks with `SOLID`, arm
`COLLISION 2` and read the contact back with `RCOLLISION`.
Neither game calls `COLLISION` or `BUMP` even once today. Of roughly 230 lines of collision
code across the two, about 19 are sprite-against-sprite; the rest is a sprite against
numbers in a BASIC array or against bare constants, because bricks are text characters in
one game and stamped pixels inside one big sprite in the other. Static collision geometry is
what changes that — a brick becomes a collidable box without spending a sprite slot.
What went: `BALLBRICKS` (29 lines) and `TESTCELL` (28) in the artwork game, and `HITTEST`
(14) plus its pixel-to-cell arithmetic in the characters game — replaced by a handler that
asks which box was hit and which axis to reverse. The hand-written minimum-translation-axis
is `RCOLLISION(n, 7)`. `BUILDLIVE`/`BUILDROW`/`STAMPROW` went with the full-field redraw
they existed to make cheap, and the artwork game gave six orphaned declarations back with
them: the label table went from 61 of 64 to 57.
What goes, concretely:
Two things are worth keeping from doing it, because neither is obvious and both cost an
evening:
- `examples/breakout/sprites/breakout.bas` — `BALLBRICKS` (29 lines) and `TESTCELL` (28)
become a handler that reads which box was hit and which axis to reverse. The
hand-written minimum-translation-axis at `:661-666` is a contact field. `BUILDLIVE` and
`BUILDROW` stop maintaining a parallel `BRK#()` grid.
- `examples/breakout/characters/breakout.bas` — `HITTEST` (14 lines) and the pixel-to-cell
arithmetic go the same way, and `PADHIT`'s five-line overlap test becomes `BUMP`.
- **`BUMP`'s mask is by sprite number, not by anything the handler is about.** The artwork
game's balls are sprites 5, 6 and 7, so their bits are 16, 32 and 64. A handler that
tests 1, 2 and 4 runs, matches nothing and returns, with no error and nothing to see.
- **A bare `SOLID` must run *before* the level is laid out, not after.** Put after the fill
loop it retires all sixty rectangles that were just registered, and the only symptom is a
ball that passes through the wall.
**The documentation cost is the reason this is separate.** Chapter 17 Step 10 and chapter 18
Steps 9 and 13 are built around that arithmetic, both chapters' examples are executed by
`docs_examples`, and both were rewritten and validated immediately before this work started.
Folding a listing rewrite into a library integration would make neither reviewable.
Sequence it after §9 item 9 if that is ever fixed, since a game that no longer spends two
sprites on the screen has two more to spend on collidable things, and the two rewrites would
otherwise touch the same lines twice.
Chapter 18 also lost a rule it depended on and no longer stated: a `FOR` with equal bounds
does not run its body (§6 item 19), which is why every list in the chapter has its one-item
case written out beside the loop. It is now stated in Step 7 where it is first used, rather
than cross-referenced to a step that the rewrite deleted.
40. **`akbasic_runtime_call_function()`: call a BASIC function from C with bound values.**
@@ -3151,7 +3151,8 @@ reduced against `build/basic`, the stdio build, unless it says otherwise.
9. ~~**A program that wants a picture on the screen has to spend a sprite slot on it, and
`examples/breakout/sprites/breakout.bas` spends two of its eight on the screen itself.**~~
**Done for the interpreter; the listing has not been converted yet -- that is §6 item 39.**
**Done.** The listing has been converted with it: no `SSHAPE` of the screen, no `PACE`
routine hunting for a batch boundary, and both slots free.
The drawing verbs now render into a layer the frame composites under the text and the
sprites (`akbasic_graphics_akgl_begin`/`_end`/`_render`, `src/graphics_akgl.c`), so a