Adventures in AI

I realize this post may raise some people’s hackles. So before I describe what I’ve been doing, I need to insert a disclaimer.

I would never use artificial intelligence for creative work, for several reasons. First, creative work is fun! Why would I deprive myself of the fun? Second, I wouldn’t expect an AI to produce work that’s as good (or as deeply personal) as what I would produce myself. Third, AI makes mistakes, and they can be hard to catch. Fourth, large language models were trained on human writing, so there are ethical issues.

That said, there are certain tasks for which AI may be vastly more efficient than a human would be. Today I’m here to talk about one of those.

If you want to reply to this post by ranting about AI, go right ahead. I may respond by ranting about the internal combustion engine, which has had a greater environmental impact than AI ever will. But my goal here is not to stir up controversy! I just want to describe this week’s project and what I’ve learned from it, on the off-chance that a few game authors may find the information useful.

On with the show…

Back in 1999 I released my first text game, “Not Just an Ordinary Ballerina.” It was a large, complicated, and rather cruel puzzle-fest, written in Inform 6, which at the time was state-of-the-art.

At some point while switching to a new computer, I lost the source code files for Ballerina, so there’s my first tip for y’all: When switching to a new computer, make sure you keep the backup copies of creative work! Today, Ballerina exists only as the compiled ballerina102.z8 file. I know of two bugs in that version, and those bugs will never be fixed. Also, this morning Claude spotted a third bug in the original that nobody ever reported. There’s a location where LISTEN produces an endless loop.

For a few years, a guy who went by the name Radical Al (that’s short for Albert, or maybe Alvin) was one of my beta-testers. At some point Al thought it might be interesting to port Ballerina over to the new Inform 7 language. He never got very far with the project, for obvious reasons. Testing a game of any size to learn about all of its possible permutations would take months, if not years.

This week, however, it occurred to me to wonder if perhaps an AI could decompile the .z8 file for Ballerina and reassemble it as an Inform 7 game. This would not be creative work, and also it’s my own game, so I can do with it whatever I like. I asked Anthropic Claude to give it a go.

I have now learned quite a lot about the pros and cons of this attempt. If you’d like to try doing something similar with an abandoned game, what I learned may help streamline your process. Heck, you can even try it with Ballerina if you like! Maybe use GPT instead of Claude. We could compare the results.

In no particular order, here are the main things I learned.

Claude was able to get the I7 Standard Rules and compiler from Graham Nelson’s github repository. Using these tools, it was readily able to write I7 code that would compile successfully. However, it never consulted any tutorials on how to write games using I7. As a result, its code bears very little resemblance to the usual style of Inform source text. In retrospect, I should definitely have included explicit instructions about this in my prompts. I have had to hand-hold Claude to make the source text more human-readable. Nor did it take advantage of any of the I7 extensions that might have streamlined its code.

Claude’s code style is strongly influenced by traditional object-oriented coding. For instance, in one of its first attempts it included a Chapter of declarations of all of the in-game things. I had to explain to it that the Inform compiler handles this chore automatically. Explicit declarations are rarely needed. It created a wilderness of “Instead of doing something” rules, where more explicit rules such as “Instead of taking the statue” would be more efficient. I had to instruct it about how to produce blocked-exit messages for whole classes of rooms rather than iterate those messages explicitly for each room (such as the rooms in the mirror maze).

Its code declared all of the properties (both true-false properties and numerical properties) for every object in the game rather than restricting properties to kinds where they would be useful, such as the property of-color for the six balloon objects. There’s also a mess of numbered global variables, such as global-14. As we’re finishing the project, I’m going to tell it to rename all of those globals based on what they’re used for.

The only way to find issues of this sort is to read through Claude’s source code. This is not easy, both because the file is very large and because the connections among blocks of code are not organized in the way a human author would organize them.

Using the walkthrough built into the original .z8 file, Claude has been able to test whether its output for the I7 rewrite is that same as the output of the original game. However, while doing this it neglected to try most of the wrong inputs that a human beta-tester would naturally try, either maliciously or through simple confusion or inadvertence. I had to point out this omission in its internal test routine. It is now testing wrong command inputs, but whether this process will iron out all of the remaining bugs is unknown. (See the footnote at the end of this post.) I certainly wouldn’t ask human testers to work their way through a very large and very old game, so it would be fair to say that the finished I7 version will be untested, even when I release it. Given how inhuman Claude’s source text is, it’s not entirely clear that I would be able to fix a bug even if a human player reports one.

