Devlog #050 - Hidden Cards in the City Machine
The city-navigation graph looked stable enough to move past.
Main Street, nighttime Main Street, and the side streets all displayed their normal card-zero rows. Their city-dependent options worked. The route from Quickstart could reach them in SDL.
But “usually displays card zero” is not the same as “the owner begins at card zero.” Several owners contain optional entry arms that publish another card first. Closing those arms exposed why a generic route table can never fully replace the original MSG state machine.
One Shared Query, Three Different Consequences
All three entry owners consult the same event query:
proc_0029_3742(2, 0, current city)A result of FFFFh is significant, but the consequences are owner-specific.
Nighttime Main Street: $MAINS02
The nighttime owner presents card 1 in mode 0 over the inherited
PICS\XNMAIN.PIC visual. It consumes no extra RNG and does not replace the
picture. After acknowledgement it rejoins the ordinary owner and publishes
card-zero rows.
Daytime Main Street: $MAINS01
The daytime owner adds another gate. Only after the event query returns
FFFFh does it consume RNG(100). A signed result below 35 selects card 1.
The picture is not a guess derived from the card text. A live relocated
descriptor capture proved POST-UP.PIC. After the card is acknowledged, the
owner publishes normal Main Street rows over the retained poster visual. It
does not reload MAIN-ST.PIC at the rejoin.
That retained picture may look like an oddity in a modern UI, but it is the original behavior and therefore part of the reconstructed state.
Daytime Side Streets: $SIDES00
The side-street owner uses card 1 in mode 2 and consumes no RNG. Its optional
and primary picture descriptors are independent far pointers, but both decode
to xsid. After acknowledgement the owner recomposes a fresh card-zero header
and rows.
These siblings now have separate StateEffect certificates. Similar-looking entry cards cannot borrow each other’s mode, picture lifetime, RNG, or rejoin behavior.
A Disabled Handbill Row Is Not a Transition
$MAINS01 also contains a due-event check for kind 0051h.
When the event is due for the current city and date, owner ordinal 5 is published in state 2: it remains visible but is greyed out and absent from the selectable-row table.
The resource text may suggest posters or handbills, but no card transition was invented from that prose. The evidence currently proves a row-publication effect. Its later gameplay consequence is a different frontier.
This is a small example of a general rule. Text explains what the player sees; the owner bytes decide what the engine does.
Night Main Street Rejoins the Generic City
One $MAINS02 action was already byte-closed but had not been projected into
clean gameplay.
Raw ordinal zero now executes its exact signed relation:
RNG(100) < 100 - raw rangeThe ordinary result publishes state 0019h, which central redispatch resolves
through the generic $CITYS01 presentation. The exceptional patrol result,
state 003Ch, remains stopped at its own boundary.
This is the desired architecture: $MAINS02 does not know how to draw a city
square. It publishes a raw result, and the central state system selects the
destination owner.
Evidence Became a Reusable Product
The last day was not only about adding routes. It strengthened how routes are added.
Each selected path now carries a narrow certificate over its exact original instruction slice. Parent owners and blocking presentation children are bound separately. Ghidra and Reko are used to cross-check focused cones. Live DOSBox-X observations close relocated pointers or ambiguous helpers. SDL smoke tests then validate the clean product without becoming semantic authority.
That discipline caught several details a looser reconstruction would erase:
- a picture that remains after acknowledgement;
- a mode-2 card where a neighboring owner uses mode 0;
- a disabled visible row rather than a hidden row;
- RNG that belongs to one sibling but not another;
- owner-local no-RNG claims that must end before central redispatch consumes its own randomness.
The complete engine suite reached 2,927 passing tests after these closures. More important than the count is what the tests pin: ordered gameplay effects, raw-state results, picture provenance, forbidden writes, and exact stopping boundaries.
What Is Actually Implemented
The clean engine and SDL host now execute the optional entry-card sequences for
$MAINS01, $MAINS02, and $SIDES00; the due-event disabled-row publication
on daytime Main Street; and the ordinary $MAINS02 ordinal-zero route back to
$CITYS01.
The exceptional patrol state and unproven handbill consequence remain closed. The next work returns to the central MSG owner census: choose high-value non-combat ordinals, reuse the shared machinery where the bytes actually do, and continue turning the city from a corridor into the original state graph.