The Trebor Chronicles

Chapter 2: More infrastructure

In the next session, I mixed infrastructure, workflow, and coding changes together. The architecture needed to start breaking out into individual handlers, so that the code could react differently depending on where it was in the game. If Moose is in Boltac’s Trading Post, it needs trading logic and decision-making. If it’s in the Maze, it needs to focus on navigation. Instead of continuing to grow one enormous monolithic .py script, I started separating the game into individual modules that were responsible for different situations.

I also introduced robust logging. The logs are surprisingly important because I can give them back to ChatGPT for analysis. When the game hangs, I can tell Moose what I observed, give it the log, and it can work through the steps leading up to the failure and help determine what went wrong. This is becoming one of the more useful parts of the whole setup: the program not only needs to play Wizardry, it needs to leave enough evidence behind for me to understand what happened when it fails.

A Better Workflow

I also wanted to speed up the development workflow. Until now, Moose would generate or modify files, I would download them, copy them onto my Mac, and then run them. That got old quickly.

So I moved everything to GitHub and gave Moose access to the repository. My workflow became:

I make feature requests. Moose makes the script changes directly in GitHub. I do a git pull on the Mac and run the changes.

That may sound like a small improvement, but it changed the rhythm of the project considerably. I could describe what I wanted, Moose could make the changes, and within a few seconds I could be testing them.

Architecture diagram

Starting to Tell a Story

I also added a bunch of smaller features. Character names are now randomly generated from fantasy-style first and last names, with one important rule: about half of them should be ridiculous. Thus a perfectly respectable adventuring party might contain someone named Talen Gorn standing beside CheeseBlade.

More importantly, I started recording a narrative as things happen.

When a new character is created, the program doesn't merely record something like CHARACTER_CREATED. It can turn that into a little piece of story: “FooBar wandered into town,” or “Talen Gorn returned home from abroad, looking for a new adventure.” The idea isn't merely to have ChatGPT play Wizardry. I want it to generate an engaging account of what happened while it was playing.

This is also where I expect the blog itself to start changing. As the code matures, there should be fewer posts about Python modules, logs, screen recognition, and keystroke injection. Slowly, Game of Drones should morph into the adventures of Moose in the Proving Grounds of the Mad Overlord.

At least, that's the plan.

The Robot Is Bigger Than the Cube

One thing that has surprised me is how much infrastructure is required for such a tiny game. Wizardry itself is basically a three-file package. The machinery I’m building around it is already vastly more complicated.

But think about a Rubik's Cube.

The cube is a small, simple object. Now imagine building a robot that can solve it. The robot is going to be much bigger than the cube and much more complicated. It needs a way to see the cube. It needs to understand what state the cube is in. It needs motors to manipulate it, logic to decide what move to make next, and safeguards so that it knows when to stop instead of happily twisting until it breaks something. It needs a power supply. It may need cooling or lubrication. And when something goes wrong, you'd probably want some way of finding out what the robot thought it was doing at the time.

That's essentially what's happening with this Wizardry project.

Wizardry may be the little cube sitting in the middle of the table.

I'm building the robot.Cube-solving rig