Playable version of Mini-Zork II

When the Infocom source code was leaked, that included an almost complete version of the unreleased Mini-Zork II. Everything is there, but it has some game-breaking bugs. This seemed like a nice project for learning about ZIL, so I spent quite a bit of time testing the game and fixing bugs along the way.

But since it was based on the now defunct “The ZIL Files” project (which was refactored into “The Infocom Files”), it contained a whole bunch of other games, and it wasn’t very convenient to work with. So a few days ago I decided to start over, still using my old changes for reference but with the benefit of hindsight and a better understanding of ZIL.

So if anyone wants to see what a Mini-Zork II might have looked like, my version can be found at [GitHub - eriktorbjorn/minizork2-renovated]. I haven’t subjected it to proper testing yet, but I have fixed a couple of bugs along the way. Some of them are still present in the full version of Zork II!

The bad news: When compiled with ZILF 0.9 (and the abbreviations it generates) the game file is still 54,860 bytes. It’s smaller than the original (buggy) data file, but probably still much too large to run from a C64 tape which was kind of the point of Mini-Zork I as I understand it. Better abbreviations may get the size down a bit, but I don’t know how much. My last few commits were to save space, but that only came out to a pathetic 60 bytes.

I almost posted this in Infocom Game Mods - 2021 Friendly Versions because this version of Zork II removes both the Bank of Zork and the Oddly-angled rooms. But that would have been just silly. :stuck_out_tongue:

7 Likes

I’ve been told that the magical size limit for building it as a single-file game with Ozmoo is 53,504 bytes.

Commenting out the bit in JIGS-UP that deals with NPCs dying, and the bit in V-WALK that handles FEXITs like “(NORTH PER MAGNET-ROOM-EXIT)”, neither of which are used in this version, brings it down to 54,794 bytes.

I’m running out of ideas. I don’t want to remove things that are actually used, e.g. the OOPS command. Maybe better abbreviations is the only realistic hope?

Almost 1300 bytes seems a bit steep to save with better abbreviations alone.

I can only get it down to 54,120 with better abbreviations.

mini2_freq.zap.txt (6 KB)

2 Likes

In SYNTAX.ZIL there are four verbs that seems like debug-verbs:

<SYNTAX \#RANDOM OBJECT = V-RANDOM>
<SYNTAX \#COMMAND = V-COMMAND-FILE>
<SYNTAX \#RECORD = V-RECORD>
<SYNTAX \#UNRECORD = V-UNRECORD>

If I remove these and the four ROUTINEs they call (only used here). Then the ATOM P-NUMBER was only used by V-RANDOM so I rewrote the ROUTINE NUMBER? to always return <RFALSE>. This means that the parser no longer can parse numbers but I don’t see that the game uses numbers anywhere.

Anyway, doing this and using the abbreviation file above I get the game to 53.884 bytes. 380 bytes left to go…

1 Like

If I remove the two calls to NUMBER? and then removes the routine NUMBER? completely it saves an additional 32 bytes. The file is now 53.852 bytes.

Removing the <GLOBAL P-NUMBER 0> and the two <COND> that refers to P-NUMBER saves additional 26 bytes. The file is now 53.826 bytes.

Yes, those are debug commands:

#RANDOM initializes the random seed so that you get predictable random numbers. (Well, at least predictable for your current Z-Machine interpreter.)
#RECORD and #UNRECORD starts/stops recording the commands you type to a file.
#COMMAND replays the recorded commands.

Very useful for testing, since recompiling the game renders your old savegames invalid. I think they’re present in at least most released versions of the Infocom games.

How do you feel about the $VERIFY command?

If you “fake it” and rewrite the V-VERIFY as:

<ROUTINE V-VERIFY ()
	 <TELL "Verifying..." CR "Correct." CR>>

you save 22 bytes. File is 53.804 bytes.

If you remove the routine and command completely the file is down to 53.768 bytes.

Note: This is if a 512 byte stack is enough. Ozmoo uses a 1024 byte stack per default, but I think Infocom z3 games typically work with 512 bytes.

If the aim is getting a version to run on a C64, and be loadable from tape, you can remove the Restart verb, since it’s not supported anyway.

