Warcraft II game engine uses this format for map files. External maps can be edited by official Warcraft II map editor and saved in .pud files. Maps supplied with the game (i.e. single player campaign) follow the same format, but are instead embedded inside the game container files.
There are two major versions: 0x11 (original one) and 0x13 (roughly corresponds to v1.33 of the game engine, although some of the features got limited support in v1.3).
File consists of a sequence of typed sections.
This page hosts a formal specification of Warcraft II map files using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.
digraph {
rankdir=LR;
node [shape=plaintext];
subgraph cluster__warcraft_2_pud {
label="Warcraft2Pud";
graph[style=dotted];
warcraft_2_pud__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
<TR><TD PORT="sections_pos">0</TD><TD PORT="sections_size">...</TD><TD>Section</TD><TD PORT="sections_type">sections</TD></TR>
<TR><TD COLSPAN="4" PORT="sections__repeat">repeat to end of stream</TD></TR>
</TABLE>>];
subgraph cluster__section_starting_resource {
label="Warcraft2Pud::SectionStartingResource";
graph[style=dotted];
section_starting_resource__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
<TR><TD PORT="resources_by_player_pos">0</TD><TD PORT="resources_by_player_size">2</TD><TD>u2le</TD><TD PORT="resources_by_player_type">resources_by_player</TD></TR>
<TR><TD COLSPAN="4" PORT="resources_by_player__repeat">repeat to end of stream</TD></TR>
</TABLE>>];
}
subgraph cluster__section_era {
label="Warcraft2Pud::SectionEra";
graph[style=dotted];
section_era__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
<TR><TD PORT="terrain_pos">0</TD><TD PORT="terrain_size">2</TD><TD>u2le→TerrainType</TD><TD PORT="terrain_type">terrain</TD></TR>
</TABLE>>];
}
subgraph cluster__section_ver {
label="Warcraft2Pud::SectionVer";
graph[style=dotted];
section_ver__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
<TR><TD PORT="version_pos">0</TD><TD PORT="version_size">2</TD><TD>u2le</TD><TD PORT="version_type">version</TD></TR>
</TABLE>>];
}
subgraph cluster__section_dim {
label="Warcraft2Pud::SectionDim";
graph[style=dotted];
section_dim__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
<TR><TD PORT="x_pos">0</TD><TD PORT="x_size">2</TD><TD>u2le</TD><TD PORT="x_type">x</TD></TR>
<TR><TD PORT="y_pos">2</TD><TD PORT="y_size">2</TD><TD>u2le</TD><TD PORT="y_type">y</TD></TR>
</TABLE>>];
}
subgraph cluster__section_type {
label="Warcraft2Pud::SectionType";
graph[style=dotted];
section_type__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
<TR><TD PORT="magic_pos">0</TD><TD PORT="magic_size">10</TD><TD></TD><TD PORT="magic_type">magic</TD></TR>
<TR><TD PORT="unused_pos">10</TD><TD PORT="unused_size">2</TD><TD></TD><TD PORT="unused_type">unused</TD></TR>
<TR><TD PORT="id_tag_pos">12</TD><TD PORT="id_tag_size">4</TD><TD>u4le</TD><TD PORT="id_tag_type">id_tag</TD></TR>
</TABLE>>];
}
subgraph cluster__section_unit {
label="Warcraft2Pud::SectionUnit";
graph[style=dotted];
section_unit__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
<TR><TD PORT="units_pos">0</TD><TD PORT="units_size">8</TD><TD>Unit</TD><TD PORT="units_type">units</TD></TR>
<TR><TD COLSPAN="4" PORT="units__repeat">repeat to end of stream</TD></TR>
</TABLE>>];
}
subgraph cluster__section {
label="Warcraft2Pud::Section";
graph[style=dotted];
section__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
<TR><TD PORT="name_pos">0</TD><TD PORT="name_size">4</TD><TD>str(ASCII)</TD><TD PORT="name_type">name</TD></TR>
<TR><TD PORT="size_pos">4</TD><TD PORT="size_size">4</TD><TD>u4le</TD><TD PORT="size_type">size</TD></TR>
<TR><TD PORT="body_pos">8</TD><TD PORT="body_size">...</TD><TD>switch (name)</TD><TD PORT="body_type">body</TD></TR>
</TABLE>>];
section__seq_body_switch [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#F0F2E4">case</TD><TD BGCOLOR="#F0F2E4">type</TD></TR>
<TR><TD>"SLBR"</TD><TD PORT="case0">SectionStartingResource</TD></TR>
<TR><TD>"ERAX"</TD><TD PORT="case1">SectionEra</TD></TR>
<TR><TD>"OWNR"</TD><TD PORT="case2">SectionOwnr</TD></TR>
<TR><TD>"ERA "</TD><TD PORT="case3">SectionEra</TD></TR>
<TR><TD>"SGLD"</TD><TD PORT="case4">SectionStartingResource</TD></TR>
<TR><TD>"VER "</TD><TD PORT="case5">SectionVer</TD></TR>
<TR><TD>"SOIL"</TD><TD PORT="case6">SectionStartingResource</TD></TR>
<TR><TD>"UNIT"</TD><TD PORT="case7">SectionUnit</TD></TR>
<TR><TD>"DIM "</TD><TD PORT="case8">SectionDim</TD></TR>
<TR><TD>"TYPE"</TD><TD PORT="case9">SectionType</TD></TR>
</TABLE>>];
}
subgraph cluster__section_ownr {
label="Warcraft2Pud::SectionOwnr";
graph[style=dotted];
section_ownr__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
<TR><TD PORT="controller_by_player_pos">0</TD><TD PORT="controller_by_player_size">1</TD><TD>u1→Controller</TD><TD PORT="controller_by_player_type">controller_by_player</TD></TR>
<TR><TD COLSPAN="4" PORT="controller_by_player__repeat">repeat to end of stream</TD></TR>
</TABLE>>];
}
subgraph cluster__unit {
label="Warcraft2Pud::Unit";
graph[style=dotted];
unit__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
<TR><TD PORT="x_pos">0</TD><TD PORT="x_size">2</TD><TD>u2le</TD><TD PORT="x_type">x</TD></TR>
<TR><TD PORT="y_pos">2</TD><TD PORT="y_size">2</TD><TD>u2le</TD><TD PORT="y_type">y</TD></TR>
<TR><TD PORT="u_type_pos">4</TD><TD PORT="u_type_size">1</TD><TD>u1→UnitType</TD><TD PORT="u_type_type">u_type</TD></TR>
<TR><TD PORT="owner_pos">5</TD><TD PORT="owner_size">1</TD><TD>u1</TD><TD PORT="owner_type">owner</TD></TR>
<TR><TD PORT="options_pos">6</TD><TD PORT="options_size">2</TD><TD>u2le</TD><TD PORT="options_type">options</TD></TR>
</TABLE>>];
unit__inst__resource [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">id</TD><TD BGCOLOR="#E0FFE0">value</TD></TR>
<TR><TD>resource</TD><TD>(options * 2500)</TD></TR>
</TABLE>>];
}
}
warcraft_2_pud__seq:sections_type -> section__seq [style=bold];
section_unit__seq:units_type -> unit__seq [style=bold];
section__seq:body_type -> section__seq_body_switch [style=bold];
section__seq_body_switch:case0 -> section_starting_resource__seq [style=bold];
section__seq_body_switch:case1 -> section_era__seq [style=bold];
section__seq_body_switch:case2 -> section_ownr__seq [style=bold];
section__seq_body_switch:case3 -> section_era__seq [style=bold];
section__seq_body_switch:case4 -> section_starting_resource__seq [style=bold];
section__seq_body_switch:case5 -> section_ver__seq [style=bold];
section__seq_body_switch:case6 -> section_starting_resource__seq [style=bold];
section__seq_body_switch:case7 -> section_unit__seq [style=bold];
section__seq_body_switch:case8 -> section_dim__seq [style=bold];
section__seq_body_switch:case9 -> section_type__seq [style=bold];
section__seq:name_type -> section__seq:body_type [color="#404040"];
unit__seq:options_type -> unit__inst__resource [color="#404040"];
}