Skip to content

Build, Jedi and other 2.5D engines ​

Between Doom (1993) and true 3D engines (Quake, 1996), several engines drew 3D-looking worlds from 2D maps with heights. They are called 2.5D engines. The map is a set of polygons (sectors) seen from above, each with a floor and a ceiling height. The renderer draws walls column by column and floors and ceilings row by row. Most of these engines added features that Doom lacked: sloped floors, rooms over rooms, mirrors.

Build ​

Ken Silverman wrote the Build engine for 3D Realms. It was licensed widely.

GameYearDeveloperNotes
Duke Nukem 3D19963D RealmsGame logic partly in CON script files
Shadow Warrior19973D RealmsIts own game code in C
Blood1997MonolithHeavily changed engine and its own game code
Redneck Rampage1997XatrixBuilt from the Duke Nukem 3D code

The engine source was released in 2000 and the Duke Nukem 3D game source in 2003.

How it works. Sectors are polygons. Each wall points to the next wall of the same sector and, through a portal, to the wall of the neighbouring sector. The renderer walks from the player's sector through portals, drawing what it can see. Two sectors may overlap in the map, because the engine never checks that the world is consistent, so rooms can be in the same place on the map. Sprites can be flat on the floor or on a wall, or face the camera.

What to note.

  • Positions are integers. Heights use a different scale from horizontal positions (a factor of 16 in Duke Nukem 3D). Watch the shifts when you read maths code.
  • Duke Nukem 3D's CON files define actors, weapons and sounds in a small script language. The game compiles them when it starts and interprets the result. Read the CON files before you trace actor behaviour in machine code.
  • The game timer runs at 120 ticks per second in Duke Nukem 3D; the game logic runs at a fraction of that (30 updates per second). Find the exact rate in the timer code of your game.
  • Files are packed in .GRP archives. Art is in .ART files with a shared palette and shade tables (PALETTE.DAT, LOOKUP.DAT).

Projects to learn from. EDuke32 (a source port that keeps old CON scripts working), NBlood (Blood's game code reimplemented from reverse engineering, on EDuke32's engine), and Raze (several Build games in one modern engine).

The Jedi engine ​

LucasArts wrote the Jedi engine for Star Wars: Dark Forces (1995) and reused a much changed version of it for Outlaws (1997). Like Build, it has sectors with floor and ceiling heights, plus rooms above rooms and 3D object models.

  • Level logic is in .INF files: a text language that defines elevators, doors, switches and triggers as small state machines.
  • Dark Forces keeps its data in .GOB archives; Outlaws uses .LAB archives instead. Levels are .LEV (geometry) and .O (objects).
  • The source was never released. The Force Engine is a reimplementation built from reverse engineering. Its documents explain the formats and the INF language.

Other engines of the type ​

EngineGamesNotes
Doom engine variantsHeretic, Hexen, StrifeSee The id Software engines
ROTT engineRise of the Triad (1994)Built from the Wolfenstein 3D engine. Each map keeps one floor and one ceiling height; raised areas are built from floating platform objects
Voxel Space (NovaLogic)Comanche (1992), Delta Force (1998)Terrain drawn from a height map and a colour map, one column at a time
XnGine (Bethesda)The Elder Scrolls: Daggerfall (1996)True 3D for its time; Daggerfall Unity documents its formats
Ultima Underworld engine (Looking Glass)Ultima Underworld (1992), System Shock (1994)Texture-mapped 3D with sloped floors, before Doom

How to approach a 2.5D game ​

  1. Decode the map format first. With the sectors, walls and objects in hand, you can draw the map from above and see the level's layout.
  2. Find the renderer's main loop. In these engines it is usually one large function that walks sectors or columns. It is the slowest code in the game, so it is often in assembly.
  3. Separate the renderer from the game logic. You can rebuild the renderer to match its output. The game logic must be exact.
  4. Find the timer rate and the game update rate. They are often different.
  5. Compare frames from the same position and angle with the original (Running the original). A software renderer's output is exact, so compare pixel by pixel.

Code: Apache 2.0. Content: CC0 1.0. No game material: bring your own copy.