every line is a key, four find their sound, and the ding prints once

- the last app-side lines become GlobalStrings keys — tooltip cells, party, petition, duel, quest, PvP and rest lines read the install's own wording, so a non-enUS chain shows its own text (2045, 2080)
- a locked chest says Requires Pick Lock, ammo and thrown weapons drop their invented slot word, a met set bonus reads Set: without the count, and a 100 s cooldown reads 1.67 min as the template prints it
- the level-up block and the free-professions line printed twice in chat and print once; a declined invite, a friend coming online, a duel request and a failed quest play the sound 1.12 gives them
- Duel cancelled. is the yellow line at the top of the screen, and a trainer refusal or a failed quest with no cached template shows nothing, as on 1.12

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Sam
2026-09-08 16:19:46 +07:00
co-authored by Claude Fable 5.1
parent 520b6dc2aa
commit 663851b17d
54 changed files with 3874 additions and 1958 deletions
+20
View File
@@ -804,6 +804,26 @@ pub(crate) fn fire_chat_login(s: &mut benilla_ui::script::UiScript) {
}
}
/// The `benilla_formats::TokenContext::text` seam (decision 2045): resolve a `GlobalStrings` key
/// out of the VM and fill its `%d` holes through the one shared filler.
///
/// The split it implements is deliberate. `benilla-formats` walks the spell's columns and knows
/// which key and which numbers a `$d` or `$s` token wants; it has no business knowing about a
/// script VM or carrying a printf-family formatter, and it depends on neither crate that has one.
/// So it names the key, and this renders it.
pub(crate) fn token_text(
script: &benilla_ui::script::UiScript,
) -> impl Fn(&str, &[i64]) -> Option<String> + '_ {
|key: &str, args: &[i64]| {
let template = benilla_ui::strings::global(script.lua(), key)?;
let args: Vec<_> = args
.iter()
.map(|n| benilla_ui::strings::Arg::D(*n))
.collect();
Some(benilla_ui::strings::fill(&template, &args))
}
}
/// [`test_ui::load_ui`] for a test module OUTSIDE `ui_script` — `ui_action::feed_tests` drives the
/// real `UIErrorsFrame` end to end and needs the same both-stores reader everything else uses.
#[cfg(test)]