Some of the default library outputs in I6 are not the same as the default outputs in I7. I should have told Claude to list the differences for me and let me choose whether to revert to I6 style or keep the I7 outputs. In general, the I7 outputs are a bit nicer, so the AI was using extra effort to make the game slightly more old-school in places where that wasn’t necessary.

In retrospect, I should have asked Claude to produce new source code for the game in Inform 6 rather than Inform 7. This would surely have been faster and less error-prone. Speaking of “faster,” I did spend $100 for more usage bandwidth, in order to complete the project within a few days. It would have dragged on for a while if I hadn’t done that, because this is a pretty intense project for an AI to undertake.

Nonetheless, I feel the project has been worthwhile. If nothing else, the next time I write a game I will consider using an AI as a first beta-tester. And I will write better prompts. If I give it specific instructions about trying to break things by using absurd inputs, quite possibly bugs will be spotted that human testers might miss. I worry that with a large game some human testers may burn out before reaching the latter part of the game. An AI won’t burn out.

Footnote: As Claude tries to tidy up its work by doing a final run-through, it finds new bugs. Specifically, it reports, “In one run, moving southwest out of the Travel Agency sometimes lands in a different room than the original’s walkthrough.” Since that door is not randomized, a bug of this sort could almost never occur in a human-coded game. Claude is also finding that in some run-throughs the ending is never triggered because certain items are disappearing from the player’s inventory. Again, this is something that would be very unlikely to occur in a human author’s game, because there’s no reason why inventory movement would be randomized or inconsistent. I’m suspecting that Claude’s approach to coding is just not reliable. (It’s an AI. It makes mistakes.)

Questions and comments are welcome. As I said, I’m not trying to stir up controversy. I’m not going to get into any back-and-forth arguments about AI. I’m not going to try to defend my usage. If you’d like, I’ll defend my continued use of a gasoline-powered automobile. That would be just as productive a discussion.

Interesting project. My early fumblings with inform are similarly unpreserved.

There are a few more bugs in Not Just an Ordinary Ballerina that I have found but never reported.

I’m not surprised. There were seven or eight testers (whose names are listed in the About text, IIRC), but nobody could test everything.

Was there an engineering reason you chose to decompile and transcode to i7 knowing that there were flaws in the i6 source and thus the compilation?

I’m not sure what an engineering reason would have been. I’m not an engineer. I was curious whether a new version might allow me to get rid of the remaining bugs, but it appears just as likely the new version will introduce new bugs, so that turns out not to be a good reason. A creative reason would be that now I can perhaps add a few features (by writing them myself, not with AI) that the original ought to have had, but didn’t.

A community reason would be to find out whether this might be a process other authors could use when faced with a similar archive problem. It’s also a way of learning just how different an AI-authored game would be from a human-authored game in terms of the code itself.

That makes sense to me and I was thinking in a broader sense of the phrase. Like practical motivations for making the jump from I6 to I7. But from what you said this was more of a creative and exploratory effort.

Now I find myself wondering how well an AI could convert some backend C++ code I’ve written into i6 or i7 to take advantage of Inform’s pre-existing parser/world map functionality. Note that I have no experience writing Inform code, the back end code I’m talking about is some of the most complex code I’ve written in C++ and seems likely to be more complex than I get the impression is considered reasonable for custom logic in Inform, and my knowledge for making interface code in C++ is limited to printing stuff to the screen and taking keyboard input and I have no interest in building a parser from scratch.

Offhand I’d say it would probably be wise to start by learning about how I7 does things. Depends on what you want to accomplish, I suppose.

I’ve been trying to port a couple of games of mine to some extremely new system (namely: Stefan Vogt’s Arcturus). I must say the effort was minimal and the results… not bad.

Arcturus itself has been made with the aid of Claude, so a nice Claude.md is present in the Git repository. This must have sped things up, but nonetheless the AI has read all the manual several times before giving me a proper conversion.
The conversion itself was done in several attempts at debugging code, as the first try was by far NOT correct. Arcturus is, in certain ways, a nice in-between of I6 and I7, with absolutely no spoken language feat but with clearer declarations than I6, and in the first trials Claude (I guess) imagined a language where there was none.

