RESC container (version 3.11)

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

Konami's named-entry archive. 48-byte TOC entries with reversed-ASCII names. Used by data/recipe/recipedata.lzs (the cooking recipe database) and a handful of other named-entry containers.

Variant of RESO that stores named TOC entries instead of type tags. Each entry is 48 bytes β€” that's what distinguishes RESC v3.11 from RESO v1.21 (which uses 16-byte entries for variant 0). The format is fully reverse-engineered and round-trip verified as of step-294 (2026-05-20); the canonical spec for the writer lives at notes/format_resc_v311.md in the translation repo.

Where RESC v3.11 appears

Outer wrapper (recipedata.lzs only)

On disk, recipedata.lzs is the SZL outer wrapper (1.00 magic + 9 zero bytes) followed by a 4-byte file tag and an LZ11 stream. The file tag at SZL +0x0C..+0x10 is file-specific for recipedata.lzs: b'\x00ser' (NOT the default b'sfo' that lzs.compress() emits). The writer preserves the original 4-byte wrapper word byte-for-byte. Other RESC v3.11 containers carry their own file-specific tags.

RESC v3.11 header (16 bytes)

OffsetSizeTypeFieldValue
0x004char[4]magic"RESC"
0x044u32 LEfile_countNumber of TOC entries (recipedata = 2)
0x084char[4]version"3.11"
0x0C4u32 LEvariantrecipedata = 0 ("type-tagged"). Variant 1 ("simple") is theoretically possible by analogy with RESO but not observed in this ROM.

TOC entry (48 bytes, variant 0)

Stride is 0x30 (48 bytes) β€” twice the entry size of RESO variant 0. Begins at file offset 0x10.

OffsetSizeFieldNotes
+0x0016type_nameUTF-8 name, byte-reversed within each 8-byte word. recipedata entry 0 = "recipelist", entry 1 = "recipepos".
+0x104unkObserved zero in all entries.
+0x144subtype_tag4-byte ASCII reversed (same encoding as RESO type_tag). Entry 0 stores b"tlcr" (reads as "rclt"); entry 1 stores b"\x00tad" (reads as "dat\x00").
+0x184lengthPayload bytes.
+0x1C4data_offsetAbsolute offset within the decompressed file.
+0x2012(padding)Zero.
+0x2C4fingerprint0x7C952298 in both recipedata entries β€” looks like a build-tool watermark, not load-bearing. The writer preserves it verbatim.

type_name byte-reversal convention

The 16-byte type_name field stores the human-readable name in 8-byte words, byte-reversed within each word. For "recipelist": word 0 holds "recipeli" stored as 69 6c 65 70 69 63 65 72; word 1 holds "st" plus zero padding, stored as 00 00 00 00 00 00 74 73. Reverse each word and you get the human-readable name. The writer is robust to this only at decode time β€” it doesn't need to write new type_name values because they're per-entry-type and unchanged across patches.

recipedata.lzs payload layout

Two entries: entry 0 "recipelist" is the recipe-menu UI strings (890 bytes), and entry 1 "recipepos" is binary recipe metadata (1,260 bytes β€” item IDs, quantities, slot positions; no translatable text).

Entry 0 "recipelist" β€” string table

+0x00  u32       record_count = 34
+0x04  N records of stride 12:
         +0x00  u32   text_offset (relative to start of entry-0 payload)
         +0x04  u8    recipe_id
         +0x05  u8    sub_id
         +0x06  u8    category_code
         +0x07  u8    subtype_code
         +0x08  u8    flag
         +0x09  u8    unk (always 0xff)
         +0x0a  u16   pad (always 0)
+0x04 + N*12  ... UTF-16-LE string blob, each string NUL-terminated

34 records. Strings are heavily deduplicated: records 21..33 (recipe_ids 0x64..0x70 β€” the 13 hidden Mysterious Soup placeholder slots) all share one string offset at 0x36a = "γ΅γ—γŽγͺγ‚ΉγƒΌγƒ—". The writer preserves deduplication: when two output strings are byte-identical, only one copy is emitted in the blob and both records point at it.

Entry 1 "recipepos" β€” binary metadata

1,260 bytes of pure binary recipe metadata β€” item_id refs, quantities, slot positions, ingredient combinations. No translatable strings. The writer copies this entry's bytes verbatim.

Alignment / padding

Entry-0 payload ends at entry0_off + entry0_len. Entry-1 payload starts at the next 0x10-byte-aligned offset. After entry-1's payload ends, the decompressed file is padded to the next 0x10-byte boundary with zeros. For recipedata.lzs: entry-0 ends at 0x3EA, entry-1 starts at 0x3F0 (6 zero bytes of pad); entry-1 ends at 0x8DC, file ends at 0x8E0 (4 bytes of trailing pad). Both alignments are enforced by the writer.

Round-trip safety

Calling the writer with an empty substitution map produces a decompressed output that is byte-identical to the input β€” verified in the writer's self-test (step-294). When substitutions are made, the string blob is rebuilt with deduplication preserved, each entry-0 record's text_offset is recomputed, entry-1's bytes pass through unchanged, and the final file is re-padded to 0x10 alignment.

Source