merge: absorb upstream/main into the Turtle fork

Fork policy (docs/METHOD.md): upstream structure wins; local-unique work
re-applied on top. This commit is the upstream half of the reconciliation.

Upstream is the same program at a rewritten history (884dff77 == 4e0e89cb
tree), so the merge base was replaced to keep a real three-way diff. The
large conflicts are upstream moving first: the UI manifest (benilla.toc ->
the binary LAYER_MANIFEST/layer.toc split), the CVar table (cvars.rs ->
cvars/{mod,table}.rs, +24 video rows), the editbox flush model, the
host-side GetTime, the Options* -> BenillaOptions* rename, expanded
ui_unit.rs, and a rebuilt volumetric_light.rs.

Local-unique pieces re-instated on the upstream structure:
- OptionsFrame.xml: the 1.12 OptionsFrameSliders table restored under the
  Benilla rename, with the TurtleWoW deviation note (patch-4 replaces
  OptionsFrame.lua).
- layer.toc: CharacterFrameAdapters.xml (the sixth TurtleWoW character tab).
- ui script: wipe/sizeof, BenillaGetMerchantItemStats, and the attach/mount
  teardown re-walk all survive.
- game_plugins.rs keeps UPDATE_ACTIONABLE_CEILING=5_509 (re-measure pending).

