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
+16 -4
View File
@@ -378,11 +378,23 @@ pub struct UnitState {
///
/// One resolver, so the verb and the plate can never disagree about what a unit whose name is
/// still in flight is called (decisions 2002, 2040).
///
/// **Both halves of that tail are here, and both are load-bearing.** The lookup is the rule
/// (decision 2045: the sentence is the install's, not ours); the literal beside it is the
/// reference's own `0x860fa4`, which is what "a literal is legitimate only as a fallback beside a
/// lookup" means. Spelled `globals().get::<String>` — the shape `benilla-app`'s
/// `reference_strings` tripwire recognises as a resolver — so the fallback reads as the fallback
/// it is rather than as undeclared drift. It answers the same three cases the `mlua::Value` read
/// it replaces did: a non-empty string is returned, and both a missing global and a present-but-
/// EMPTY one take `0x860fa4` (the binary tests the pointer and then its first byte).
pub fn unknownobject(lua: &Lua) -> mlua::Result<mlua::String> {
match lua.globals().get::<mlua::Value>("UNKNOWNOBJECT") {
Ok(mlua::Value::String(s)) if !s.as_bytes().is_empty() => Ok(s),
_ => lua.create_string("Unknown Being"),
}
// One expression, deliberately: `globals().get::<String>` is what the tripwire matches on,
// and a line break inside it would hide this resolver from the walk again.
let global = lua.globals().get::<String>("UNKNOWNOBJECT").ok();
lua.create_string(match global.as_deref() {
Some(s) if !s.is_empty() => s,
_ => "Unknown Being",
})
}
/// The grey-band table `0x80ae98` (a byte-identical twin at `0x81dda8` drives the nameplate's