Files
Sylpheed/docs/re/structures/cutscene-message-table.md
Sylpheed RE agent cddf1deedb re: the sound-cue table, and cutscene dialogue's speaker/portrait/timing
dat/tables.pak holds a 5798-entry SOUNDS record (cue name -> sound id) and a
5135-entry FILES record (.slb bank paths). Cue names are the join key, so a
script message id now resolves all the way to the bank that voices it:
MSG_VOICE_D_257 -> VOICE_D_257 -> 6945 -> jpn\etc\VOICE_D_257.slb.

The prefix rule is MSG_ -> VOICE_, not strip-MSG_. My first rule was the
latter; it left 88 names unresolved and I was about to write those families up
as text-only announcements, until VOICE_TCAF_592.slb turned up in FILES and
refuted it. Corrected rule resolves 1326 of 1338, and SOUNDS and FILES agree on
exactly the same 12 absentees.

Separately, MSG_DEMO_* is driven by its own IDXD tables in the language packs,
which carry speaker, portrait, on-screen seconds and audio cue per page. Field
count is 9*PageCount+2 for all 7 distinct PageCounts; 1252/1252 caption-key
slots match <ID>_<page>_<line>; the 78 multi-page records equal the 78 counted
independently from the caption side; 138 ids close exactly against the caption
table both ways.

Does not settle the known VOICE_D_452 wrong-recording case -- every cue id is
distinct, so bank sharing is not happening at this layer.
2026-08-26 03:24:15 +00:00

4.0 KiB
Raw Blame History

The cutscene message table — speaker, portrait, timing and audio cue

Settled 2026-08-26. The MSG_DEMO_* family is not called from any stage script; it is driven by its own IDXD tables in the language packs. Those tables carry, per line of cutscene dialogue: who says it, which portrait is shown, how long it stays on screen, and which audio cue plays.

This answers the question left open by isl-message-dialogue-link.md — what drives cutscene dialogue, given that built-in 64 never mentions it.

Where it lives

32 IDXD objects per language pack (dat/GP_MAIN_GAME_<lang>.pak). Each holds a Generic record with a Count, plus some number of Message_NNN records — 149 in total across the English pack, covering 138 distinct ids.

Record layout

A Message_NNN record has two named fields, ID and PageCount, and then 9 positional fields per page:

slot content example
0 speaker CharacterNATALIE
1 portrait FaceNATALIE_01
2 constant None at all 149 records None
3 on-screen seconds, 1.00 5.00 (mean 2.48) 1.9
4 audio cue, or empty DEMO_017
58 the four caption keys of that page MSG_DEMO_600_000_00_03

The field count is exactly 9 · PageCount + 2, and that identity holds for every one of the 7 distinct PageCount values present (1→11, 2→20, 3→29, 4→38, 5→47, 6→56, 8→74). That is what pins the per-page grouping.

Evidence

  • 1 252 of 1 252 caption-key slots equal <ID>_<page>_<line> exactly, with zero mismatches. The grouping is not a guess about which slot is which.
  • 78 records span more than one page — which independently equals the 78 multi-page MSG_DEMO ids counted from the caption side, by a different method. Two measurements, same number.
  • In 68 of those 78 the speaker changes between pages, confirming from the data that successive pages are successive utterances rather than one long speech.
  • The id sets close exactly: 138 ids in the caption table, 138 in the message table, none on either side without the other.
  • 28 distinct speakers, 98 distinct portraits.

The audio cue (slot 4)

296 of 313 pages carry a cue, and there are 296 distinct values — one per page, never reused. It joins to the SOUNDS table described in sound-cue-table.md:

DEMO_017  ->  sound id 8017

The numbering rule is DEMO_nnn8000 + nnn, which holds for 286 of 286 plain-numeric cues. The 9 remaining cues carry a letter suffix (DEMO_067A, DEMO_190AC, DEMO_216AC, DEMO_278AB) and are assigned 84008408 in order. There is no unexplained residue.

Within a message, 77 of the 78 multi-page records number their cues consecutively; one does not.

A guess I had and dropped: slot 4 looked at first like a movie reference, since the values resemble the DEMO_nnn naming of a clip. It is not — there are 97 .wmv files on the disc and their names look nothing like this (ADV.wmv, RT01A.wmv), and the values are unique per page, which no movie reference would be.

What this does not settle

  • 17 pages have no cue (slot 4 empty). Silent, or voiced by another route, is unmeasured.
  • Slot 2 is None at all 149 records, so what it would hold otherwise is unknown — a constant with no observed variation carries no information.
  • 5 ids have more than one record (MSG_DEMO_600604), accounting for the 11 extra records over 138 ids. Whether these are context variants or duplicates was not investigated.
  • Nothing here was run. This is a static read of the tables; the playback order, and whether slot 3 is really the on-screen duration rather than an audio length or a delay, has not been checked against the running game.

Artifact

../data/cutscene-message-table.txt — all 313 pages with speaker, portrait, seconds, cue and text. Regenerate with tools/re-capture/sound_cues.py demo.