Measured on the cartridge from the rung-10 checkpoint: `wXCoord` and `wYCoord` change at the *end*
of a sixteen-frame step while the background scrolls throughout it, so for fifteen frames of every
sixteen the screen buffer is centred one tile ahead of the coordinates. The cross-check compared
the decode of the fly's own tile with the screen's reading of the tile ahead and refused. Pewter
City decoded on 118 of 120 standing frames and on none of the moving ones, so every walk the fly
actually took was re-planned over the ten-by-nine window, which is the oscillation of row 23.
Nothing in the pinned symbol table says "a step is in progress" and a new address cannot be pinned
without the disassembly `gen_symbols.py` reads, so the anchor is measured rather than named: the
screen is centred on the fly's tile or on one of its four neighbours, and the one it is centred on
is the one whose whole neighbourhood agrees with the decode. A decode with a wrong stride, a wrong
quadrant or a half-loaded map agrees with none of the five, and neither does the mid-warp tear the
per-serve check was added for, so both refusals stand.
`state::step_destination` names the tile the step is landing on, for the ledger the next commit
writes. The town fixture gains two landmarks beside the fly, because a neighbourhood that is the
same tile id in every direction cannot tell one anchor from another.
Unit: no battle pad holds both NEXT and BACK, over every sub-state with and
without a potion and a ball, and NEXT is on none with a cursor accepting input
(the assertion the top-level menu failed before this branch). A battle frame
with a cursor accepting input is the fly's turn, against real WRAM, for all
four menus plus the two frames that correctly are not one. The bag deals
ITEM / THROW BALL / BACK, and BACK alone when the bag is empty.
ROM-gated, from the live rung-9 forest checkpoint: no pad with both buttons, no
NEXT while a menu accepts input, the longest NEXT/BACK alternation under four,
and every battle entered also left, each on a bounded number of macros. The
battle rules ask the scene the pad was dealt for rather than wIsInBattle, so
the $ff frame a lost battle passes through -- which reads Unknown, whose pad is
NEXT and BACK by contract -- is not accused of a battle rule.
The test fails on v0.4.2 from the same checkpoint with "NEXT was on the pad
while a battle menu was accepting input", NEXT dealt on battle/main, and a run
that never leaves map 51.
The walkable predicate answered for the ten-by-nine screen window and Unknown
everywhere else. MapGrid is the same rule over every tile of the loaded map:
block ids out of wOverworldMap, a blocks-to-tiles read of the tileset header s
blockset through the new bank-aware ROM read, the tileset s collision list as
before, and the TilePairCollisionsLand values as directed walls both ways.
The reader checks itself before it answers: the decode is compared against the
window predicate over the player s own neighbourhood, and a frame where the
window can answer for none of it -- a battle, a text box, a frame mid-warp -- is
refused, because wOverworldMap shares its bytes with the picture buffer. Every
refusal is named (GridRefusal) and leaves the window predicate in charge.
Cached per map id and size, so a map is decoded once on arrival rather than once
per question, and owned beside the session ledgers: never checkpointed.