6 January 2025

Treasure of Count Goldenwald

This is a technical entry on a recent project, being performed together with my sons Benedek and Domonkos. We are working on implementing a text adventure in retro style, aiming at 8-bit microcomputers (and possibly others). Currently, our work runs on a ZX Spectrum 48k or a Commodore 64 or PLUS-4. This time I will disclose just a very short part of the source code of the project since we have some further plans with it, namely, to continue this work to extend it towards a professional game engine.


You can start the current snapshot of the ZX Spectrum version in the above window, by clicking the ▶ button, and then wait about 4 minutes and 40 seconds. In case you are in a hurry and don't want to wait such a long time, try this link instead. It will start another ZX Spectrum emulator, Qaop/JS by Jan Bobrowski, and by using that one, you can save the game state with the button F2. (It will be very useful to avoid restarting the whole game from the beginning in the case of a failure during your adventure. You can go back to a saved state by using your mouse and move it to the very right side of the emulator window.)

On this current page, the emulator being used is an embedded version of Matt Wescott's JSSpeccy 3, similarly to a former blog entry of mine, from 2023.

The story of the text adventure comes from 1989. I presented a Christmas gift to my father by writing a text adventure as a book. It was planned that I and my brother, Zsigmond will work on that, keeping in mind that Zsigmond was very good at artistic work. Indeed, later he studied in several schools of arts, including the Hungarian University of Arts and Design, and for several years he has been working as a caricaturist.

The idea of re-creating the adventure as a retro computer game was inspired by nicely working C compiler toolchains for the ZX Spectrum and the Commodore machines. For the former, I tried the z88dk toolchain. It is wonderful piece of free software providing a very nice learning curve. I started my attempts by changing the source of a Mandelbrot Set visualizer, having the idea that the basic algorithm from the XaoS fractal zoomer and morpher could be ported to the ZX Spectrum as well. The first insights are nice, but the speed may be still too far from the expected result.

Therefore, instead of working hard on porting XaoS to the Spectrum, I set a doable challenge to achieve. Domonkos suggested that that old story with Count Goldenwald would be something fine as a first project. He already managed to finish the book version of the text adventure (presented to my father in 1989) several times, so a computer version of the game could also be a nice idea.

The first version of the game was written in Hungarian texts. I simply copied my original room descriptions from the Hungarian textbook, by changing them as little as possible, even if some details in the story looked somewhat ridiculous. But still, I wanted to keep the whole atmosphere of my childhood as I was 14, with all of its naivity.

The English version was created by uploading the C source file in a ChatGPT conversation, and with more or less success the translation was done quite quickly. ChatGPT is clever enough to separate C code and the text of the story, and to translate only the latter. In such a way, a very quick translation to an arbitrary human language is possible.

The C language allows the programmer to fine tune the code with a set of #ifdef preprocessor commands. In my case, this helped a lot to write platform dependent code in a kind of separated way. For example, the game engine begins the following piece of code:

#include <math.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#ifdef SPECTRUM
#include <malloc.h>
#endif // SPECTRUM

#ifdef C64
#include <ctype.h>
#include <c64/vic.h>
#endif // C64

This immediately shows that some headers were important for certain platforms, and some others for other platforms, while some were required for all of them. The use of #ifdefs can be a mess after a while, so one should keep in mind that with this technique it is difficult to keep large projects clearly structured. But, by using this method, I was able to port the game to the Linux terminal very quickly, and it was also possible to test the game with a fixed input (consisting of more than 200 short lines) immediately and continuously. (In fact, there is a working WebAssembly port as well, after tweaking the code just minimally.)

There are, however, some Spectrum specific parts. For example, the z88dk toolchain comes with a nice ANSI terminal emulation layer, including accented letters. This is far from being complete, but at least it is nice enough to support programming of text based adventure games. Here is a simple example of the way how one could use it. Actually, I ran into an issue with this subsystem, and posted my question to the developers. It turned out that it is related to the attribute clash problem which is a well-known limitation of the ZX Spectrum.

