Category: Engines and File Formats

How the era’s engines worked, and what is actually inside a PAK, WAD or BSP file.

  • Reading an old game’s configuration files without breaking anything

    A large share of problems with old PC games are solved in a text file rather than an options menu. Games of this period externalised far more than they exposed, and the file holding those values is usually sitting in the installation directory in a readable format.

    Where the values live

    Several conventions coexisted, and a game may use more than one at once.

    • Plain configuration files in the game directory, often with an obvious extension and readable structure.
    • Console variable dumps, written by the engine itself, listing every setting the console can change.
    • Binary settings files, typically produced by an installer recording hardware choices.
    • Registry entries, increasingly common toward the end of the period, holding install paths and hardware settings.

    The console variable dump is the richest target. Engines with a console frequently wrote out every variable and its current value, which means the file is simultaneously the settings and a complete list of what can be set. Reading one tells you what the engine can do.

    The rules that prevent an evening being wasted

    Configuration editing goes wrong in predictable ways, all of which are avoidable.

    • Copy the file before changing it. This single habit prevents nearly every unrecoverable outcome.
    • Change one value at a time and test. Changing six and finding the game broken tells you nothing useful.
    • Preserve the line ending style of the original file. Some parsers of this era are less forgiving than you expect.
    • Close the game first. Many engines rewrite their configuration on exit and will overwrite edits made while running.

    That last one is responsible for a great deal of confusion. An edit is made, the game is closed, the edit has vanished, and the conclusion drawn is that the setting is ignored. In fact the setting was applied and then overwritten by the engine’s own save on exit. Editing with the game closed avoids it entirely, and marking the file read-only afterwards is the usual approach where an engine insists on rewriting values.

    Values worth knowing about

    Certain settings recur across engines of this era and are frequently absent from the menus.

    Field of view is the most commonly sought, usually stored as a number that the menu never exposes. Raising it helps on widescreen displays, though it is worth confirming whether the game widens the view or crops it vertically.

    Frame rate limits and sound buffer sizes are similarly external, and both are common causes of problems on modern hardware where the original defaults assumed much slower systems.

    Install paths and drive letters are the other big category, recorded at install time and consulted forever after. A game that cannot find its data files after a folder move is usually reading a path from one of these files, and correcting it there is far quicker than reinstalling.

    When the file is binary

    Binary configuration is a harder case and generally not worth attacking directly. The values are usually settable another way: through the game’s own setup utility, which still runs in most cases, or through a console at runtime.

    Where a setup utility exists, running it is nearly always faster and safer than editing bytes. These utilities were built to write exactly this file correctly, and they still do.

    Recording what you changed

    Keeping a short note of edits pays off repeatedly, because these problems recur. Reinstalling the game, moving it to another machine, or returning to it after a year all mean redoing the same work, and reconstructing which four values mattered is far slower than reading a note.

    A plain text file beside the backup of the original configuration is enough. The point is not documentation for its own sake, but that future-you will otherwise repeat the entire diagnostic process from the beginning.

  • How texture packing worked before texture atlases were automatic

    How texture packing worked before texture atlases were automatic

    Look closely at PC game art from the late 1990s and patterns emerge: textures at consistent small sizes, palettes shared across unrelated surfaces, repetition that looks deliberate and is often necessity. These are the fingerprints of memory limits that no longer exist.

    The constraint

    An early consumer 3D accelerator might carry four megabytes of memory, shared between the frame buffer, the depth buffer and textures. After the buffers took their share, what remained for textures was small, sometimes under two megabytes.

    Textures had to be resident in that memory to be used. Anything not resident had to be transferred across the bus mid-frame, which was slow enough to be visible as a stall. Managing residency was therefore a central performance concern rather than a detail.

    There were hard shape constraints too. Dimensions generally had to be powers of two, and many chips imposed limits on maximum size and on aspect ratio. An artist could not simply produce an image of whatever size suited the surface.

    What artists did about it

    The responses are visible in the finished art once you know to look for them.

    • Small tiles repeated across large surfaces, rather than large unique textures. A 128×128 tile covering a whole wall costs a fraction of a unique texture.
    • Detail concentrated where the player would be close, with distant geometry given the cheapest possible surfaces.
    • Shared palettes across a level, so that a single palette load served many textures.
    • Geometry designed to hide seams, because tiling seams were unavoidable and the alternative was hiding them with level layout.

    The tiling aesthetic that reads as period style today was substantially a memory budget expressed as art direction. It happens to have aged well, which is partly luck and partly that constraints tend to produce consistency.

    Atlases, assembled by hand

    Combining many small textures into one larger image reduces the overhead of switching between them, and the technique was well understood at the time. What did not exist was reliable automation.

    Atlases were frequently laid out by hand, or with in-house tools written for one project and never generalised. That made them expensive to change. Adding one texture to a full atlas could mean relaying out the whole thing and updating every coordinate that referenced it.

    The consequence was that atlas layout got frozen early in a project, and later art had to fit whatever space remained. Art produced late in development is sometimes recognisably squeezed into gaps, which is not a judgment on the artist.

    Filtering created a further trap. Bilinear filtering samples neighbouring pixels, so a texture adjacent to another in an atlas could bleed colour from its neighbour at the edges. Preventing it meant padding borders, which wasted the space the atlas was meant to save. Getting that balance right was a real craft skill.

    Compression arrives

    Hardware texture compression changed the calculation substantially, offering a fixed compression ratio with decompression handled in hardware at no cost during rendering. Roughly four times as much texture in the same memory, for a quality loss that varied by content.

    It was not free of character. The compression schemes handled smooth gradients and photographic detail well, and struggled with sharp colour transitions and particularly with normal maps, producing blocking artefacts around hard edges. Artists learned which content compressed cleanly and which needed to stay uncompressed, and budgeted accordingly.

    Why this matters when looking at old assets

    Anyone extracting or examining textures from games of this era should expect to find them in hardware-specific compressed formats, at power-of-two sizes, often atlased with padding, and sometimes with palettes stored separately from the image data.

    A texture extracted without its palette is not a corrupted file. It is half a file. Similarly, an atlas extracted without the coordinate data that maps surfaces onto it is a picture of a lot of textures rather than a set of textures.

    The information needed to reassemble these things is usually present in the game data somewhere. It is just rarely in the same place as the images, because in the original pipeline nothing needed it to be.

  • Redbook audio, and why copying a game disc loses the music

    Redbook audio, and why copying a game disc loses the music

    Copy a game CD from the mid-1990s to a hard drive, run it, and there is a good chance it works perfectly except that the music never plays. No error, no missing file, just silence where a soundtrack should be. The explanation is in how the disc was laid out.

    A game disc could be two kinds of disc at once

    The compact disc standards defined separate track types. Audio tracks hold uncompressed stereo audio in the format a CD player expects. Data tracks hold arbitrary bytes with error correction, which is what a computer reads files from.

    A mixed mode disc holds both. Track one is data, containing the game. Tracks two onward are audio, containing the music. Put that disc in a CD player and it plays the soundtrack, usually starting from track two because track one would be noise.

    The game plays music by asking the drive to start playing a numbered audio track. It does not read a file, decode anything or manage the audio itself. The drive plays the track and routes it to the sound card directly.

    Why this was an attractive design

    On the hardware of the period it was close to free. Compressed audio decoding cost processor time the game needed for everything else. Asking the drive to play a track cost essentially nothing, because the drive did the work in dedicated hardware.

    The audio quality was also excellent by the standards of the alternatives. Full CD quality at a time when compressed formats were rare and expensive to decode was a real advantage, and composers could deliver recorded music rather than sequenced arrangements.

    The tradeoff was that the drive could not read data while playing audio at full speed, which is part of why games using this approach tended to load a level, then start the music, rather than streaming both at once.

    What goes wrong when you copy the disc

    File copying tools see the data track. They copy the files, which is everything the game needs except the music, because the music is not files. It is audio tracks with no filesystem representation at all.

    The result is a complete installation that runs correctly and plays nothing. The game asks the drive to play track four; there is no disc, or the disc image has no audio tracks, and the request quietly fails.

    • Rip the audio tracks separately to lossless files, one per track, keeping the numbering.
    • Check whether a source port or wrapper for the game supports substituting audio files for track playback. Many do, and this is the cleanest route.
    • If using a disc image, use a format that preserves multiple tracks. A single-track data image cannot contain the audio no matter how it was produced.

    That last point catches people repeatedly. Common single-track image formats represent one data track and nothing else. An image in that format is structurally incapable of holding the soundtrack, so no amount of remounting will recover it. A cue sheet with separate track files, or a format that preserves the full disc layout, is required.

    The preservation angle

    Redbook audio is a genuine preservation hazard, because the loss is silent. A copied game that will not start is obviously incomplete. A copied game that runs perfectly with no music looks fine, and may sit in an archive for years before anyone notices that a substantial part of the work is missing.

    Track numbering matters too. Extracting the audio without recording which track was which produces a folder of files that no longer maps onto anything the game asks for. The order is the only metadata there was.

    Anyone archiving discs from this era should check the track layout before assuming a data copy is complete. It takes moments, and the alternative is discovering the gap much later, possibly after the disc is no longer readable.

  • What is actually inside a WAD file

    What is actually inside a WAD file

    The WAD is one of the most consequential file formats in PC gaming, and one of the simplest. Understanding its structure explains a surprising amount about why the modding culture around it developed the way it did.

    The name is usually expanded as Where’s All the Data. That expansion appears in the original technical documentation, so it is at least contemporaneous rather than a later joke, though the format’s design suggests the acronym came second.

    Three parts and nothing else

    A WAD file has a twelve-byte header, a body of raw data, and a directory. That is the entire format.

    The header records an identification string, the number of entries, and the byte offset where the directory begins. The identification string is either IWAD or PWAD. An IWAD is a base game file, self-sufficient and containing everything needed to run. A PWAD is a patch file, containing only entries that should replace their equivalents in the loaded IWAD.

    That distinction is the foundation of the entire modding scene. The engine loads the base file, then loads any patch files over it, and later entries with the same name win. No installer, no file replacement, no risk to the original. Users could try a modification and remove it by not loading it next time.

    The directory is a flat list

    Each directory entry is sixteen bytes: a four-byte offset, a four-byte size, and an eight-byte name padded with nulls. There is no type field, no timestamp, no folder structure and no compression.

    Two consequences follow immediately. Names are limited to eight characters, which is why entries carry terse names like E1M1 or PLAYPAL rather than anything descriptive. And because there are no directories, organisation had to be expressed through naming conventions instead.

    The convention that emerged used marker entries: zero-length entries whose only purpose was to bracket a range. Everything between the sprite start and sprite end markers is a sprite. Everything between the flat markers is a floor or ceiling texture. The engine determines type by position relative to markers, not by anything recorded in the entry itself.

    Why a level is many entries rather than one

    A level is not stored as a single blob. It is a marker entry naming the level, followed by a fixed sequence of entries in a required order, each holding one aspect of the level’s geometry and contents.

    • THINGS lists every object placement: monsters, items, player starts.
    • LINEDEFS and SIDEDEFS describe walls, their textures and their behaviours.
    • VERTEXES holds the raw coordinates those lines connect.
    • SECTORS defines floor and ceiling heights, lighting and special behaviour.
    • SEGS, SSECTORS and NODES hold the precomputed spatial subdivision the renderer walks.

    The last group matters more than it looks. Those entries are generated by a separate tool from the level geometry, and the engine relies on them being correct for rendering and collision. An editor that changed geometry without regenerating them produced a level that looked right in the editor and behaved incorrectly in play.

    This is why the node builder was a distinct, named piece of software in the toolchain rather than a hidden implementation detail, and why the quality of a node builder was something modders held opinions about.

    What the format got right

    The design was not obviously destined to spawn decades of modification, but three properties made it happen.

    Replacement by name meant a modification only needed to include what it changed. A file altering one texture could be a few kilobytes. Distribution over a modem was practical.

    The absence of compression meant the format was trivially inspectable. Anyone who could read a hex dump could work out the structure without documentation, and people did, quickly, before any official specification was published.

    And the separation of patch from base meant the base file was never modified. The barrier to experimenting was near zero, because nothing could be broken permanently.

    Reading one today

    The format is simple enough to parse in a short script: read twelve bytes, seek to the directory offset, read sixteen bytes per entry. Modern tooling exists and is better than writing your own, but the exercise is genuinely instructive, because the structure is small enough to hold in your head entirely.

    Very few formats from the period are that approachable. Most of what came later was compressed, packed and versioned in ways that require documentation to make sense of. The WAD can be understood by staring at it, and a great deal of what followed in PC modding came from that fact.