The LFT/Turtle_TransmogUI rows benilla.toc named off the player's install
now come from the chain's own FrameXML.toc via the new core loader.
This commit is contained in:
chairmanpow
2026-10-12 17:20:45 +01:00
604 changed files with 68323 additions and 19877 deletions
+3 -5
View File
@@ -50,10 +50,9 @@ awk -F'\t' -v ref="$REF" -v show_missing="$show_missing" -v show_beyond="$show_b
if (o == "engine" || o == "lua") have++
else if (o == "framexml") transcribable[$1] = 1
else {
# Categorize the superset. Only the last bucket is an API-target question; the first two are
# benilla being benilla, and the third is our Lua runtime being 5.1 where 1.12 is 5.0.
# Categorize the superset. Only the last bucket is an API-target question; the first is
# benilla being benilla, and the second is our Lua runtime being 5.1 where 1.12 is 5.0.
if ($1 ~ /^Benilla/) bridge[$1] = 1
else if ($1 ~ /^__/) internal[$1] = 1
else if ($1 ~ /^(_G|_VERSION|coroutine|print|select)$/) lua51[$1] = 1
else api[$1] = 1
}
@@ -66,7 +65,7 @@ awk -F'\t' -v ref="$REF" -v show_missing="$show_missing" -v show_beyond="$show_b
n_ref["engine"] + n_ref["framexml"] + n_ref["lua"]
printf " engine %5d functions, %5d other <- benilla implements these in Rust\n", \
n_ref_fn["engine"], n_ref["engine"] - n_ref_fn["engine"]
printf " framexml %5d functions, %5d other <- benilla transcribes these into assets/ui\n", \
printf " framexml %5d functions, %5d other <- the stock FrameXML defines these\n", \
n_ref_fn["framexml"], n_ref["framexml"] - n_ref_fn["framexml"]
printf " lua %5d functions, %5d other <- mlua provides these\n", \
n_ref_fn["lua"], n_ref["lua"] - n_ref_fn["lua"]
@@ -78,7 +77,6 @@ awk -F'\t' -v ref="$REF" -v show_missing="$show_missing" -v show_beyond="$show_b
printf "\nbeyond 1.12, by kind — every one of these is a deliberate exception or a bug:\n"
printf " %3d benilla host bridge Benilla*, called only by our own FrameXML\n", length(bridge)
printf " %3d VM internals __benilla_*, pushed by the tick\n", length(internal)
printf " %3d Lua 5.1 past 1.12'\''s 5.0 ", length(lua51); dump(lua51, "")
printf " %3d WoW API past 1.12 the phase-5 list\n", length(api)
printf " %3d ours in Rust that 1.12 defines in FrameXML\n", length(transcribable)
+2 -2
View File
@@ -95,7 +95,7 @@ esac
pflags=""
for p in $pkgs; do pflags="$pflags -p $p"; done
echo "check: scope = $pkgs"
echo "check: (changed crates + everything that depends on them; full chain still runs at sync→land)"
echo "check: (changed crates + everything that depends on them; the full chain runs once, at land)"
log="$(mktemp "${TMPDIR:-/tmp}/benilla-check.XXXXXX")"
skips="$(mktemp "${TMPDIR:-/tmp}/benilla-check-skips.XXXXXX")"
@@ -123,4 +123,4 @@ if [ -s "$skips" ]; then
fi
echo "CHECK GREEN (scoped: $pkgs)"
echo " (land still pays the full chain once: scripts/gates.sh — memoized, so an already-gated tree is free)"
echo " (the full chain, scripts/gates.sh, runs once on the tree that lands; a run before it repeats it)"
+16 -12
View File
@@ -1,11 +1,12 @@
#!/usr/bin/env bash
# The land gate chain: every gate in order, stopping at the first failure.
#
# fmt, clippy, test, test-no-install, doc-links, pass-span-lint, player-build, player-tests,
# enforcer, enforcer-no-install. A failure prints the gate's log tail and exits nonzero; a green
# fmt, clippy, test, test-no-install, doc-links, pass-span-lint, player-tests, enforcer,
# enforcer-no-install. A failure prints the gate's log tail and exits nonzero; a green
# run stamps the tree, which then re-greens without running. GATES_FORCE=1 runs the chain anyway,
# WOW_DATA picks the install (set and empty: none) and TMPDIR holds the scratch files; the script
# sets BENILLA_REQUIRE_DATA, BENILLA_SKIP_LOG and WOW_WORLDVIEW_CHECK for its gates.
# sets BENILLA_REQUIRE_DATA, BENILLA_ADDON_CORPUS, BENILLA_SKIP_LOG and WOW_WORLDVIEW_CHECK for
# its gates.
# `.github/workflows/ci.yml` runs the gates that need neither the install nor a display on a fork's
# pull request: a gate added here goes there too, if it can run on a bare Linux runner.
#
@@ -137,15 +138,18 @@ run doc-links scripts/doc-links.py
# wgpu validation error on Vulkan and a silent no-op on Metal and DX12, which no macOS run sees.
run pass-span-lint scripts/pass-span-lint.py
# player-build: `benilla` without `dev`, which compiles out the debug panel, perf HUD, inspector,
# capture harness and probes, so it fails when any other code names one of them.
run player-build cargo build -p benilla --no-default-features
# player-tests: the unit tests of the `cfg(not(feature = "dev"))` code (the resolver skips the
# source tree; the state folder sits beside the binary), which no other gate runs. WOW_DATA, which
# a player build reads too, goes in for the shipped-UI tests that read FrameXML off the install; no
# BENILLA_REQUIRE_DATA, since without `dev` only $BENILLA_ADDON_CORPUS finds the addon corpus.
run player-tests env ${wow_data:+WOW_DATA="$wow_data"} BENILLA_SKIP_LOG="$skips" \
# player-tests: the player build, `benilla-app` without `dev`, which compiles out the debug panel,
# perf HUD, inspector, capture harness and probes, so it fails when any other code names one of
# them. Its test build compiles every line of the player graph but the `benilla` launcher, a shim
# with no `dev` seam, so a `cargo build -p benilla --no-default-features` would add only the shim
# and a link. It runs the unit tests of the `cfg(not(feature = "dev"))` code (the resolver skips
# the source tree; the state folder sits beside the binary), which no other gate runs. WOW_DATA, which
# a player build reads too, goes in for the shipped-UI tests that read FrameXML off the install.
# Without `dev` only $BENILLA_ADDON_CORPUS finds the addon corpus, so the link goes in by that name,
# and BENILLA_REQUIRE_DATA refuses a skip here exactly where it does in `test`.
run player-tests env ${wow_data:+WOW_DATA="$wow_data"} \
${corpus:+BENILLA_ADDON_CORPUS="$root/wow-addons-vanilla"} \
${require_data:+BENILLA_REQUIRE_DATA=1} BENILLA_SKIP_LOG="$skips" \
cargo test -p benilla-formats -p benilla-app --no-default-features --lib
report_skips player-tests
+7 -6
View File
@@ -129,24 +129,25 @@ panics="$(printf '%s\n' "$plain" | grep -cE 'panicked at')"
[ "$errors" -ne 0 ] && fail "$errors ERROR line(s)"
# A marker counts once per edge it fires on. Each world entry builds a world VM beside the
# character screen's glue VM (the reference's `0x490bd0`/`0x48fbf0` pair), so per-VM markers count
# character screen's glue VM (the reference's `0x490bd0`/`0x48fbf0` pair), so the VM marker counts
# twice per login; half that means an entry adopted the glue VM and its spent `VmMemo`s.
sessions=2 # world entries in this walk
vms=$((sessions * 2)) # …and the Lua states they cost: a glue VM and a world VM each
for marker in "Fonts.xml loaded"; do
for marker in "new VM, session"; do
n="$(printf '%s\n' "$plain" | grep -cF "$marker")"
printf ' %-24s %s\n' "$marker" "$n"
[ "$n" -eq "$vms" ] ||
fail "'$marker' happened $n time(s), expected $vms — one per VM built, two per login; \
$sessions would mean the entry adopted the character screen's VM and inherited its spent VmMemos"
done
# The in-game UI and the keybinding table (`seed_bindings_for_vm`, run on the world-entry edge)
# build once per login; one count for two logins means the second reused the first's frame tree.
for marker in "UIParent.xml loaded" "commands registered"; do
# The in-game UI, `FrameXML.toc`'s `Fonts.xml` included, and the key-binding commands (the core's
# `Bindings.xml`, loaded after the toc) build once per login; one count for two logins means the
# second reused the first's frame tree.
for marker in "Fonts.xml loaded" "UIParent.xml loaded" "commands registered"; do
n="$(printf '%s\n' "$plain" | grep -cF "$marker")"
printf ' %-24s %s\n' "$marker" "$n"
[ "$n" -eq "$sessions" ] ||
fail "'$marker' happened $n time(s), expected $sessions — once per login: the UI rebuilt per login and the keybinding table seeded on the entry edge"
fail "'$marker' happened $n time(s), expected $sessions — once per login: the UI and its binding commands rebuilt per login"
done
# The shutdown tail runs once per session: at the /logout, and at the exit, which closes the window