The Trebor Chronicles

Chapter 9: Rerollapalooza

After getting combat working, we tried it out. It worked, but there was a navigation error that crumbled everything. I am impressed with Moose's postmortem.

In the last run, combat worked well, but there was a navigation disaster. Look at ./latest.log and tell me if you spot it. Don't make any code changes, just do a post-mortem.

Yes. The navigation failure is very clear, and it is much worse than an ordinary wrong turn.

The run is healthy enough during exploration. We start at (0,0,1), move north to (0,8,1), east to (3,8,1), south, and eventually reach (3,3,1). There is one small navigation loop at (3,5,1)d, a, d, a—but the loop detector notices it and successfully escapes by moving south. So that part actually did what it was supposed to do.

The disaster begins after the 100-key budget is reached. The controller switches to exit mode, runs from combat, and then tries its “shortest mapped route toward the exit.” Within only a few moves, that alleged route sends the party into walls:

EXIT +008 ... Advance along the shortest mapped route toward the exit [MAZE] blocked move: restored position=(2, 3, 1); direction=1 recorded as WALL

It then abandons shortest-path navigation and switches to “reverse the recorded outbound path.” That immediately hits another wall, twice, then another wall in a different direction.

At that point the fallback has effectively lost its mind. The log becomes an enormous repeated sequence of:

d, d, w d, d, w d, d, w ...

all labeled “Turn right while reversing the recorded outbound path” and “Fallback: reverse one recorded outbound step toward the entrance.” It performs that pattern dozens of times without any evidence that it is getting closer to the entrance.

That bad exit navigation has catastrophic consequences. Instead of getting out, the party wanders long enough to trigger another encounter with Scruffy Men/Zombies. It repeatedly tries to run, Cheese Beard is killed, then Boom Crowen, Aldor Light, and Isold Keldor die, Snack Fang is paralyzed, and the survivors escape only briefly. The broken reverse-path routine resumes, another encounter occurs with three Undead Kobolds, and eventually:

YOUR ENTIRE PARTY HAS BEEN SLAUGHTERED

Even after that screen appears, the controller continues emitting navigation commands—more d, w, d, d, w...—because exit mode evidently does not recognize that the party no longer exists and that normal maze navigation is no longer possible.

So my post-mortem is: combat did not kill this party; exit navigation did. The first sign of the underlying problem is that the controller's internal map/path history disagrees with the physical maze. A supposedly known shortest route immediately attempts a wall, and the supposedly reliable outbound path cannot be reversed either. Once those two sources of truth fail, there is no sane recovery strategy—the fallback just churns through recorded movements, generates huge numbers of exit-mode keystrokes, keeps exposing the party to random encounters, and never establishes whether its estimated position still corresponds to reality.

One especially suspicious clue is the transition around the second combat. Just before combat, our modeled state is (1,2,1) facing south, then we press a to turn left and combat interrupts. When the 100-key limit later arrives and we successfully run, exit navigation seems to trust its recorded coordinates/path as though combat, running, treasure transitions, blocked moves, and interrupted turns could not have desynchronized it. I would treat “our logical position/orientation is no longer trustworthy” as the primary failure hypothesis, rather than merely “the shortest path algorithm picked badly.”

And there is a second independent safety failure: once exit navigation has hit even a couple of walls on a route that was supposedly already known, that should have been regarded as strong evidence that localization was invalid. Instead the controller kept trying to navigate for over a hundred exit-mode keystrokes. The repeated wall collisions were an alarm; the system treated them as routine obstacles.

No code changes made.

We discussed this and realized that a navigation move was made, but interrupted by combat. However, the internal map recorded the move as having succeeded, and that threw all the mapping off. Moose treated this as a hypothesis, but I challenged him to test it by reconstructing the play from the log. He did this and discovered too that the R)un command (running away from combat) can end with the party in an unknown location.

So yes — you were right to ask me to reconstruct it. The log gives much more support to the interrupted-action theory than I gave it credit for. But it also exposes R)UN as another state-invalidating event that we need to keep in mind.

That is a good find about R)un. Please create a new branch called InterruptedNavigation and make two changes:
  1. Only record the movement as having happened if the move is not interrupted
  2. You will need to add some kind of "reorienting" code that gets run after R)un succeeds. I don't know how you will do it, but you do. Please proceed.

While testing this change, we started a new campaign, and hit a new bug. During character creation, Moose tried to make a Priest, but the PIETY value was not high enough, so character-creation stopped. This triggered a watchdog in the automation and it stopped. I had Moose update character-creation logic so that a character is re-rolled if the primary attribute for the intended class cannot reach 18. We spent a few iterations fine-tuning this logic, and we can now generate a strong party.

3 dice

Then we ran out of time for the day and had to merge into Main without ever getting to thoroughly test that navigation fix. But we did generate a strong party, and the party did get into and out of the maze successfully, albeit no combat. So it goes; we'll resume later.