Glulx: A 32-Bit Virtual Machine for IF (original) (raw)
What Is It?
Glulx is a portable VM, like the Z-machine. Unlike the Z-machine, it uses 32-bit data and addresses, so it can handle game files up to four gigabytes long. Also unlike the Z-machine, it has native support for Glk I/O, so game files can use any capability Glk provides. However, like the Z-machine -- again -- you can write games in the Inform language and compile them to Glulx game files.
For more justification (or, perhaps, rationalization) seechapter zero of the Glulx Spec.
Specification
This is the Glulx VM Specification, version 3.1.3.
- HTML version of Glulx specification
- Plain text version of Glulx specification
- PDF version of Glulx specification
- Change log for the specification
Glulxe
Glulxe (for "Glulx Execute") is the Glulx interpreter. The current version is 0.6.1.
The official and up-to-date archive of Glulxe ports is on the IF Archive, underif-archive/programming/glulx/interpreters/glulxe.
- Glulxe 0.6.1(C source code.)
- GIT source code repository(bleeding edge and older versions.)
Since this is a Glk program, it must be built with a Glk library. See theGlk home page.
Quixe
Quixe is a Glulx interpreter written in pure Javascript. It lets you run Glulx games in a web browser.
Lectrote
Lectroteis Quixe wrapped up as an app for MacOS, Windows, and Linux.(Current binaries here.)
Glulx Inform
The standardInform 6 compilercan generate Glulx binaries. (If you want the bleeding-edge version, you can followDavid Kinder's Github repository.)
Here isThe Game Author's Guide to Glulx Inform. This is what you need to know if you know Inform, and want to compile your new (or old) Inform game for the Glulx VM.
Here isThe Glulx Inform Technical Reference, which documents all the internal table formats used by Glulx Inform games. (Dictionary tables, grammar tables, property tables, and so on.) Here isThe Local Variable Mess, a technical note on the deprecation of 8-bit and 16-bit local variables.
John Cater katre@plover.net has written infglk, an Inform header file for Glk functions, with support for rebuilding it when the glk.h header changes. (However, a more up-to-date version is now on myGithub account.)
Sample Game Files
I've compiled Adventure. This is Graham's Inform source, release 5 serial 961209. I compiled it without any changes at all, except for two constant definitions which will be unnecessary in the final release. (See the Guide to Glulx Inform.)
- <Advent.z5>: the Z-code version.
- <Advent.ulx>: the Glulx version.
- <Advent.save>: a save file from the Glulx version.
The Z-code and Glulx game files should behave identically in just about every way. (You should download both of them, so that you're really comparing the same game, library, and compiler version. These use Inform 6.21 and the adapted bi-platform 6/10 library. The version of Advent.z5 on the IF Archive uses an earlier library.)
Known differences:
- Text styles are more diverse. As mentioned in the Guide to Glulx Inform: the game's title is displayed in the Header style; room names are displayed in Subheader; score changes are in Note; and "You have died" is in Alert. You can adjust your Glk library preferences to make these styles appear however you want. (In MacGlk and XGlk, for example, you can set the font/size/color of each of them independently.)
- The Glulxe version is slower. This is noticeable and annoying on my old (20MHz?) 68040 machine. On the newer (120MHz) machine, it's not a problem. (The search opcodes in the newest compiler, library, and interpreter should speed up games by about 20%.)
Sample Program Without Inform Library
In Z-code Inform, you can write a "Hello world" program in one line of code. A print statement will work all by itself.
In Glulx Inform, you have to do a little more work: you have to set Glk up to work, and create a window to print to. It's still only about four lines of code.
- <helloworld.inf>: the Inform source code to print a single line.
Now, don't get confused, most Inform game authors will never need to worry about those four lines of code. The bi-platform Inform library takes care of all this magically. However, if you want to write a Glulx Inform program that doesn't use the library at all, look at helloworld.inf to get started.
Sample Game With Resources
And introducing: Sensory Jam (release 4). This is a tiny demo game which contains sounds, graphics, and all sorts of other nifty things. Well, really just sound and graphics.
- <sensory.ulx>: the plain Glulx file.
- <sensory.tar.Z>: a tar file containing sensory.ulx, plus all its sounds and images as separate files.
- <sensory.blb>: a Blorb file containing the game and all its resources.
- <sensory.inf>: the Inform source code.
You'll need a Glulxe 0.3.3 interpreter to play this, since it was compiled with the latest compiler.
Toni Arnold has extracted some of the graphics code from Sensory Jam into an Inform library extension. It was written to deal with the older bi-platform library, so you will have to diddle it a bit to fit it into current code -- I haven't tried it myself. Nonetheless, it's a handy example.
Sample Game With Parallel Worlds
- <twocol.inf>: the Inform source code for a two-column game.
- <twocol.ulx>: the Glulx game file.
This is a quick demo of a game concept: it takes place in two parallel worlds, each with its own story window. You enter commands in the left window, and your twin performs analogous actions in the right window. It's a very basic implementation, and a lot of stuff doesn't work right, but it's a start.
Unit Test Sample Games
- <glulxercise.inf>(<glulxercise.ulx>) (test in browser): a unit test that runs through all the Glulx opcodes and features.
- <graphwintest.inf>(<graphwintest.gblorb>) (test in browser): a game which tests the features of graphics windows.
- <imagetest.inf>(<imagetest.gblorb>) (test in browser): a game which tests displaying images in text buffers.
- <autosavetest.inf>(<autosavetest.gblorb>): a game which tests embedding a save file in the Blorb data.
- <extbinaryfile.inf>(<extbinaryfile.ulx>): a game which tests data files in text/unicode mode (UTF-8, by a recent spec change).
- <resizememstreamtest.inf>(<resizememstreamtest.ulx>) a game which tests a memory bug that was fixed in Glulxe 0.5.0.
- <resstreamtest.inf>(<resstreamtest.gblorb>) a game which tests the resource-reading feature.
- <startsavetest.inf>(<startsavetest-empty.gblorb>,<startsavetest.gblorb>) a game which uses the resource-reading feature to start itself up quickly. (The startsavetest.gblorb file contains an embedded save file, which is restored at startup time. The startsavetest-empty.gblorb file is an intermediate stage in constructing this. See the header comments.)
- <unisourcetest.inf>(<unisourcetest.ulx>): a game which tests I6's ability to read Unicode source files. (This is an I6 compiler feature, not an interpreter feature.)
- <chinesedicttest.inf>(<chinesedicttest.ulx>): another game which tests I6's ability to read Unicode source files. (This is an I6 compiler feature, not an interpreter feature.)
- <dictflagtest.inf>(<dictflagtest.ulx>,<dictflagtest.z5>): a game which tests the I6 dictionary-flag feature. (This is an I6 compiler feature, not an interpreter feature.)
- <datetimetest.inf>(<datetimetest.ulx>) (test in browser): a game which tests the date and time features.
- <inputfeaturetest.inf>(<inputfeaturetest.ulx>) (test in browser): a game which tests the line-input echoing and termination features.
- <floatparsetest.inf>(<floatparsetest.ulx>): a game which can parse float constants in game commands. (Contains a working I6 GPR routine for float values.)
- <floatconsttest.inf>(<floatconsttest.ulx>): a game which tests the I6 float-literal parser. (This is an I6 compiler feature, not an interpreter feature.)
- <doubleconsttest.inf>(<doubleconsttest.ulx>): a game which tests the I6 double-literal parser. (This is an I6 compiler feature, not an interpreter feature.)
- <unicasetest.inf>(<unicasetest.ulx>) (test in browser): a game which tests the Unicode case-changing and normalization functions.
- <unicodetest.inf>(<unicodetest.ulx>) (test in browser): a game which prints various Unicode characters.
- <discardundotest.inf>(<discardundotest.ulx>): a game which lets you test the @hasundo and @discardundo opcodes.
- <memcopytest.inf>(<memcopytest.ulx>): a game which lets you test the @mcopy and @mzero opcodes.
- <memheaptest.inf>(<memheaptest.ulx>): a game which lets you test the @malloc and @mfree opcodes.
- <memstreamtest.inf>(<memstreamtest.ulx>): a game which lets you test the glk_stream_open_memory() and glk_stream_open_memory_uni() calls.
- <inputeventtest.inf>(<inputeventtest.ulx>) (test in browser): a game which lets you test character and line input events (plain and Unicode, text buffer and text grid windows).
- <accelfunctest.inf>(<accelfunctest.ulx>) (test in browser): a game which lets you test function acceleration.
- <arraylimittest.inf>(<arraylimittest.ulx>): a game which calls print_to_array(buf) with no second argument. (This demonstrates the ability of the interpreter to catch this mistake and display a warning or error.)
- <unidicttest.inf>(<unidicttest.ulx>): a game which contains various Unicode characters in its game dictionary.
- <externalfile.inf>(<externalfile.ulx>): a game which creates data files using various file-opening modes.
- <windowtest.inf>(<windowtest.ulx>) (test in browser): a game which lets you try out various window arrangements, and other Glk features.
- <randomgen.inf>(<randomgen.ulx>): a game which spits out random numbers.
Glulx Assembler
Simon Stapleton has written glulxa, an assembler for the Glulx VM. Here isthe source code (on the IFArchive).
There's also Glasby Joonas Pihlaja, although it's a bit old.
Text Compression Sample Code
I've settled on good old-fashioned Huffman encoding for the compression system, allowing either characters or words (or a mixture of both) as the encoding entities.
However, if you want to experiment on your own, these are some simple tests, trying various text-compression algorithms. Here is the source code. You can extend this test platform to try out new compression ideas, if you want.
Before Anybody Asks...
MIME type "application/x-glulx". On the Mac, file type "UlxG", and the standard Glulxe interpreter uses creator code "gUlx".
What's New
The Glulx 3.1.3 spec: support for double-precision floating-point math. Also @hasundo and @discardundo opcodes. Glulxe 0.6.0 supports this.
As of April 2020, the copyright of the Glk spec document is transferred to theInteractive Fiction Technology Foundation. I still act as the maintainer.
Glulxe 0.5.4: a debugger module. (Not compiled in by default.)
Glulxe 0.5.3: optimizations and bug fixes.
Quixe 2.1.3, with support for Electron. And then 2.1.4, with support for autosave.
Quixe 2.1.0, now with graphics.
Quixe 2.0.0, now jQuery-based.
Updated the Glulx 3.1.2 spec to add more accelerated functions. (It's still numbered "3.1.2", a decision I may regret.) Glulxe 0.5.2 and Quixe 1.3.1 support this.
Glulxe 0.5.1: bug fixes.
Glulxe 0.5.0: bug fixes; turned on memory-range checking by default; added glue for iOS port.
Glulxe 0.4.7: profiling improvments; bug fixes.
The Glulx 3.1.2 spec: support for floating-point math. Also Glulxe 0.4.6, which supports it, along with some bug fixes.
Glulxe 0.4.5: more bug fixes, and a deprecation warning for a case that occurs if Inform code calls print_to_array(buf) with no second argument.
The Glulx 3.1.1 spec: support for accelerated functions. Glulxe 0.4.4 supports this, and also can be compiled with a profiling option.
Glulxe 0.4.3: includes some bug fixes, and the option to check for memory overruns.
Put out the Glulx 3.1.0 spec, which includes @mzero, @mcopy, @malloc, and @mfree opcodes.
Kicked out the Glulx 3.0.0 spec, which includes the infrastructure needed for Unicode support.
(Fixed typo in spec: the @streamstr opcode can be used for string types E0, E1, or E2. The original 3.0.0 document failed to mention E2.)
Last updated October 22, 2023.