This page hosts a formal specification of .dat file format of Fallout 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__fallout_dat {
label="FalloutDat";
graph[style=dotted];
fallout_dat__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="folder_count_pos">0</TD><TD PORT="folder_count_size">4</TD><TD>u4be</TD><TD PORT="folder_count_type">folder_count</TD></TR>
<TR><TD PORT="unknown1_pos">4</TD><TD PORT="unknown1_size">4</TD><TD>u4be</TD><TD PORT="unknown1_type">unknown1</TD></TR>
<TR><TD PORT="unknown2_pos">8</TD><TD PORT="unknown2_size">4</TD><TD>u4be</TD><TD PORT="unknown2_type">unknown2</TD></TR>
<TR><TD PORT="timestamp_pos">12</TD><TD PORT="timestamp_size">4</TD><TD>u4be</TD><TD PORT="timestamp_type">timestamp</TD></TR>
<TR><TD PORT="folder_names_pos">16</TD><TD PORT="folder_names_size">...</TD><TD>Pstr</TD><TD PORT="folder_names_type">folder_names</TD></TR>
<TR><TD COLSPAN="4" PORT="folder_names__repeat">repeat folder_count times</TD></TR>
<TR><TD PORT="folders_pos">...</TD><TD PORT="folders_size">...</TD><TD>Folder</TD><TD PORT="folders_type">folders</TD></TR>
<TR><TD COLSPAN="4" PORT="folders__repeat">repeat folder_count times</TD></TR>
</TABLE>>];
subgraph cluster__pstr {
label="FalloutDat::Pstr";
graph[style=dotted];
pstr__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="size_pos">0</TD><TD PORT="size_size">1</TD><TD>u1</TD><TD PORT="size_type">size</TD></TR>
<TR><TD PORT="str_pos">1</TD><TD PORT="str_size">size</TD><TD>str(ASCII)</TD><TD PORT="str_type">str</TD></TR>
</TABLE>>];
}
subgraph cluster__folder {
label="FalloutDat::Folder";
graph[style=dotted];
folder__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="file_count_pos">0</TD><TD PORT="file_count_size">4</TD><TD>u4be</TD><TD PORT="file_count_type">file_count</TD></TR>
<TR><TD PORT="unknown_pos">4</TD><TD PORT="unknown_size">4</TD><TD>u4be</TD><TD PORT="unknown_type">unknown</TD></TR>
<TR><TD PORT="flags_pos">8</TD><TD PORT="flags_size">4</TD><TD>u4be</TD><TD PORT="flags_type">flags</TD></TR>
<TR><TD PORT="timestamp_pos">12</TD><TD PORT="timestamp_size">4</TD><TD>u4be</TD><TD PORT="timestamp_type">timestamp</TD></TR>
<TR><TD PORT="files_pos">16</TD><TD PORT="files_size">...</TD><TD>File</TD><TD PORT="files_type">files</TD></TR>
<TR><TD COLSPAN="4" PORT="files__repeat">repeat file_count times</TD></TR>
</TABLE>>];
}
subgraph cluster__file {
label="FalloutDat::File";
graph[style=dotted];
file__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">...</TD><TD>Pstr</TD><TD PORT="name_type">name</TD></TR>
<TR><TD PORT="flags_pos">...</TD><TD PORT="flags_size">4</TD><TD>u4be→Compression</TD><TD PORT="flags_type">flags</TD></TR>
<TR><TD PORT="offset_pos">...</TD><TD PORT="offset_size">4</TD><TD>u4be</TD><TD PORT="offset_type">offset</TD></TR>
<TR><TD PORT="size_unpacked_pos">...</TD><TD PORT="size_unpacked_size">4</TD><TD>u4be</TD><TD PORT="size_unpacked_type">size_unpacked</TD></TR>
<TR><TD PORT="size_packed_pos">...</TD><TD PORT="size_packed_size">4</TD><TD>u4be</TD><TD PORT="size_packed_type">size_packed</TD></TR>
</TABLE>>];
file__inst__contents [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="contents_pos">offset</TD><TD PORT="contents_size">(flags == :compression_none ? size_unpacked : size_packed)</TD><TD></TD><TD PORT="contents_type">contents</TD></TR>
</TABLE>>];
}
}
fallout_dat__seq:folder_names_type -> pstr__seq [style=bold];
fallout_dat__seq:folder_count_type -> fallout_dat__seq:folder_names__repeat [color="#404040"];
fallout_dat__seq:folders_type -> folder__seq [style=bold];
fallout_dat__seq:folder_count_type -> fallout_dat__seq:folders__repeat [color="#404040"];
pstr__seq:size_type -> pstr__seq:str_size [color="#404040"];
folder__seq:files_type -> file__seq [style=bold];
folder__seq:file_count_type -> folder__seq:files__repeat [color="#404040"];
file__seq:name_type -> pstr__seq [style=bold];
file__seq:offset_type -> file__inst__contents:contents_pos [color="#404040"];
file__seq:flags_type -> file__inst__contents:contents_size [color="#404040"];
file__seq:size_unpacked_type -> file__inst__contents:contents_size [color="#404040"];
file__seq:size_packed_type -> file__inst__contents:contents_size [color="#404040"];
}