Mandala and Z Fighter Forever

About Mandala and True Portal Engines

True Portals

By now, you've probably seen games with "portals", such as Prey, or Valve's imaginatively-titled Portal. These aren't really portal engines and, yes, I am slightly bitter that I started working on such a beast a few months before it was announced that Prey was to be resurrected. To try and distinguish graphics engines such as Mandala's renderer, and the original Prey, from these modern pretenders, I have dubbed them "true" portal engines.

A fairly solid introduction to what portals are all about, and why they're cool, can be found in a UseNet thread, in which William Scarboro, one of the original Prey developers, says "don't do this". Basically, the environment is carved up into mostly-convex areas dubbed "sectors" (think individual rooms and hallways in a building). These are then connected to eachother by "portals" (think doorways). If a portal leading out of the current sector isn't currently visible, then the renderer knows that it doesn't have to render the sector on the other side. This provides fairly efficient runtime visibility culling (the process of avoiding wasting time preparing to draw things which are hidden anyway), and is what portal engines were originally about.

Then someone figured out that you don't necessarily have to put all the sectors in one contiguous block. The kitchen and the dining room can be several miles apart, but if their doorways still link to eachother then they'll appear to be adjacent from inside. Standing in the doorway between them, half of you would be several miles away from the other half, but you wouldn't notice.

What you might notice were if the door to the understair cupboard lead to a massive concert hall, yet you could still walk around to the other side of the stairs and find them quite ordinary. Because this is an entirely runtime technique, by the time you go back, the cupboard may now look through to a bus station in Milton Keynes, a spinning dimensional rift inside your own head, or even a small storage area with a mop in it which just happens to be somewhere in Swaythling. This is where true portal engines get really cool: they can bend space into pretty much any shape you can imagine, but they can be as subtle about it as you like.

This is what Prey and Portal don't do—what they have is an approximation of a portal, bolted on top of a regular, BSP-based engine. (Yes, that's also the case for the Unreal engine's little-used WarpZones.) It's true that it gives them a great deal of the magic of portals, but they have their limits: they can't, as far as I can determine, support the same flexibility, because they're still based on heavy amounts of precomputation. I strongly suspect that they still have a global co-ordinate system (a true portal engine can only really express things in terms of sector-relative co-ordinates, becuase a sector may appear more than once if lots of portals lead to it—imagine a wall of 'televisions' which all share a screen, and reaching into one makes your hand also appear in all the others), and effectively have one Really Huge sector with lots of isolated areas in, connected by portals: they instead rely on existing BSP visibility culling. This kind of approach leads to a lot of rough edges, such as the inability to properly handle the potentially multiple unique locations of a single item, or correct traversal of all objects and partial-penetration collision cases through portals. In particular, lighting and splash damage do not work through these portals.

And I think they've skimped on the maths, too. Working out mappings between sectors for arbitrary portal orientations is hard. Teaching your engine a small set of precomputed sign-flips for right-angled orientations is easy. Have you ever seen a portal in Prey or Portal which isn't axis-aligned? ;)

Unreal can handle the rendering for it, but doesn't rotate objects passing through portals at all, which means that they may appear to rotate for no reason. Such are the perils of trying to fit portals into a global-co-ordinate-system engine.

