WAD

WAD (which, according to the Doom Bible, is an acronym for "Where's All the Data?") is the file format used by Doom and all Doom-engine-based games for storing data. A WAD file consists of a header, a directory, and the data lumps that make up the resources stored within the file. A WAD file can be of two types:


 * IWAD: An "Internal WAD" (or "Initial WAD"), or a core WAD that is loaded automatically (or from a game select menu on source ports) by the engine and generally provides all the data required to run the game.


 * PWAD: A "Patch WAD", or an optional file that replaces data from the IWAD loaded or provides additional data to the engine.

A WAD file can be read and/or edited by many tools, such as WAD editors.

Historical background
After the release of Wolfenstein 3D in, fans developed unauthorized mods of the game that changed elements such as levels and monster graphics. Rather than causing id Software to seek to suppress such mods, they encouraged the developers to make Doom more easily moddable.

The WAD file system is the primary mechanism that allows easy modding by fans. Mods containing new levels, graphics, sound effects and music are natively supported by vanilla Doom without needing any special third party tooling; they can simply be loaded using the -file command line argument. This is in comparison to Wolfenstein mods, where the main game resource files had to be modified in order to make any change.

WAD files contain certain limitations: for example, much of the game behavior cannot be changed without patching DOOM.EXE using a tool such as DeHackEd (modern source ports allow DeHackEd patch files to be included in WAD files). Vanilla Doom does not support replacing sprites from inside PWAD files; older graphical mods would commonly be distributed with a small tool named DeuSF that would work around this limitation (modern source ports have entirely removed the restriction).

Header
A WAD file always starts with a 12-byte header. It contains three values: All integers are 4 bytes long in x86-style little-endian order. Their values can never exceed 231-1, since Doom reads them as signed ints. For some ports based on the Atari Jaguar code (Playstation derived ports being the notable exception), big-endian order is used instead.

The IWAD or PWAD signature is meant to define whether the file is an IWAD or a PWAD, however this is not actually checked by the engine. Loading an IWAD as a PWAD is possible, and inversely loading a PWAD as an IWAD is also possible. For example, CHEX.WAD and TNT.WAD have a PWAD signature despite serving as IWAD.

Directory
The directory associates names of lumps with the data that belong to them. It consists of a number of entries, each with a length of 16 bytes. The length of the directory is determined by the number given in the WAD header. The structure of each entry is as follows:

Tools should not assume the lump-order in the WAD to be sorted by their byte offset into the WAD.

"Virtual" lumps (such as F_START) only exist in the directory, having a size of 0. Their offset value therefore is nonsensical (often 0).

It is possible for more than one lump to have the same offset value, as well as having offsets that overlap other lump data.

When a modder imports lumps into a WAD from other files, file extensions are not included. Doom's executable examines only the name field to determine whether all required entries are present at launch. This means, for example, that the encoding of a music track may not be immediately obvious if the WAD's intended port supports multiple formats.

Typical wad file:

Compression
The Atari Jaguar port introduced a form of LZSS compression for lumps. If the first character of the name has the 0x80 flag set then it is considered to be compressed. The compressed size of the lump is not stored as the compressed stream has a terminating sequence. It should not be assumed that the compressed data is smaller than the uncompressed size since compression is required for some lumps in the console ports. (Likewise some lumps are required to be uncompressed in order to be read directly from cartridge ROM.)

The stream has a 12-bit sliding window. The format of the compressed stream is a flag byte followed by 8 chunks. The size of a chunk is determined by the flag byte in least significant bit first order. If the bit is not set then it is a uncompressed byte, otherwise it is a 16-bit offset length pair. The first byte of the pair is the upper 8-bits of the offset. The upper 4-bits of the second byte is the lower 4-bits of the offset. The remaining 4 bits are the length to copy. The offset is from the current output position (or from the end of the sliding window) and may overlap. Length is incremented by 1 so it becomes some value 1-16. If length is 1 then it is the end of the stream.

In order to know in advance how much information to read from the compressed lump, console versions of Doom which utilize this compression algorithm take the difference between the offset of the target lump and the next lump in the WAD directory. As a result, all such WAD files are terminated with an empty lump which marks the end of the directory, and has an offset equal to the end of the previous lump. This avoids undefined behavior if the last lump in the directory happens to be compressed.

Lump order
The majority of lumps have no restrictions on where they must be located in WAD files, although there are typically some guidelines to make the file easily readable by other people. For certain lumps, however, the location is crucial.