Another Spectrum specific part is pixel graphics. Currently, only this platform has any graphics in the game, and it is also quite limited. One scene requires 2304 bytes of data for illustrating the story in the upper third of the screen. Currently, 6 scenes are provided (plus the initial screen), so they immediately reserve almost 14 kB of memory, out of 41 kB. I tried some compression technique to save about 25% at most, but for the currently used artwork (which is based on dithering) it does not help at all. Before using some really professional artwork, the current illustrations are created with several software, after finding freely available pictures of the Alps, Swiss villages and streets. The illustrations had to be converted into a good look for the Spectrum; here we tried several pieces of software, and finally we chose DaDither. It is still not exactly we want, but maybe Zsigmond can jump in someday and improve the quality substantially!

Memory is, of course, quite a bottleneck. The C library (including the fonts) we use requires about 8 kB of code, and also the game logic and the texts occupy some 17 kB of memory. Altogether, we are already very close to 40 kB, so there is no room for much more ideas unless the texts are compressed in a clever way, similarly how BASIC commands are tokenized: they are reserved for character codes 165-255. Hopefully, the game logic could be simplified to something shorter (by using something very general and simple technique instead of a bunch of if-statements). So we expect that the game logic and the texts could be shrinked to 50%, and this would allow space for 3 more illustrations in the game.

The source code is actually not long. The game engine (written in C) consists of 15 kB, the actual game specific C code is another 15 kB, and the game messages occupy another 16 kB. The artwork, stored as C header files, requires 73 kB of data.

The game still lacks of music. My old friend, Gyuri, with whom we spent many great days together as teenagers, became a hobby music composer meanwhile, but he never forgot the good old days with his Spectrum. So maybe Gyuri could be a kind of artistic consultant in this field someday, if time allows – he also has a family meanwhile with lots of other important activities. He already started to play with the Hungarian version of the game, similarly to another old friend, Gábor. I forgot to tell them, that it is impossible to enter any accented letters on the keyboard, and the non-accented version of the letters will not be identified, either! Both in the English and Hungarian versions it is possible to use any substring of a mentioned object, that is, if someone wants to write use matchbox, or abbreviated, u matchbox, any substring of the word matchbox will also be accepted (unless there is an ambiguity with another object). That is, u box seems to be a good option, for example!

Gábor did very good progress last week, he reported a success about achieving 55% of the whole game story. His feedback, and also the positive messages of the Facebook channel ZX Spectrum to my post about this adventure game motivated me to share my thoughts also as a blog entry today.

And a final comment: If you are a Commodore 64 fan, you may try a non-graphical version of the game here. The C64 version was compiled with the oscar64 toolchain, another masterpiece of work. The most important thing here that the author answered and fixed my bug reports #172 and #180 within one or two hours. This is more than fascinating and it shows that these old communities have a very special strength, even after four decades. All of this encourages me that the era of microcomputers was indeed something special and what remains with us in some sense.


Entries on topic technical developments

  1. Embedding realgeom in GeoGebra (9 July 2021)
  2. Web version of Tarski (1 October 2021)
  3. Developing Giac with Qt Creator on Windows (24 January 2022)
  4. Compiling Giac via MSYS2/CLANG32 (2 April 2022)
  5. Terminals on the web (28 June 2022)
  6. Torus puzzle (15 April 2023)
  7. Tube amoeba (16 April 2023)
  8. XaoS in WebAssembly (30 August 2023)
  9. Debut of GNU Aris in WebAssembly (11 November 2023)
  10. JGEX 0.81 (in Hungarian) (10 December 2023)
  11. xaos.app (2 January 2024)
  12. Compiling and running bibref-qt on Wine (22 August 2024)
  13. Treasure of Count Goldenwald (6 January 2025)

Zoltán Kovács
Linz School of Education
Johannes Kepler University
Altenberger Strasse 69
A-4040 Linz