{
  "schema": "imperivm-format-article/v1",
  "language": "en",
  "scope": "Imperivm HD",
  "status": "partial",
  "slug": "pak",
  "title": "PAK · resource packages",
  "summary": "Resource container with a 40-byte header and a directory whose names share prefixes between entries.",
  "sections": [
    {
      "id": "purpose",
      "title": "Purpose",
      "paragraphs": [
        "A .pak file groups resource files. Here the extension refers to Imperivm's HMMSYS PackFile container; other games use different formats with the same PAK extension.",
        "The complete signature is 18 bytes: the text HMMSYS PackFile followed by a newline, byte 26 and a zero byte. Identify the container before interpreting its directory."
      ]
    },
    {
      "id": "header",
      "title": "Header",
      "table": {
        "columns": [
          "Byte position",
          "Size",
          "Contents"
        ],
        "rows": [
          [
            "0",
            "18 bytes",
            "HMMSYS PackFile signature and its three trailing bytes"
          ],
          [
            "18",
            "14 bytes",
            "Area whose complete meaning is not documented here"
          ],
          [
            "32",
            "uint32 LE",
            "Entry count"
          ],
          [
            "36",
            "uint32 LE",
            "Directory length in bytes"
          ],
          [
            "40",
            "Variable",
            "Directory start"
          ]
        ]
      },
      "paragraphs": [
        "LE means little-endian. Positions in this table are zero-based offsets within the file."
      ]
    },
    {
      "id": "directory",
      "title": "Directory entries",
      "list": [
        "TotalLen: one byte containing the complete name length.",
        "PrefixLen: one byte containing the length of the prefix shared with the previous name.",
        "Suffix: TotalLen − PrefixLen bytes containing the remaining name.",
        "Offset: a 32-bit little-endian integer containing the absolute position of the entry data in the PAK file.",
        "Size: a 32-bit little-endian integer containing the entry size."
      ],
      "paragraphs": [
        "Reconstruct a name using the indicated prefix of the previous name followed by the current suffix. Do not add the field at position 36 to Offset: that field measures the directory, and entry offsets are absolute."
      ]
    },
    {
      "id": "workflow",
      "title": "When inspecting or extracting",
      "list": [
        "Check the signature and that the complete header is present.",
        "Validate lengths and positions before reading each entry; do not accept a prefix longer than the previous name.",
        "Check that Offset and Size describe a range within the file.",
        "When extracting, preserve the relative hierarchy and reject absolute paths or .. traversal outside the output directory."
      ]
    },
    {
      "id": "limits",
      "title": "Known limits",
      "paragraphs": [
        "This entry describes the header, directory shape and current interpretation of its offsets. It is not a complete specification of malformed-file behavior or every possible variant.",
        "The area between the end of the directory and the first entry is not characterized here. A complete game-compatible repacking workflow is not documented either."
      ]
    }
  ]
}