Devlog #055 - The River Is a Road
The docks looked like another city menu. They were not.
Behind $DOCKS00 is a compact transportation system that reads the active
city record, offers routes that really exist from that port, charges the
party, advances time twice, replaces the current city data, and hands control
to a separate arrival controller. Completing it connected several systems we
had previously reconstructed in isolation.
Five Copied Owners, One Sailing Family
The original contains five sailing handlers. The first four correspond to visible destinations; the fifth exists but is not published as a selectable row by the current presentation.
Comparing their bytes showed that they are copies of one algorithm. They vary
only in the fare-record address, the destination word in DARKLAND.CTY, and
relative call displacements caused by their positions in the overlay. That
gave us the right clean model: one parameterized sailing action, not a set of
city-specific routes.
Each city record holds as many as five boat connections at offsets
+4Ah..+52h. Missing routes remain absent. The game is building the menu from
world data, just as it builds other city rows from city flags.
Paying in Florins, Groschen, and Pfennigs
The fare is not flattened to a modern integer and subtracted casually. Darklands keeps its three denominations and performs the original borrow sequence:
- 12 pfennigs borrow from one groschen;
- 20 groschen borrow from one florin;
- the three words are written in the original order.
An unaffordable fare takes a different route. The game advances one hour and
can mention selling mounts to reduce the price. That text is useful evidence
for the recurring item-definition mask 2000h, which strongly correlates
with horses or mounts, though the raw flag remains conservatively named until
the data relation itself proves the vocabulary.
The successful route subtracts the fare before the voyage starts.
Two Clocks, Not One Travel Duration
A paid voyage consumes two separate random calendar effects.
First, RNG(3)+1 chooses a wait of one to three hours. $DOCKS00.MSG card 9
is displayed over the retained dock picture while the party waits to cast
off. Only after acknowledging that card does the calendar advance.
Then the destination city and description records replace the active
DARKLAND.CTY and DARKLAND.DSC data. A second random draw selects 48 to 95
hours of sailing.
The total is therefore 49 to 98 hours, but the two steps must remain ordered. Combining them into a convenient “travel for N days” operation would lose the original acknowledgement boundary, RNG order, and calendar side effects.
This work also exposed a valuable calendar boundary. A second consecutive voyage crossed August into September and entered the monthly world-maintenance owner. Until that owner was certified, SDL correctly stopped instead of pretending a same-month helper could handle the transition. The calendar work later closed that general rollover path.
Arrival Is Its Own Controller
The sailing owner publishes raw state 005Ah, which enters $ENTER00.
The original loads PICS\XRIVER.PIC and offers a new set of choices:
- disembark outside the city;
- pay the wharf toll;
- persuade the wharfmaster;
- sneak ashore;
- invoke a saint;
- remain aboard and continue to another connected port.
This corrected an earlier visual assumption. The arrival screen does not
retain the previous city or dock picture. Runtime pointer bytes established
XRIVER directly; the screenshot merely corroborated it.
The guarded and besieged variants come from city flags. Toll admission uses local reputation and events. Persuasion uses the leader’s Charisma and Speak Common with reputation adjustment. Sneaking combines party Streetwise and Stealth before its success or combat result.
The onward-voyage choices form a particularly satisfying loop. They advance
time, load the newly selected city and description records, and republish
state 005Ah. The boat can therefore continue from port to port through the
same original controller.
What Is Implemented
SDL can now execute the paid voyage for every published dock destination,
including exact fare subtraction, the one-to-three-hour departure card, the
48-to-95-hour voyage, city and description replacement, hourglass/calendar
effects, and the $ENTER00 arrival presentation. It can also follow the
published onward-boat routes generically.
Several arrival choices are independently implemented, including land approach, toll acceptance and rejection, and persuasion outcomes. Uncertified saint effects and combat-bearing failures remain explicit boundaries.
The important result is larger than “boats work.” The river network now uses the same city data, calendar, money, event, MSG, and redispatch mechanisms as the rest of the game.