This said: the process of fully converting A1RL0CK took a couple of evenings. The conversion is not 100% perfect and it will need thorough testing by real people before one can consider it done. But I leave the timing there for you to see. It would have taken me a month or two to do the same, messy conversion.
Corrections and tweaks, especially, are extraordinarily convenient. Imagine a repeated bug. Or a misinterpretation of the rules popping up in any given kind of code (I.e. how to handle blocked exits). Those stand corrected in a couple of minutes. All of them together. In a nice, ready to download file.

I’m totally against using AI for creative purposes. It’s stealing work from others, first of all, and then the result is always kinda lame, unless you are impressed by “nice drawings”. But as an aid in coding, well.

Sounds like the same thing that happened when cameras first, and Photoshop a century later, came out. Painters and designers went crazy I guess. Pictures especially were universally loathed. Fact is, now and back then, a software will never replace human qualities. It’s just a tool and, if we get to be able to use it without destroying Amazonia, we should. I mean, why not? A couple of generations of cousins with PS thought the app was enough to turn them into good, if not great designers. Time has proven them wrong. :slight_smile:

Ah! It’s important to state that, in order to code a game with AI, you NEED to know the language and how to code. Otherwise I suppose you have to simply trust someone who you don’t know at all, telling you how to live. Times and times again, to give an example, Claude ended up in a loophole. Without my intervention it would have still been stuck in there, changing the same variable and back again forever.

Writing software is an artistic endeavor and takes a lot of creative energy. It pains me when I read things like this.

Sorry, I’m not following you.

Porting a game to another system, with the aim of making it completely identical, is an artistic feat?

“But is it art?” is as old a debate as “Is it interactive fiction?” :slight_smile:

I think you’re definitely right that you’re very likely to introduce more bugs than you fix. The engineering approach would be to use one of the Z-code to Inform 6 decompilers to generate an Inform 6 source file that compiled to a Z-code file that was byte-for-byte identical with the original (apart from the serial number in the header) which should be possible, perhaps with Claude’s help.

If you can get that far, you could then try to find the smallest possible change (again, maybe with Claude’s help) that fixed the bugs. But without the original source code there’s so much lost information about how the game is meant to work, that doing that is not easy.

My limited experience with Claude Code is that writing prompts is surprisingly similar to writing the code yourself. As with playing chess, you have to think two or three steps ahead, or you’ll box yourself in.

I suspect you’re right. I doubt I’ll ever try to use AI for authoring a new game, for exactly that reason. At the very least, I should have given Claude much more detailed prompts about how to write human-readable I7. I could have instructed it to read my Inform Handbook and be guided by the code examples there. I still feel this was a useful experiment, because I learned a few things.

This depends on the context window and the model though. Anthropic’s models vary here significantly. I am using Claude Fable 5.1 for most of the work on Arcturus (the first lines were written with Fable 5). Since the compiler and the library now have a very solid foundation, that mostly involves bug fixes reported from adopters or rolling out new features, like the lighttopology granule very recently. Arcturus has evolved into a pretty significant project now, so the AI needs to have a very good understanding of the language and the library itself.

Fable itself is suitable for what I do with Arcturus, it might be overkill when you want to port your game with it. My recommendation would be that for the next game you want to port over, go for the Claude Opus 5.5 model. It is very close to Fable in coding but uses way less tokens. The way I would do it: explain Opus on the web that you want to port game X and that it shall create a Claude.md file for it, tell it to ask questions if it has any. Place the file then in the conversion directory. Place the Arcturus .md documentation files in a sub dir, e.g. docs. Point Opus to the Claude.md in the project root but also to the docs and tell it that all it needs to starts developing in the language can be found there. Ask it to do a conversion plan and put it out in a progress file like progress.md. And it will define a roadmap with steps. Then execute step by step. That works better than the “Hey let’s be funny and let’s do everything at once” approach.

If you do this, your next result will transition from …not bad to: wow this is really good.

The last thing you can do is having the AI act as a playtester to uncover conversion or logic bugs (if any). The best way to do it is that you tell the AI to put itself into a role of a human Infocom adventure playtester. I am usually going for Amy Briggs (sorry Amy!). Tell it to do the testing in --console or --headless Actaea. I used this method after I converted Hibernated 2 from Inform to Arcturus. It didn’t find conversion bugs, but it found 4 bugs, that after investigation, were also existing in the Inform source.

Hope this helps!

Actually, that’s what I’ve been using all through this process.