Mandala has a ton of rough edges too, I easily concede, but it was developed in a few months by two-to-three students, and I still think we have better portals than Human Head and Valve. (In a nutshell: we aimed for getting portals right. They aimed to add most of the cool-factor for minimal development effort. It took us a lot of work, and we don't have the artistic skills (or time left over) to make them really spangly and really show it off. They published, or are going to publish, successful games, but will never get the remaining coolness out of portals without starting over and doing it properly.)

Mandala

Mandala is an open-source game engine written in C which supports these "true" portals. In the spirit of portal engines, there is a heavy emphasis on dynamism: Mandala prefers to use just-in-time computation and caching in favour of precalculation, allowing for enviroments which change radically without suffering large performance penalties.

It is modular to an almost pathological degree. Everything in a "world", a particular game environment, is an entity. Entities have behaviours, such as "do something for this timeslice", "work out if you're colliding with this", or "draw yourself". The upshot is that it's entirely possible to use any kind of graphical and spatial representation of an object you like—the renderer only knows about polygons becuase they're a convenient way to define the outline of a portal: everything else is up to behaviours. Of course, there are a common set of built-in behaviors for common roles such as mesh rendering and collision.

Mandala also includes an entire input binding and abstraction system which lets you write in terms of "move forward" and "alternate fire", not "W" and "right mouse button"—and it's been designed so that even joysticks, keyboards, and extra mouse buttons can all be used interchangably while still making sense. Tedium such as loading, managing memory for, and caching of models and textures is taken care of, and the system is very careful to ensure that resources get deallocated again. Rotations are handled in terms of quaternions, avoiding the horrors of gimbal lock (essential for space games such as Z Fighter Forever), and there are 'nice' methods to generate and use them for people who'd rather not think about quaternions.

Mandala's design and implementation, as well as some additional matter on portals, is covered in the project report for Z Fighter Forever below. If you want the really technical stuff, all of the public (and private) Mandala headers are documented in doxygen syntax. I've tried to be more helpful than the average "getFoo(): returns foo" level of most header comments. Start with the master header, move to mandala_engine.h, and you should find enough context to work out where you want to go from there.

Of historic interest may be the Advanced Computer Graphics project report, which describes Mandala in its pre-ZFF state. Note that this conflicts quite violently with Mandala's current state in parts.

Large thanks go to Jim Gerrard, for taking an interest in, and working out a lot of, the hairy problems with transforming between the multitudes of co-ordinate systems involved in such an engine. Further thanks for his and John-Mark Bell's work on Mandala for Z Fighter Forever.

The name

man-da-la n.

A ritualistic, geometric design used in Hinduism, Buddhism and Discordianism (the design of which on page 43 of the Principia Discordia inspired the use of such a name for this engine, and is used for the logo) as an aid to meditation, symbolic of the universe. Fnord.

I thought that it was fitting. And shorter than "that portal engine thing that Phil's writing: you know, with the non-Euclidean geometry, and maths that drive him insane".

About Z Fighter Forever

For the group Interactive Entertainment Systems assignment, Jim and I worked with Karl Doody and John-Mark Bell on beating Mandala into shape and producing a game using it (much to our later amusement—3D Realms fans may be able to guess how much amusement by the title). The result is Z Fighter Forever: a multiplayer little-ships-in-passages-and-caverns shooter, with realistic space physics. (You have inertia, but neither atmospheric resistance nor gravity, and hitting things will just make you bounce off of them. Getting moving is easy. Controlling where you move, or stopping, is not.)

ZFF isn't particularly complete, but it's quasi-playable (Jim's demonstrated his relative mastery of the physics by utterly annihilating me several times), and it serves as a demonstration of game development with Mandala. The single included level, ]|[space, has corridors in the shape of a 270-degree triangle, with three overlapping central rooms. The spawnpoints in these rooms themselves overlap the outer corridor.

What it doesn't show is Mandala's ability to handle all this portal malarky when it's dynamically changing which polygons are portals, where they point, and where they are, during the game. This is a limitation of ZFF's level format (blame me—I had to develop it to a deadline ;)).

The networking also had to be quite, quite rushed, unfortunately, so you may encounter some pretty horriffic lag-like effects at times. The resimulation will occasionally cause the server to throw you about a bit: unfortunately, without this, the clients would go out of synchronisation and you wouldn't be able to shoot each other. =/

For more information than you ever wanted to know about Z Fighter Forever, see the (5 MB) project report, which includes plentiful design and implementation documentation. And more screenshots.

Download

Mandala is pure C99, with some filthy hacks to also make it compile under Microsoft Visual C++. KUI and ZFF require a C++ compiler, such as g++ or MSVC. All three have been tested under Windows and Linux, and should work on any POSIX-y or Windows-y platform, possibly with some tweaking of the MSVC project/makefiles. You'll probably make your life easier if you extract all three in adjacent directories, as the "buildall" script in ZFF expects.

You will need these libraries:

Mandala, Karl's UI library (KUI), and Z Fighter Forever are licensed under the Common Public License 1.0.

There aren't publically accessible version repositories for these (yet), so please just e-mail any modifications to me, and I'll merge them/dispatch them to the others. If you plan to make any large changes, please e-mail me in advance to avoid duplicated or conflicting efforts.

Update Dec 07: Doxygen of Mandala 0.22, including all the private bits you shouldn't touch (but probably need to see for now until proper, high-level documentation exists).