I’m a bit hesitant about removing things that can be triggered by the player, but it should be possible to use conditional compilation to enable/disable features if that’s desired. I’m not entirely sure of the syntax, but I tried something like this as proof of concept just now:

In mini2.zil, I added <SETG ENABLE-DEBUG-VERBS? T>, and then I made the syntax definitions and routines conditional like this:

%<COND (,ENABLE-DEBUG-VERBS?
'<ROUTINE V-COMMAND-FILE ()
	 <DIRIN 1>
	 <RTRUE>>
)>

This is a bit outside the scope of what I was planning to do, but of course anyone can fork the project. In the meantime, I’ve committed a few more fixes/changes for some more tiny savings.

1 Like

Here is a couple of strings you can replace with constans. Not much saved (66 bytes).

<GLOBAL TALKING-TO-SELF "Talking to yourself is a sign of impending mental collapse.|"> ;"28 bytes"
<GLOBAL NOUN-MISSING "There seems to be a noun missing in that sentence!|"> ;"20 bytes"
<GLOBAL THERE-IS-NOTHING "There is nothing "> ;"8 bytes"
<GLOBAL STEEL-CAGE-FALLS " the sphere, a solid steel cage falls "> ;"8 bytes"

With ZILF 0.9 it’s 54.706 bytes.
With ZILF Beta (next version) it’s 54.354 bytes.
With Russotto’s (from higher in thread) it’s 54.036 bytes.
With @mulehollandaise python-script it’s 54.382 bytes.

Here is a list of strings of more than 14 characters and their frequency (if there is more...)..
        .FSTR FSTR?1,"Talking to yourself is a sign of impending mental collapse."        ; 2x, saved 59
        .FSTR FSTR?2,". To the east is a "        ; 4x, saved 57
        .FSTR FSTR?3,"othing happens."        ; 5x, saved 56
        .FSTR FSTR?4," crystal sphere"        ; 5x, saved 52
        .FSTR FSTR?5,"There seems to be a noun missing in that sentence!"        ; 2x, saved 50
        .FSTR FSTR?6,"There is nothing "        ; 4x, saved 48
        .FSTR FSTR?7," the center of th"        ; 4x, saved 45
        .FSTR FSTR?8," under the door."        ; 4x, saved 45
        .FSTR FSTR?9,"s to the ground."        ; 4x, saved 45
        .FSTR FSTR?10,"You don't have "        ; 4x, saved 45
        .FSTR FSTR?11,"he Wizard of Frobozz "        ; 3x, saved 42
        .FSTR FSTR?12,"nd ""In Frobs We Trust""."        ; 2x, saved 40
        .FSTR FSTR?13," of the volcano"        ; 4x, saved 39
        .FSTR FSTR?14," and evaporates"        ; 4x, saved 39
        .FSTR FSTR?15,". The only exit is "        ; 3x, saved 38
        .FSTR FSTR?16,"You can't turn that"        ; 3x, saved 38
        .FSTR FSTR?17," the sphere, a solid steel cage falls "        ; 2x, saved 37
        .FSTR FSTR?18,"ern half of the room"        ; 3x, saved 36
        .FSTR FSTR?19,"he topiary animals "        ; 3x, saved 34
        .FSTR FSTR?20,"The door is locked"        ; 3x, saved 34
        .FSTR FSTR?21," in your direction"        ; 3x, saved 32
        .FSTR FSTR?22,"floating in midair"        ; 3x, saved 32
        .FSTR FSTR?23," blocks your way."        ; 3x, saved 32
        .FSTR FSTR?24,"n the floor is a "        ; 3x, saved 30
        .FSTR FSTR?25," in the aquarium"        ; 3x, saved 28
        .FSTR FSTR?26,"moke curls from "        ; 3x, saved 28
        .FSTR FSTR?27,"The cloth bag i"        ; 3x, saved 28
        .FSTR FSTR?28," doorway leads "        ; 3x, saved 26
        .FSTR FSTR?29,"mbedded in the "        ; 3x, saved 26
        .FSTR FSTR?30," receptacle is "        ; 3x, saved 26
        .FSTR FSTR?31," passage leads "        ; 3x, saved 26
        .FSTR FSTR?32," and disappears"        ; 3x, saved 26
        .FSTR FSTR?33,"your bare hands"        ; 3x, saved 26
        .FSTR FSTR?34," whirring sound comes from "        ; 2x, saved 25
        .FSTR FSTR?35," Lord Dimwit Flathead "        ; 2x, saved 23
        .FSTR FSTR?36,"g snaps at you viciously"        ; 2x, saved 22
        .FSTR FSTR?37,"s a strange black sphere"        ; 2x, saved 22
        .FSTR FSTR?38,"A beautiful unicorn is "        ; 2x, saved 22
        .FSTR FSTR?39,"dangles from the basket"        ; 2x, saved 21
        .FSTR FSTR?40," the Black Crystal, "        ; 2x, saved 21
        .FSTR FSTR?41,"The Wizard appears, "        ; 2x, saved 21
        .FSTR FSTR?42,"d!"" The demon "        ; 2x, saved 21
        .FSTR FSTR?43," the bottom of the "        ; 2x, saved 17
        .FSTR FSTR?44," in that sentence"        ; 2x, saved 15
