This is an experiment to try adding support for the TI-99/4A Scott Adams games to ScottFree. It doesn’t actually work, but still gets further than expected.
I made a repository here with the GlkTerm source included, a makefile and an Xcode project. I have only tried building on my M1 Mac. It is a cut-down version of the Spatterlight ScottFree interpreter, using the GlkTerm library, with all support for graphics and the ZX Spectrum and C-64 versions removed. Fragments of the Bunyon interpreter are also sprinkled here and there. I’m afraid it is not in a very clean or readable state.
Some games, like Adventureland and the other first four SACA games seems to work pretty well, while others, such as The Count and Savage Island, break at the first move. I haven’t tested any of them extensively, though. It reads games in the .fiad format only. (It also still plays TRS-80 format games, but that’s not what we are testing here.)
The main problem is that the action format is different, and that the TI-99/4A format allows more conditions and commands per action than the TRS-80 format that ScottFree uses natively. I’ve tried working around this by simply cutting up the too-long actions into several shorter ones and inserting extra continue commands to glue them together. This is a gross hack and it isn’t surprising that it doesn’t work perfectly, but many of the more severe problems seem to have other causes. I wonder if the differences in the TI-99/4A continue command (TRY) are to blame.
I don’t really expect to get much further with this. I’m posting it here in the hope that somebody will find it interesting, and perhaps even be able to explain why and where it breaks. Any ideas for alternative approaches are welcome.
I’ll be sure to read this in great detail. I’ve gotten started writing a terp for the TI-99/4A files at least once, so this is super interesting to me at least.
In my case, I abandoned the effort due to a combination of not finding good documentation and not being able to figure out everything on my own, and it just being too much work, considering the end result. I seem to remember the actions being very different, removing some annoying old constraints while adding new ones.
Don’t get me wrong. I’d like to get further since it’s a slightly more capable engine than the original TRS-80 heritage one, and also investigate if there’s a connection to the later “v2” data files that later QuestProbe games use. (They may be completely unconnected, of course, but Scott Adams seems to have been pretty enamoured with his games on the TI-99.)
I don’t know if this is relevant, but I made a Scottkit game, and when playing it using Scottkit player, I noticed 2 things:
The command gameover still has one extra turn before really ending the game. It maybe my fault, but it seems that the game still takes user input before ending the game, even though there’s no more processing of said input.
The random value seems to be called once per turn, rather than once per command. So, occur 10% and occur 50% either occurs both at the same time, or only 50%. I’d think that they should computed independently.
This is the behavior I noticed from ScottKit. I haven’t tested it with ScottFree.
Just as an example of what is broken, here is beginning of The Count in this build:
Welcome to ADVENTURE: 5 'THE COUNT'. Dedicated to Alvin Files.
I see I was put to bed. I've overslept & it's after noon!
I've a hunch I've been robbed!
I see I was put to bed. I've overslept & it's after noon!
A bell rings somewhere: 'DING-DONG'.
Tell me what to do ?
Note the repeated message. Also, the game will start in darkness. Here is the correct behaviour, from Bunyon:
Welcome to ADVENTURE: 5 'THE COUNT'. Dedicated to Alvin Files. I see I was put
to bed. I've overslept & it's after noon!
What shall I do?
Looking at the actions (decompiled with Bunyon), there are a lot of statements like this:
msg_002; # "I see I was put to bed. I've overslept & it's after noon!";
drop itm_000; # Sheets
That are not meant to fire on the first turn, but do anyway.
I suspect that it isn’t completely on-topic exactly, but those are interesting points.
That sounds wrong, but maybe there’s a sort of “do you wish to play again Y/N” input expected there. I need to do a bit of investigation to be sure.
That sounds even more wrong. The original BASIC source code generates a new random value every time a new action is evaluated at least: 380 IF NV(0) = 0 THEN F = 0 : IF RND(100) <= N THEN 400 ELSE NEXT X : GOTO 990
That was my first thought too. But it seems that most of the flags that are checked are set by earlier actions, so my hunch is that either the order in which the actions are checked is wrong, some opcodes are broken in translation, or that the TI-99 engine has a special mechanism to stop actions from being considered. As I mentioned, I still don’t quite understand what the parameter of the TRY command does.
I really should improve the debug tracing output of both Bunyon and ScottFree so that the differences can be seen more clearly.
My old notes weren’t a great help unfortunately. What I did, was to compare the binary data of the TI-99/4A version of Ghost Town with the TRS-80 version. I couldn’t get Bunyon working properly for me, or I would have sprinkled the source code with printf() statements until i understood it.
I made some more fixes and added support for disk image format and homebrew games.
I think the homebrew games expect the inventory to always show in the upper window, as they have no INVENTORY command. Also, it would be nice if ScottFree showed the startup screen text, like Bunyon does.
EDIT: I’m giving up again! Turns out the TRY mechanism is a lot more intricate than I had hoped, which breaks homebrew games like the Colossal Cave port. I have no idea how to implement it using the current approach.
I guess I could just add Bunyon to Spatterlight instead, but then Stu George would first have to release it under a GPL-compatible license.