re: GP_DIALOG 0/1 is a byte-identical duplicate; 2/3 is a structural pair

The two adjacent pairs with identical element sets split. 0/1 are the same 59 810
bytes stored twice -- a duplicate, not a language pair. 2/3, the DIFFICULTY build,
differ in size and in 2.77 % of bytes from offset 0x1BB while sharing every element
name, which is what a language pair looks like.

Control: entries 10/11, known to be two different dialogs, differ in 54.90 % of the
common prefix, so the comparator separates unrelated dialogs.

Supported, not proven, with the untested step named: I have not captured DIFFICULTY
in ja. That the two are ENGLISH and JAPANESE rests on the disc's convention, not on
a capture of this screen. This partially restores a claim I withdrew, at lower
strength than the original phrasing.

Also records a refutation attempt on the port's BGM_103 exclusion: it survives and
is tighter than they stated -- of 32 census rows, exactly one bank carries EITHER
wave size, not merely both.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wuu56cE8vJGTBtn1ppsk8v
This commit is contained in:
sylph-decoder
2026-08-31 03:12:59 +00:00
parent dc98fd1b2f
commit 7626f9e646
3 changed files with 104 additions and 0 deletions

View File

@@ -0,0 +1,47 @@
//! Are `GP_DIALOG` entries 0/1 and 2/3 a LANGUAGE PAIR or a DUPLICATE?
//!
//! They are the only two adjacent pairs in that archive with identical element
//! sets; every other adjacent pair is two unrelated dialogs. Left open as
//! "untested" — identical element names are equally consistent with a language
//! pair (same layout, different glyphs baked into the textures) and with a
//! byte-for-byte duplicate.
//!
//! The bytes decide it: identical entries are a duplicate; entries that share
//! every element name but differ in payload are a language pair.
//!
//! CONTROL: entries 10/11, known to be two DIFFERENT dialogs (stage 10 vs stage
//! 02), must come out as differing — and by a lot. A comparator that cannot
//! separate two unrelated dialogs cannot judge two similar ones.
//!
//! cargo run -p sylpheed-formats --example dialog_pair_identity
use sylpheed_formats::pak::PakArchive;
use std::path::PathBuf;
fn cmp(ar: &PakArchive, a: usize, b: usize, what: &str) {
let (Ok(x), Ok(y)) = (ar.read(&ar.entries()[a]), ar.read(&ar.entries()[b])) else {
println!("{what}: unreadable");
return;
};
let same_len = x.len() == y.len();
let n = x.len().min(y.len());
let diff = (0..n).filter(|&i| x[i] != y[i]).count();
let first = (0..n).find(|&i| x[i] != y[i]);
println!("{what}");
println!(" sizes {} / {} ({})", x.len(), y.len(),
if same_len { "equal" } else { "DIFFER" });
println!(" differing bytes over the common prefix: {diff} / {n} ({:.2}%)",
100.0 * diff as f64 / n as f64);
match first {
None if same_len => println!(" => BYTE-IDENTICAL — a duplicate"),
None => println!(" => one is a prefix of the other"),
Some(o) => println!(" => first difference at offset 0x{o:X}"),
}
}
fn main() {
let root = PathBuf::from(std::env::var("SYLPHEED_DISC").expect("SYLPHEED_DISC"));
let ar = PakArchive::open(root.join("dat/GP_DIALOG.pak")).expect("GP_DIALOG");
cmp(&ar, 10, 11, "CONTROL: entries 10/11 — known two different dialogs");
cmp(&ar, 0, 1, "entries 0/1");
cmp(&ar, 2, 3, "entries 2/3 — the DIFFICULTY build");
}

View File

@@ -837,3 +837,23 @@ screen. Checked against the disc, with the main menu as a control
**The claim survives**, and the control confirms the ordering rule reproduces a
screen whose answer is independently known.
### Refutation attempt on `sylpheed-port`'s `BGM_103` exclusion — ✅ SURVIVES, and is stronger (2026-08-31)
**Target:** their `audio.json` rests P6's most important value on three legs, two
of which they found to be a single disc-to-runtime comparison. The legs stand only
if the disc census **excludes alternatives** — they measured *"of 32 readable
`BGM_*` banks, exactly one carries waves of that size"*.
**My attempt:** re-derive the exclusion from the committed census
(`data/bgm-wave-census.txt`, produced by my own tool rather than their reader).
| | |
|---|---|
| census rows | 32 |
| banks carrying **both** 3 876 864 and 3 930 112 | **1**`BGM_103.slb` |
| banks carrying **either** size | **1**`BGM_103.slb` |
**The claim survives and the exclusion is tighter than they stated**: no other bank
carries *either* wave size, not merely not both. Their third leg is genuinely
discriminating.

View File

@@ -0,0 +1,37 @@
# Are GP_DIALOG entries 0/1 and 2/3 language pairs or duplicates? 2026-08-31.
# ✅ ANSWERED, and the two cases SPLIT.
#
# They are the only two adjacent pairs in GP_DIALOG with identical element sets;
# every other adjacent pair is two unrelated dialogs
# (difficulty-is-a-dialog.txt). Identical element NAMES are equally consistent
# with a language pair and with a byte-for-byte duplicate, so it was left
# untested. The bytes decide it.
#
# ✅ CONTROL: entries 10/11 are known to be two DIFFERENT dialogs (stage 10 vs
# stage 02). They differ in 54.90 % of the common prefix and in size. A
# comparator that cannot separate two unrelated dialogs cannot judge two similar
# ones -- this one can.
#
# entries 10/11 sizes 7 072 448 / 6 788 820 54.90 % of bytes differ
# entries 0/1 sizes 59 810 / 59 810 0.00 % -- BYTE-IDENTICAL
# entries 2/3 sizes 8 136 936 / 8 124 856 2.77 % differ, first at 0x1BB
#
# ✅ ENTRIES 0/1 ARE A DUPLICATE. Same size, zero differing bytes. Not a language
# pair -- the same 59 810 bytes stored twice.
#
# 🟡 ENTRIES 2/3 -- THE DIFFICULTY BUILD -- ARE NOT. Different sizes, 2.77 % of
# bytes differing from offset 0x1BB, while sharing EVERY element name. That is
# what a language pair looks like: one layout, one element set, and a small
# fraction of the payload differing where the glyphs live.
#
# ⚠️ SUPPORTED, NOT PROVEN, and the untested step is nameable: I have not
# captured DIFFICULTY in `ja`. What is established is "two builds, same element
# names, ~97.2 % identical bytes"; that they are ENGLISH and JAPANESE rests on the
# disc's pattern of shipping screens twice per language, not on a capture of this
# screen.
#
# 📌 This partially restores a claim I withdrew. I called 2/3 "an EN/JP pair" as a
# bare assertion, and withdrew it when sylpheed-port showed adjacent GP_DIALOG
# entries are generally unrelated. The withdrawal was right -- I had no evidence
# then. This is the evidence, and it is weaker than the original phrasing: a pair
# by structure, a LANGUAGE pair by inference from a disc-wide convention.