Map data lumps
A map in Doom is made up of several lumps, each containing specific data required to construct and execute the map. The first lump gives the internal name of the map. In Doom, this had to be in the form ExMy or MAPxx, where x and y could not exceed 4 and 9 respectively (Ultimate Doom), and xx could not exceed 32 (Doom 2/Final Doom). Other than defining the name of the map, the lump is usually empty but can contain data. The DOOM64.WAD file for Doom 64 EX, converted out of the Nintendo 64 ROM content, contains embedded IWADs in MAPxx lumps. In Hexen, they contain version control information; which is not used by the game but was presumably used by Raven Software's editing tools. SMMU introduced using it to store map information and FraggleScript. The level name marks the start of this map. In order to work properly, the following lumps must follow immediately, in that order, after the level name:


 * THINGS: A lump listing all the Things present in this map: their X and Y coordinates, starting angles, type and flags. In the Hexen map format, this lump also contains information on Z-height and a thing's TID, special, and arguments. As with all of these lumps, this list will be generated by your level editor and should generally be left alone.


 * LINEDEFS: A list of linedefs, defined by their starting and ending vertices, flags, type, tag, args, and front and back sidedefs (if any). Note: The standard Doom format does not contain args.


 * SIDEDEFS: A list of the sidedefs that are linked to the linedefs. These contain the data for what textures appear where on the side of each line, their X and Y offsets, and what sector this side of the linedef belongs to.


 * VERTEXES: A list of each vertex in the map, using X and Y coordinates.


 * SEGS: A list of line segments called "segs" that connect to form subsectors. Created by a node builder.


 * SSECTORS: A list of subsectors, created by a node builder.


 * NODES: The node tree which Doom uses to speed up the rendering process. Similar to a vismap in modern 3D games (such as Quake 3). Created by a node builder.


 * SECTORS: Defines the floor and ceiling heights and textures, as well as light value, tag, and type of each sector in your map.


 * REJECT: Optionally compiled by the node builder, this lump contains data about which sectors are visible from which other sectors. Originally, Doom used this to optimize the game speed by skipping AI routines for enemies whose target was in a rejected sector. Some modern source ports do not require this lump any more; ZDoom for example has been designed to work even without this lump present. For compatibility purposes, an empty (0-filled) REJECT lump should be included if nothing else. The REJECT lump can also be used to create certain special effects (sectors into which enemies cannot see, for example) if modified carefully.


 * BLOCKMAP: Collision-detection information which determines whether objects in a map are touching.


 * BEHAVIOR: Not originally a part of Doom, the BEHAVIOR lump was first used in Hexen and contains the compiled scripts that this map will use. Vanilla Doom and other ports designed for Doom only will crash when this lump is present because Hexen format levels are not compatible with Doom format levels. In Crispy Doom 2.3+ it is possible to load and explore maps in Hexen format, but all interactions with the environment are most probably broken. This lump must be present for Hexen format levels since it is the only way to tell if a map is in Hexen or Doom format.

Console port level lumps
Some of the console ports of Doom add additional lumps to levels in order to facilitate their extensions to the game engine:
 * LEAFS: Present in PlayStation versions of Doom as well as in Doom 64. Indexes non-rendered extra segs added to subsectors by the node builder to track edges of subsectors which do not correspond to linedefs. Enables rendering floors and ceilings as polygons.
 * MACROS: Present only in Doom 64. Stores compiled script bytecode for each map. Scripts may run at map start or be referenced individually by linedefs with a macro action flag.

Flats, Sprites, and Patches
These three resources must be located between special marker lumps so that Doom knows what it is looking at. Other than defining the beginning and end of a graphics section, these lumps contain no data and are 0 bytes long.

The markers consist of names X_START and X_END, where X is the first 1 or 2 letters of the appropriate resource. For example, sprites should be located between S_START and S_END markers. SS_START and SS_END are usually used for user WAD files.

These markers are required by DOOM:

These markers are found in the official WAD files, but are unused by known DOOM engines:

Patches are not required to have any markers. Some lump management utilities require P_START and P_END.

Console versions
Console versions based on the Atari Jaguar code base use an additional marker-defined namespace for storing textures: Each texture in these versions of Doom consists of a single patch between these markers (in differing formats per platform), and the TEXTUREx lumps used by the PC version do not exist.

Miscellaneous
Some lumps are known by their names and apply to the game as a whole. Some of these are:
 * Sound effects.
 * Music.
 * PLAYPAL: Color palettes for various situations.
 * COLORMAP: Map to adjust pixel values for reduced brightness.
 * ENDOOM: Text displayed when vanilla Doom exits.
 * TEXTURE1, TEXTURE2, PNAMES: Data defining the wall textures.
 * DEMOs: Recorded games, auto-played before any level is started.

Uses outside the Doom engine
Due to Doom's popularity and the simplicity of the format, many third party tools were written to manipulate WAD files very early on. This encouraged other game developers to adopt it even for unrelated games. Some even made use of the map format, though the values associated to thing, line, and sector types are usually completely different.
 * A.D. Cop and A.D. Cop: Overseas Missions (IWAD/PWAD signature replaced with PACK, additional lumps added to map format)
 *  some of the ETC resource files are actually PWADs
 * Amulets & Armor (only stores maps in WAD files, resources are in other containers)
 *  (only stores maps in WAD files, resources are in other containers)
 * Doom 2D (stores resources in WAD, but with different image and sound formats. It also supports LMP and PLAYPAL lumps)
 * Mars 3D
 * Rise of the Triad (stores resources in WAD, but with different image and sound formats)
 * Also of note is that the Nintendo Wii uses the .wad suffix for digital distribution such as WiiWare games, but this is (likely) coincidental and is an unrelated file format.