.pak file format of Games based on Haxe Game Framework "Heaps" (e.g. Dead Cells): GraphViz block diagram (.dot) source

Application

Games based on Haxe Game Framework "Heaps" (e.g. Dead Cells)

File extension

pak

KS implementation details

License: MIT

This page hosts a formal specification of .pak file format of Games based on Haxe Game Framework "Heaps" (e.g. Dead Cells) using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.

GraphViz block diagram source

heaps_pak.dot

digraph {
	rankdir=LR;
	node [shape=plaintext];
	subgraph cluster__heaps_pak {
		label="HeapsPak";
		graph[style=dotted];

		heaps_pak__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="header_pos">0</TD><TD PORT="header_size">...</TD><TD>Header</TD><TD PORT="header_type">header</TD></TR>
		</TABLE>>];
		subgraph cluster__header {
			label="HeapsPak::Header";
			graph[style=dotted];

			header__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="magic1_pos">0</TD><TD PORT="magic1_size">3</TD><TD></TD><TD PORT="magic1_type">magic1</TD></TR>
				<TR><TD PORT="version_pos">3</TD><TD PORT="version_size">1</TD><TD>u1</TD><TD PORT="version_type">version</TD></TR>
				<TR><TD PORT="len_header_pos">4</TD><TD PORT="len_header_size">4</TD><TD>u4le</TD><TD PORT="len_header_type">len_header</TD></TR>
				<TR><TD PORT="len_data_pos">8</TD><TD PORT="len_data_size">4</TD><TD>u4le</TD><TD PORT="len_data_type">len_data</TD></TR>
				<TR><TD PORT="root_entry_pos">12</TD><TD PORT="root_entry_size">(len_header - 16)</TD><TD>Entry</TD><TD PORT="root_entry_type">root_entry</TD></TR>
				<TR><TD PORT="magic2_pos">...</TD><TD PORT="magic2_size">4</TD><TD></TD><TD PORT="magic2_type">magic2</TD></TR>
			</TABLE>>];
			subgraph cluster__entry {
				label="HeapsPak::Header::Entry";
				graph[style=dotted];

				entry__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="len_name_pos">0</TD><TD PORT="len_name_size">1</TD><TD>u1</TD><TD PORT="len_name_type">len_name</TD></TR>
					<TR><TD PORT="name_pos">1</TD><TD PORT="name_size">len_name</TD><TD>str(UTF-8)</TD><TD PORT="name_type">name</TD></TR>
					<TR><TD PORT="flags_pos">...</TD><TD PORT="flags_size">1</TD><TD>Flags</TD><TD PORT="flags_type">flags</TD></TR>
					<TR><TD PORT="body_pos">...</TD><TD PORT="body_size">...</TD><TD>switch (flags.is_dir)</TD><TD PORT="body_type">body</TD></TR>
				</TABLE>>];
entry__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>true</TD><TD PORT="case0">Dir</TD></TR>
	<TR><TD>false</TD><TD PORT="case1">File</TD></TR>
</TABLE>>];
				subgraph cluster__flags {
					label="HeapsPak::Header::Entry::Flags";
					graph[style=dotted];

					flags__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="unused_pos">0</TD><TD PORT="unused_size">7b</TD><TD>b7</TD><TD PORT="unused_type">unused</TD></TR>
						<TR><TD PORT="is_dir_pos">0:7</TD><TD PORT="is_dir_size">1b</TD><TD>BitsType1(BigBitEndian)</TD><TD PORT="is_dir_type">is_dir</TD></TR>
					</TABLE>>];
				}
			}
			subgraph cluster__file {
				label="HeapsPak::Header::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="ofs_data_pos">0</TD><TD PORT="ofs_data_size">4</TD><TD>u4le</TD><TD PORT="ofs_data_type">ofs_data</TD></TR>
					<TR><TD PORT="len_data_pos">4</TD><TD PORT="len_data_size">4</TD><TD>u4le</TD><TD PORT="len_data_type">len_data</TD></TR>
					<TR><TD PORT="checksum_pos">8</TD><TD PORT="checksum_size">4</TD><TD></TD><TD PORT="checksum_type">checksum</TD></TR>
				</TABLE>>];
				file__inst__data [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="data_pos">(_root.header.len_header + ofs_data)</TD><TD PORT="data_size">len_data</TD><TD></TD><TD PORT="data_type">data</TD></TR>
				</TABLE>>];
			}
			subgraph cluster__dir {
				label="HeapsPak::Header::Dir";
				graph[style=dotted];

				dir__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="num_entries_pos">0</TD><TD PORT="num_entries_size">4</TD><TD>u4le</TD><TD PORT="num_entries_type">num_entries</TD></TR>
					<TR><TD PORT="entries_pos">4</TD><TD PORT="entries_size">...</TD><TD>Entry</TD><TD PORT="entries_type">entries</TD></TR>
					<TR><TD COLSPAN="4" PORT="entries__repeat">repeat num_entries times</TD></TR>
				</TABLE>>];
			}
		}
	}
	heaps_pak__seq:header_type -> header__seq [style=bold];
	header__seq:len_header_type -> header__seq:root_entry_size [color="#404040"];
	header__seq:root_entry_type -> entry__seq [style=bold];
	entry__seq:len_name_type -> entry__seq:name_size [color="#404040"];
	entry__seq:flags_type -> flags__seq [style=bold];
	entry__seq:body_type -> entry__seq_body_switch [style=bold];
	entry__seq_body_switch:case0 -> dir__seq [style=bold];
	entry__seq_body_switch:case1 -> file__seq [style=bold];
	flags__seq:is_dir_type -> entry__seq:body_type [color="#404040"];
	header__seq:len_header_type -> file__inst__data:data_pos [color="#404040"];
	file__seq:ofs_data_type -> file__inst__data:data_pos [color="#404040"];
	file__seq:len_data_type -> file__inst__data:data_size [color="#404040"];
	dir__seq:entries_type -> entry__seq [style=bold];
	dir__seq:num_entries_type -> dir__seq:entries__repeat [color="#404040"];
}