I wrote that nothing rewards closing the 37 pairs that differ without a button-count mismatch, and that a reader could not tell whether the bound was respected or merely convenient. They treated that as a prompt and closed it. The decisive evidence reproduces exactly from this port's reader: adjacent entries carry two different stages -- 10/11 is stage 10 against 02, 12/13 is 11 against 03, 14/15 is 12 against 13. Those are DLG_STAGE_TITLE01..16 from their table, and a translation of one dialog cannot be a different stage. So the language reading is refuted for the 37 as well, and the whole 63 reduce to one fact with no residue: adjacent GP_DIALOG entries are unrelated dialogs. Their second argument does not reproduce. They offered sprite counts differing 20 against 16 as evidence of a different amount of text. Counting .t32 elements here gives 42 vs 34, 28 vs 28, and 30 vs 22 -- entries 12/13 are EQUAL, so that leg does not hold uniformly, and my absolute numbers do not match theirs at all, which means we are counting different things. Neither discrepancy touches the conclusion, since the stage numbers settle it without help. Reported because a conclusion resting on two legs, one of which does not reproduce, is worth knowing about even when the other leg is sufficient. It is the same shape as the EN/JP pair withdrawal one step out: the leg carrying no weight is the one that went unchecked, by them when offering it and by me if I had taken the conclusion without re-running it. Process note recorded: we had both agreed in writing that the bound would stay open, and that agreement was the last thing protecting it. What broke it was saying out loud that nothing rewarded closing it. Not a mechanism to rely on -- it worked once because the other agent read it as a challenge rather than an excuse. Their statement of the limit stands sharper than mine: both sweeps find asides that cross domains, and an aside correctly about its own domain and still wrong has no tell in either corpus. Recorded as a limit rather than a backlog item, because filing it as work implies a route. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N7FiFFFwbvG2uxdcEh8HyF
88 lines
4.7 KiB
Rust
88 lines
4.7 KiB
Rust
//! Test the Decoder's UNTESTED reading of a residual they recorded as odd.
|
|
//!
|
|
//! `GP_DIALOG` holds 140 entries against a 70-record dialog table — a 2:1 ratio
|
|
//! that would make the id→entry join an ordering question. It does not hold:
|
|
//! adjacent pairing gives identical element-name sets on **2 of 65** pairs,
|
|
//! halves pairing on **0**. In `GP_TITLE` a language pair shares its element set
|
|
//! exactly, so identical sets are the signature there and almost nothing matches
|
|
//! here.
|
|
//!
|
|
//! The residual: the only two adjacent pairs that DO match are entries `0/1` and
|
|
//! `2/3` — and `2/3` is the DIFFICULTY build. Their plausible reading is that
|
|
//! dialog text is baked into language-specific sprites, so EN/JP entries differ
|
|
//! by construction. ⚠️ **They flagged it as untested and did not assert it**, and
|
|
//! it has a hole they named themselves: it would explain the 63 that differ and
|
|
//! leave the 2 that match needing their own explanation.
|
|
//!
|
|
//! This prints what the differences actually look like, so the reading is judged
|
|
//! against the names rather than accepted as plausible.
|
|
use sylpheed_formats::{pak, ratc, ui_layout};
|
|
use std::collections::BTreeSet;
|
|
|
|
fn main() {
|
|
let root = std::env::var("SYLPHEED_DISC").unwrap_or_else(|_| "/disc".into());
|
|
let ar = pak::PakArchive::open(format!("{root}/dat/GP_DIALOG.pak")).expect("GP_DIALOG.pak");
|
|
let sets: Vec<Option<BTreeSet<String>>> = ar.entries().iter().map(|e| {
|
|
let by = ar.read(e).ok()?;
|
|
if !ratc::is_ratc(&by) { return None }
|
|
let b = ui_layout::parse_build(&by)?;
|
|
Some(b.elements.iter().map(|el| el.name.clone()).collect())
|
|
}).collect();
|
|
|
|
let (mut same, mut diff, mut pairs) = (0usize, 0usize, 0usize);
|
|
let mut shown = 0;
|
|
for i in (0..sets.len().saturating_sub(1)).step_by(2) {
|
|
let (Some(a), Some(b)) = (&sets[i], &sets[i + 1]) else { continue };
|
|
pairs += 1;
|
|
if a == b {
|
|
same += 1;
|
|
println!(" entries {i:>3}/{:<3} IDENTICAL sets, {} element(s)", i + 1, a.len());
|
|
continue;
|
|
}
|
|
diff += 1;
|
|
// The stage-dialog pairs, checked by name and by SPRITE COUNT. A
|
|
// translation of one dialog carries the same amount of text; a
|
|
// different stage does not. This is the Decoder's closing evidence for
|
|
// the 37 pairs that differ WITHOUT a button-count mismatch, re-derived
|
|
// here because it settles a bound I had recorded as unlikely to be
|
|
// tested -- and saying so is what got it tested.
|
|
if (10..=15).contains(&i) {
|
|
let sp = |x: &BTreeSet<String>| x.iter().filter(|n| n.ends_with(".t32")).count();
|
|
let stage = |x: &BTreeSet<String>| -> Vec<String> {
|
|
let mut v: Vec<String> = x.iter().filter_map(|n| n.strip_prefix("pzstg")
|
|
.and_then(|r| r.get(..2)).map(|s| s.to_string())).collect();
|
|
v.sort(); v.dedup(); v
|
|
};
|
|
println!(" entries {i:>3}/{:<3} stages {:?} vs {:?} sprites {} vs {}",
|
|
i + 1, stage(a), stage(b), sp(a), sp(b));
|
|
}
|
|
if shown < 3 {
|
|
shown += 1;
|
|
let only_a: Vec<_> = a.difference(b).cloned().collect();
|
|
let only_b: Vec<_> = b.difference(a).cloned().collect();
|
|
println!(" entries {i:>3}/{:<3} differ: {} only-in-first, {} only-in-second",
|
|
i + 1, only_a.len(), only_b.len());
|
|
println!(" first : {:?}", &only_a[..only_a.len().min(4)]);
|
|
println!(" second : {:?}", &only_b[..only_b.len().min(4)]);
|
|
}
|
|
}
|
|
// 🔴 THE DECISIVE DETAIL, not the impressionistic one. Two languages of one
|
|
// dialog cannot differ in BUTTON COUNT. If adjacent entries do, they are
|
|
// different dialogs and the whole adjacent-pairing premise is wrong -- which
|
|
// is a stronger statement than "the language reading is untested".
|
|
let btns = |s: &Option<BTreeSet<String>>| -> usize {
|
|
s.as_ref().map_or(0, |x| x.iter().filter(|n| n.contains("btn")).count())
|
|
};
|
|
let mut mismatched = 0;
|
|
for i in (0..sets.len().saturating_sub(1)).step_by(2) {
|
|
if sets[i].is_none() || sets[i + 1].is_none() { continue }
|
|
if btns(&sets[i]) != btns(&sets[i + 1]) { mismatched += 1 }
|
|
}
|
|
println!("\n adjacent pairs whose BUTTON COUNTS differ: {mismatched}");
|
|
println!(" A language pair cannot. Every one of these is two different dialogs.");
|
|
println!("\n {pairs} adjacent pair(s): {same} identical, {diff} differing");
|
|
println!(" Their reading -- text baked into language-specific sprites -- predicts");
|
|
println!(" the differing names look SYSTEMATIC (a locale suffix, a parallel set).");
|
|
println!(" Judge it against the names above rather than against its plausibility.");
|
|
}
|