the spell owns its state, and a malformed file is refused, not a crash

- the spell owns its lifecycle state: the in-flight cast, the local cancel, the cooldowns and the spell-modifier tables live in one module (2328)
- a malformed MPQ, DBC, M2 or WDT file is refused instead of crashing the client, nine read sites bounded
- a test that needs the install or the addon corpus fails instead of skipping when the data is there; the Bagnon render suite runs again (2329)
- the dev crash injector is armed on every platform, and no instrument writes a path relative to the working directory

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sam
2026-09-23 12:08:33 +07:00
co-authored by Claude Opus 5.5
parent ac1084783a
commit c2d6f7c858
91 changed files with 2266 additions and 1813 deletions
+2 -2
View File
@@ -61,7 +61,7 @@ struct ViewCtx<'a> {
sub_classes: Option<&'a benilla_formats::ItemSubClassCatalog>,
/// The talent spell-modifier tables — the cost cell shows the RESOLVED cost, which since
/// `SPELLMOD_COST` landed means the modified one (`crate::ui_action::usable::power_cost`).
spell_mods: &'a crate::spell_mods::SpellModifiers,
spell_mods: &'a crate::spell::SpellModifiers,
/// The VM's own `GlobalStrings.lua` (decision 2045) — every cell this builder composes is a
/// key, and this is where they resolve. `text` is the `%d`-filling twin the `$`-engine's
/// keyed tokens take (`benilla_formats::TokenContext::text`).
@@ -444,7 +444,7 @@ fn feed_spell_tooltips(
// spell-modifier tables the cost cell resolves through.
lookups: (
Option<Res<crate::ui_items::ItemSubClasses>>,
Res<crate::spell_mods::SpellModifiers>,
Res<crate::spell::SpellModifiers>,
),
commands: Res<NetCommands>,
mut memory: Local<crate::ui_script::VmMemo<SpellFeedMemory>>,
+2 -2
View File
@@ -21,7 +21,7 @@ struct TestCtx {
text: Box<Filler>,
/// Empty tables, which is the un-talented character every cell here is graded as: the cost
/// cell's modifier hop must be the identity when nothing has been sent.
spell_mods: crate::spell_mods::SpellModifiers,
spell_mods: crate::spell::SpellModifiers,
}
/// The two lookup shapes, named so the harness's fields read.
@@ -39,7 +39,7 @@ impl TestCtx {
commands: NetCommands(tx),
_rx: rx,
get: Box::new(move |key| benilla_ui::strings::global(for_get.lua(), key)),
spell_mods: crate::spell_mods::SpellModifiers::default(),
spell_mods: crate::spell::SpellModifiers::default(),
text: Box::new(move |key, args: &[i64]| {
let template = benilla_ui::strings::global(for_text.lua(), key)?;
let args: Vec<_> = args