A WAD file is a header, the lumps’ data and a directory. Every number is a signed 32-bit little-endian integer, and every name is eight bytes.
Header
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
| 0 | 4 | ASCII | identification | IWAD for a game’s own data, PWAD for a patch WAD. |
| 4 | 4 | i32 | numlumps | The number of entries in the directory. |
| 8 | 4 | i32 | infotableofs | Where the directory starts, from the start of the file. |
The Doom source code calls the header wadinfo_t and gives the fields these
names. An invented PWAD of three lumps whose directory starts at byte 1000:
0identification50 57 41 44(“PWAD”)4 bytes4numlumps03 00 00 00(3)4 bytes8infotableofsE8 03 00 00(1000)4 bytes
Directory
The directory is numlumps entries of 16 bytes, one after another. The order
of the entries matters: it is how markers and maps group their lumps. The order of the
data in the file does not.
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
| 0 | 4 | i32 | filepos | Where the lump’s data starts, from the start of the file. |
| 4 | 4 | i32 | size | The lump’s size in bytes; 0 for a marker. |
| 8 | 8 | ASCII | name | Up to 8 characters, padded with zero bytes. |
0filepos0C 00 00 00(12)4 bytes4size00 03 00 00(768)4 bytes8name50 4C 41 59 50 41 4C 00(“PLAYPAL”)8 bytes
A name that fills all eight bytes has no zero after it. Names are upper case by convention; the games turn the name they look for into upper case and compare eight bytes. Some tools leave stray bytes after the first zero, which the games ignore and so does the explorer.
Nothing stops two entries from pointing at the same bytes, or at overlapping ones. Empty lumps usually have an offset of 0 or the offset of the lump after them. id’s own tools started every lump on a multiple of 4 bytes, so the IWADs have up to 3 unused bytes between lumps. The explorer shows shared data once, under the first entry that points at it, and the bytes no entry points at as padding or unused bytes.
Looking lumps up
The game reads every directory of every WAD it loads into one list, the IWAD first and
then each PWAD. It finds a lump by name by searching that list from the end, so the last
lump of a name wins: a PWAD’s PLAYPAL replaces the IWAD’s. Lumps that come
in groups are found by position instead: the lumps of a map follow its marker, and the
sprites and flats lie between their start and end markers.
Markers and namespaces
A marker is a lump of size 0 whose name says where a group starts or ends. Doom uses these:
| Markers | Between them |
|---|---|
S_START, S_END | Sprites: the pictures of things, in the picture format |
F_START, F_END, with F1_START to F3_END inside | Flats |
P_START, P_END, with P1_START to P3_END inside | Wall patches, which textures are made of |
The engine uses the S and F markers to find sprites and flats; the P markers only
organise the file, because patches are found by name through PNAMES. The
numbered inner markers are left from id’s tools and mean nothing to the game. Editors
for PWADs use SS_START and FF_START (with matching ends) for
sprites and flats meant to be merged with the IWAD’s, and later source ports added more,
such as ZDoom’s TX_START for textures.
Maps
A map is a marker lump with the map’s name, followed by its lumps in this order:
THINGS, LINEDEFS, SIDEDEFS,
VERTEXES, SEGS, SSECTORS, NODES,
SECTORS, REJECT, BLOCKMAP, and in Hexen’s format
BEHAVIOR. The game finds them by their position after the marker, not by
their names. Doom’s maps are named E1M1 to E4M9, Doom II’s
MAP01 to MAP32. The map
lumps page describes each one.