RESO container

DS game only γ¨γ‚“γŒγ‚Šγƒœγ‚¦γ‚·γ¨γŠγ—γ‚ƒγ‚Œγͺまほう぀かい The field guide documents the DS game's internals.

Konami's TOC-based archive: 16-byte header, N TOC entries (8 or 16 B each), payload region. 2,343 of 2,441 game files are RESO.

Used by both .ofs (raw) and .lzs (post-LZ11) files. Reference parser: src/archive/reso.py.

Header (16 bytes)

OffsetSizeTypeFieldValue
0x004char[4]magic"RESO" = 52 45 53 4F
0x044u32 LEfile_countNumber of TOC entries
0x084char[4]versionTypically "1.21" = 31 2E 32 31
0x0C4u32 LEvariant0 (type-tagged, 16-B stride) or 1 (simple, 8-B stride)

TOC entry β€” variant 0 (16 bytes)

Used by configuration-style containers like global.lzs, title_pack.ofs, sprite atlases.

OffsetSizeTypeField
+0x004u32 LEunk (often 0; in tad entries holds metadata)
+0x044char[4]type_tag (reversed ASCII β€” see below)
+0x084u32 LElength (payload bytes; 0 = empty slot)
+0x0C4u32 LEdata_offset (absolute offset within the RESO file)

TOC entry β€” variant 1 (8 bytes)

Used by message files (data/message/**/*.ofs), talkstart/*.ofs, and most plain data containers.

OffsetSizeTypeField
+0x004u32 LElength
+0x044u32 LEdata_offset

Type tag values (variant 0)

The 4-byte type_tag is reversed ASCII. Reverse to recover the Nitro / Konami magic identifier.

Stored bytesReversedMagicDescriptionCount in corpus
rgcnNCGRRGCNTile graphics4,337
rlcnNCLRRLCNPalette2,600
recnNCERRECNCell / OAM definition1,553
rcsnNSCRRCSNBG screen / tilemap1,128
rnanNANRRNANAnimation225
rtfnNFTRRTFNBitmap font1
ncbrNCBRRBCNLinear/bitmap NCGR variant1
szllzsβ€”Nested LZ11-compressed sub-RESO34,464
sfoofsβ€”Nested RESO (uncompressed)333
taddatβ€”Konami widget table (see Konami extensions)694
nibbinβ€”Per-container binary blob (variable schema)251
tbsnnsbtBTX03D texture pack (NSBTX)8,773
mbsnnsbmBMD03D model (NSBMD)297
cbsnnsbcBCA03D animation (NSBCA)35
ymddmyβ€”Dummy / placeholder script blob15,712

Payload region

Annotated hex dump β€” header + first 4 TOC entries

data/message/msg00/00/msg00000.ofs (variant 1, 100 entries):

offs  bytes                                              meaning
----  -------------------------------------------------- --------------------------------
0000  52 45 53 4F                                        magic = "RESO"
0004  64 00 00 00                                        file_count = 100
0008  31 2E 32 31                                        version = "1.21"
000C  01 00 00 00                                        variant = 1 (8-B stride TOC)

0010  08 00 00 00  30 03 00 00                           entry[0]: len=8, off=0x0330
0018  40 01 00 00  38 03 00 00                           entry[1]: len=320, off=0x0338
0020  EA 00 00 00  78 04 00 00                           entry[2]: len=234, off=0x0478
0028  20 01 00 00  62 05 00 00                           entry[3]: len=288, off=0x0562
... TOC continues for 96 more entries (100*8 = 800 bytes)
0330  ...                                                 payload region begins

Variant-0 example: title_pack.ofs

0000  52 45 53 4F  05 00 00 00  31 2E 32 31  00 00 00 00   header, file_count=5, variant=0
0010  00 00 00 00  6C 7A 73 00  00 F4 00 00  60 00 00 00   entry[0]: unk=0, tag="szl",
                                                            len=0xF400 (62464), off=0x60
0020  00 00 00 00  6C 7A 73 00  C0 5E 01 00  60 F4 00 00   entry[1]: tag="szl", len=89792
0030  ... 3 more 16-B entries ...
0060  11 10 27 00  ... LZ11 stream of inner RESO ...       payload[0] starts at 0x60

Decoder reference

# src/archive/reso.py
def parse(data: bytes) -> list[ResoEntry]:
    h = parse_header(data)
    stride = 0x10 if h.variant == 0 else 0x08
    entries = []
    for i in range(h.file_count):
        off = 0x10 + i * stride
        if h.variant == 0:
            unk          = u32(data, off + 0)
            type_tag     = data[off+4:off+8].decode("ascii")  # reversed
            length       = u32(data, off + 8)
            data_offset  = u32(data, off + 12)
        else:
            length       = u32(data, off + 0)
            data_offset  = u32(data, off + 4)
            type_tag     = ""
        entries.append(ResoEntry(i, type_tag, length, data_offset, unk))
    return entries

Cross-references