A-code language history (as I recall it)
The main purpose of this document is to explain (in response to some requests) why some aspects of my A-code implementation are the way they are, and what the future might hold if I get around to it.
A-code is the language developed by Dave Platt in order to write his influential Adv550 expansion of the classic game Adventure by Crowther and Woods (Adv350 in the modern nomenclature). Originally written in PL6, a Fortran 77 implementation of the original A-code engine was distributed in the late 1980s together with the the Adv550 A-code source.
Dave Platt's A-code engine had a "munger" and an "executive", both written in F77. The munger took the A-code source and produced a tokenised pseudo-binary. The executive was was effectively a virtual machine which executed the pseudo-binary. The lightly encoded game's text was in a separate file.
I first made use of this original A-code implementation to merge Luckett's and Pike's Adventure II (now known as Adv440) with Adv550 and Platt's Adv550 into Adventure4, which later evolved into Adventure4+ (now known as Adv660).
The initial Adventure4 and then Adventure4+ (1983 - 1985/6, on Primes) implementation took the A-code architecture as it was. The only changes to the munger/executive were in improving the command parser (e.g. automatically allowing all words to be abbreviated to the minimal unambiguous length, chaining commands on one line with semicolons, and providing AGAIN for command (simple or compound) repetition.
In September 1990 I embarked on re-implementing A-code in C on Unix, the main aim being to teach myself C (my previous expertise was first in Algol/Algol68, then in Fortran4, then in Fortran77). I later joked that the new version was dedicated to the proposition that a real programmer can write Fortran in any language. That implementation was the seed of the current version and it moved away from Platt's in one crucial step, the full significance of which did not transpire until much later. Instead of replicating Platt's virtual machine approach, I wrote acdc, which translated A-code directly into compilable C, with game-independent kernel C source providing a library of standard calls used by the translated code.
The reason for this shift was performance. Adventure4+ by that time became too large and complex, yet I wanted it to run on ordinary PCs as they then were. Virtual machine interpreter of pseudo-binary struggled with that, but compiled C worked just fine.
To accommodate minuscule (by modern standards) memories standard at the time and the slow speed of disk access, I nicked from Prime an outline of their paging algorithm, and built that into the kernel, together with the ability to report locate demands, the number of locate buffers being specifiable at compilation time. This mechanism is still present within the kernel, but for all it is by now completely redundant. The kernel also provided the option of reading all texts from the data file as required, with no paging mechanism, or to load the data file entirely into memory on startup. Initially there was no option for pre-loading all of the text into memory -- compilers of the time tended to choke on that.
Unix (Irix in fact) became the default platform. DOS/Windows executable got built by using djgpp under DOS.
As memory capacities grew and general machine performance improved, I first added the option to build the whole game as a single executable with no data file – all text begin stored in initialised arrays in the C source. Later this became the default. Thus things stood until I embarked on Adv770, which is when I discovered some unexpected upsides and downsides of the approach I'd taken.
I needed the game to be tested by others, but I knew from experience that it would be foolish to rely on testers to report all problems. Without knowing what is supposed to happen, it is not necessarily obvious whether things are going wrong or not. I simply had to have access to testers' log files. The only way this could be achieved was to run the game through a web interface – in the cloud, as one would say these days. Unfortunately, as the acdc/kernel implementation of A-code stood at the time, this simply was not possible. An acode game was simply an executable, taking player commands from standard input and responding on standard output in a continuous loop.
My eventual solution was to implement the context mechanism and replace any use of query with setting the special variable CONTEXT to a unique value, specifying the nature of the query, before saving the game state and exiting. Once a response arrived from the player, the game would restart and if the value of the restored CONTEXT indicated that a yes/no question had been asked, it would evaluate the answer in the same way as it would have done if QUERY had been used. This permitted cloud-based operation (initially CGI, later PHP).
Some internal changes had to be introduced to support this development, and so the major version number of the acdc and the A-code kernel got incremented from 10 to 11.
Adv770 was finally released in 2003, but I continued tinkering with my A-code implementation anyway.......
==== To be continued... ====