Personal Computer News, Issue 086, 1984-11-10

ankh84_choose ankh84_smearyPractice


This game is something else but exactly what I’m not sure. Put at its simplest (and this game is anything but simple), Ankh is a series of logic puzzles, some unbelievably tough.

The game environment is described as the ‘Metareal world of Ankh where logic works but doesn’t rule’. The idea is to find your way through 64 connecting rooms, each of which is different and holds a puzzle. Sometimes you can pass through a room’s doorway with no trouble but mostly you need to find a way to open up the exit before you can pass.

Each room must be prodded, poked and probed to yield up its secrets. Solving a room’s puzzle may bring forth a treasure, a tool or (groan) yet a further puzzle. You control a spherical object, your Mindprobe. It can be moved around and fire missiles. You gain power by performing certain actions (gaining access to a new room, for example) and lose it at a rate of knots when you collide with your environment. The game is over when you lose all power – or when you solve it.

At start-up you have the opportunity to experiment on an abstract set-up – a confidence-sapping experience in my case. You may also select the level of perplexity of the puzzles (from mindboggling to mind shattering).

A real headache inducer, Ankh is like nothing you’ve played before. There’s no middle way – you either love it madly or stick it straight under a steam hammer.

Issue: 086
Publication Date: November 10 1984
Subsection: GAMEPLAY
Article Name: Ankh
Author: Bob Chappell

Computer: Commodore 64
Price: £8.95 (Cassette)
Publisher: Beyond
Reviewer: Bob Chappell
Rating: 8/10

Engine: MeRenderWorld

And now, a few notes about the Metareal Engine architecture. As mentioned earlier, of course it’s silly to write my own, let’s move on.

The library presently consists of two major components: Rendering and Volume Management. The Rendering side deals with lists of triangles, groupings of parts, geometry lists, and shader graphs. The Volume Management side deals with detecting intersections of volumes, and notifying listeners. Physics is built on top of volume management, as a special case of responding to intersections.

In this post, I’ll talk about one aspect of Rendering.


The class MeRenderWorld is presently the highest level container. An application may use several, certainly, but this is the top container on the library side.

An MeRenderWorld manages:

  • Lists of Parts (each part is a geometry list)
  • Cached geometry lists, grouping parts by material, so each material uses a single glDraw
  • References to materials (shader programs, for an OpenGL implementation)
  • Backing buffers for rendering post processing
  • List of render operations

The MeRenderWorld itself knows nothing about OpenGL; rather it deals with MeIMaterials and MeIPartRenderers and MeITextures and so on. For now there are only two implementations of each, one for OpenGL and one for FakeFL, which just records actions suitable for unit testing the library.

Often, one wants to describe a process by means of a document, perhaps in XML or similar. Describing the graph of draws and post-processing for a final scene frame is a perfect example of this. However, I have a strict policy of implementing code first, document second. Here I’ll show the code mechanism for building up a render graph.

The render graph is described as a strict, linear sequence of actions. It has to become one anyway (at least until glNext), so that’s the primitive. Here is an example setup:

    MeRenderWorld *rw = this->renderWorld;
    rw->addStepClear("", 0x123456);
    rw->addStepDraw(this->materialSky, "");
    rw->addStepDraw(this->materialOpaque, "");

Here we see that each frame will be created with three actions: a clear-to-color, and two material draws. Today this is, in fact, exactly two glDraw() calls, but that could change.

The empty strings are the names of frame buffers. The unnamed buffer, “”, is the default output buffer. This might be the screen or window, or be another buffer, depending later on the argument to rw->draw().

Here’s a more complex render sequence:

    rw->addStepClear("b0", this->bgColor);
    rw->addStepDraw(this->materialSky, "b0");
    rw->addStepDraw(this->material, "b0");
    addCopyingStep(rw, "b0", "b1");

    rw->addStepSetTextureColor("b1", this->materialTransparent, "texture1");
    rw->addStepDraw(this->materialTransparent, "b0");

    addCopyingStep(rw, "b0", "");

In this sequence, the background is cleared and then drawn with a skybox. Then, the opaque parts of the geometry are drawn onto a buffer named “b0”. This buffer is created on-demand by MeRenderWorld, you just have to name it, and it exists.

That first render is provided as a texture argument to the transparent material, in a uniform named “texture1”, which is then drawn onto “b0” also.

Lastly, “b0” is copied to the output. (addCopyingStep() is a macro which instantiates a screen-sized rectangle textured with one buffer, drawing to the other).

Here’s a frame of the output:


And there’s a peek into the Metareal Engine’s rendering component.

Looking Forward


As I’m coding, managing lists of millions of vertices, swapping buffers, keeping track of state and building optimization caches (in time and space, as we say), it is wonderfully overwhelming. There is so very much more to do. Collada imports, managing interactive object types, state saving and recalling, and many fine details that can’t yet be revealed.

To say nothing of the joy of actually crafting the puzzles, and the graphics and the music.

I am reminded of an excellent SF book by Greg Egan called “Permutation City”, which takes place mostly in a simulated world. (The world has become detached from reality, because the computer that generated it was turned off, so they are free-floating.)

One of the persons inside it has found a way to cope with immortality; from time to time he is reborn with a new obsession. After he has cataloged the last of the several billion species of butterfly and moths in some imaginary world, he wonders who he will become next.

The room goes fuzzy, and he is disoriented… he realizes he is in a workshop with acres of bins of wooden dowels… all waiting to be lathed into table and chair legs.

He is in heaven.