the addon arc: the AddOns folder opens

- benilla loads real 1.12 addons from Interface/AddOns — TOC, XML and Lua through one loader, with per-addon saved variables, Bindings.xml and the lifecycle events addons expect
- both AddOns screens are in: the character-select list with per-addon enable state, and the ESC menu's in-game list
- the API surface is measured, not guessed — a corpus harness runs hundreds of real 1.12 addons and ranks exactly which globals, templates and verbs they demand
- the Lua dialect is the client's own, read off the binary — 5.0 semantics with the 1.12 additions, and UI source files are bytes, not UTF-8

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Sam
2026-08-11 18:18:31 +07:00
co-authored by Claude Fable 5
parent bfb3e3addc
commit 44ff435304
231 changed files with 31316 additions and 5594 deletions
@@ -2027,7 +2027,7 @@ fn the_action_bars_page_locks_the_real_bar() {
);
s.fire_event("PLAYER_ENTERING_WORLD", vec![]);
s.resolve();
s.run("BenillaActionButton_OnDragStart(BenillaActionButton1)")
s.run("BenillaActionButton_OnDragStart(ActionButton1)")
.unwrap();
assert!(
s.cursor_payload().is_none(),
@@ -2037,7 +2037,7 @@ fn the_action_bars_page_locks_the_real_bar() {
// Defaults walks it back to ActionBar.xml's own assignment, and the bar drags again.
s.run("OptionsFrameContainerDefaults:Click()").unwrap();
assert_eq!(s.eval::<String>("return LOCK_ACTIONBAR").unwrap(), "0");
s.run("BenillaActionButton_OnDragStart(BenillaActionButton1)")
s.run("BenillaActionButton_OnDragStart(ActionButton1)")
.unwrap();
assert!(s.cursor_payload().is_some(), "unlocked again");
assert!(s.errors().is_empty(), "script errors: {:?}", s.errors());
@@ -2419,7 +2419,8 @@ fn the_status_bar_text_row_pins_the_numerals_the_moment_it_is_clicked() {
// The bar needs a real span before it decides anything about its numerals (its update bails
// on valueMax == 0 and hides the strip instead).
s.set_player_xp(1000, 10000);
s.run("BenillaExpBar_Update(BenillaExpBar)").unwrap();
s.run("this = MainMenuExpBar; MainMenuExpBar_Update()")
.unwrap();
// Shipped default: off, so the numerals only show while hovered.
assert_eq!(
s.eval::<String>("return GetCVar(\"statusBarText\")")
@@ -2427,7 +2428,7 @@ fn the_status_bar_text_row_pins_the_numerals_the_moment_it_is_clicked() {
"0"
);
assert!(!s
.eval::<bool>("return BenillaExpBarText:IsShown()")
.eval::<bool>("return MainMenuBarExpText:IsShown()")
.unwrap());
s.run("ShowUIPanel(OptionsFrame)").unwrap();
@@ -2446,7 +2447,7 @@ fn the_status_bar_text_row_pins_the_numerals_the_moment_it_is_clicked() {
// No repaint, no XP tick — only the CVAR_UPDATE the third argument queued.
s.tick(0.0);
assert!(
s.eval::<bool>("return BenillaExpBarText:IsShown()")
s.eval::<bool>("return MainMenuBarExpText:IsShown()")
.unwrap(),
"the watcher woke on the click, not on the next value change"
);
@@ -2456,7 +2457,7 @@ fn the_status_bar_text_row_pins_the_numerals_the_moment_it_is_clicked() {
.unwrap();
s.tick(0.0);
assert!(!s
.eval::<bool>("return BenillaExpBarText:IsShown()")
.eval::<bool>("return MainMenuBarExpText:IsShown()")
.unwrap());
assert!(s.errors().is_empty(), "script errors: {:?}", s.errors());
}