1 Like

Thanks! I’ve added those four.

1 Like

After another few changes, I’m now down to 54,578 bytes with ZILF 0.9’s default abbreviations. I haven’t tried building the beta version of ZILF, or figured out how to generate the better abbreviations.

Edit: 54,440 bytes now. I cleaned out some code from GOTO dealing with vehicles in a more general way than was needed by this game.

Edit: 54,380 bytes now. It seems ZILF 0.9 doesn’t always generate the exact same abbreviations, so your mileage may vary slightly.

Edit: 54,352 bytes, and now I’m at least temporarily out of ideas on how to save more space. Sherlock uses <SETG COMPACT-VOCABULARY? T> to “Save a byte/word”, but that obviously requires parser changes way beyond my pay grade, and I’m not sure if it even works right in v3 games. Interestingly, Sherlock and Mini-Zork II are the only games to use ```<SETG COMPACT-SYNTAXES? T>" to “Seriously cram syntaxes”, so apparenly that feature works.

Edit: The documentation from the PAX drive confirms that COMPACT-VOCABULARY? “won’t work in ZIP games”. So that idea is out.

Edit: 54,280 bytes now. The game no longer has the ability to parse the time of day, e.g. “9:45”. There was no reason at all to keep that in my opinion.

2 Likes

Using the different abbreviations, the file now compiles to:

Standard Zilf 0.9                54.440 bytes
mulehollandaise's python script  54.098 bytes (pl)
Zilf Beta-version                54.096 bytes (beta)
Russotto's abbr. file            53.776 bytes (mr)

mini2_freq_pl.xzap.txt (6.4 KB) mini2_freq_beta.xzap.txt (6.1 KB) mini2_freq_mr.xzap.txt (6 KB)

4 Likes

With the latest changes I can get it down to 53,478 without hacking out the debugging verbs by compressing the pre-actions table. Instead of having it mirror the actions table, I have it as a list of VERB/PRE-ACTION terminated with -1,0. Unfortunately this requires either hacking ZILF or directly modifying the ZAP intermediate file; I opted for the latter. I also generated a new abbr table

squashpre.diff.txt (2.0 KB)

mini2_freq.zap.txt (6.0 KB)

3 Likes

Neat trick, but a bit outside of my scope. I’ve made the debug verbs a compile-time option (borrowing a trick from Suspect). They’re enabled by default, of course. Disabling them and using your new abbreviations brings down the size to 53,490 bytes. Of course it would be nice to slim down the game without having to disable anything, but now I really think I am running out of obvious ways to do that…

Maybe I spoke too soon, because I found some other places to save some space. Unfortunately I also found a few bugs, but fixing them only added a couple of bytes. I’m down to 54,148 bytes with ZILF 0,9’s abbreviations. If I use Matthew Russotto’s abbreviations above, it shrinks to 53,508 bytes.

So close!

2 Likes

I havn’t looked if you used it, but you can save 1 byte each by replacing CONSTANTs with GLOBALs. I guess that is because addressing is different. Be sure that the CONSTANT is in use, though. ZILF removes unused CONSTANTs during compilation but noy unused GLOBALs.

OK, but it’s 53378 with your latest changes. Also here’s a ZILF patch to do the pre-action thing by setting COMPACT-PREACTIONS?

zilfch.txt (1.8 KB)