16 Commits
Author SHA1 Message Date
gromandClaude Opus 5 81d96af35d Everwood: the HD/OctoWoW line of benilla, imported onto upstream
This checkout had no git history at all, so this one commit carries the whole
of the Everwood work as a single import on top of chairmanpow/benilla-octo's
`main` (706cd71). The two trees have genuinely diverged — each has files the
other does not — so this is a fork point, not a catch-up.

Today's work, which is the reason a baseline exists at all:

- Booth previews no longer cast world shadows (`NO_BOOTH_SHADOW`). Portrait
  characters were entering the sun's shadow cascades, so every skinned-rig
  shadow specialization compiled live mid-frame; the hitch detector logged
  "main thread blocked 1316 ms" beside a `compiled LIVE` warning. This was
  the Fashion/Tmog stutter.
- Per-pane dress-up: each `DressUpModel` pane assembles and stages its own
  tried-on look instead of every pane mirroring the live player.
- Item template cache is append-only JSONL written on the IO pool, replacing
  an 11.6 MB whole-map JSON rewrite on the main thread every 10 s.
- `WOW_SYSTEM_TIMING` rebuilt per-thread: it took 2 mutexes per system enter
  and 4 per exit, costing 15 ms a frame (590 fps -> 60) and corrupting the
  measurements it was taken to produce.
- The visibility-churn sweep moved to its own `WOW_FLASH_CHURN` switch, so a
  frame-cost reading no longer pays 2.7 ms a frame for it.

Local state (`benilla-config/`, `logs/`, `target/`) is excluded by the
existing .gitignore; the account credential it holds is not in this commit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SgstFWtn1RxEJ5kVrpgYwn
2026-10-15 15:01:14 -06:00
chairmanpow 706cd717a3 merge: absorb samwhosung/main on top of the upstream merge
Same fork policy: upstream structure wins, local-unique re-instated.

Cargo.toml unions both measured dev-profile philosophies (codegen-units=1 +
lto=off from samwhosung, debug=line-tables-only + split-debuginfo from the
fork's disk measurements).

glue_booth.rs takes samwhosung's typed GlueScene (token/of_race/from_model_path)
and re-adds the fork's TurtleWoW races (Goblin=9, BloodElf=10) as variants;
their glue fog stays on Human's row, exactly as the fork's scene_fog fallback did.

ui script takes samwhosung's mouseover/hyperlink rework (world_mouseover,
minimap_blip, hyperlink.rs) over the fork's inline hover_link/span_at/pointer
path — the rework covers the same OnHyperlinkEnter/Leave behaviour.

game_plugins.rs keeps the fork's re-measured ceilings (466 / 5,509); mail.rs
keeps the explicit 13-tuple with a float daysLeft; MAP.md takes the superset.
2026-10-12 17:24:31 +01:00
chairmanpow 26d714fd1d 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.
2026-10-12 17:20:45 +01:00
Sam SungandClaude Opus 5.5 a9dd325bb7 A glue Lua state with the reference glue surface, events and ModelFFX (#963)
The first piece of running the stock GlueXML: benilla had no glue Lua state, and no reference data for its surface.

In 1.12.1 the glue state holds the base set (`0x7039e0`) and seven registrars (`0x46abb0`): 119 functions, 105 of them glue-only, with 26 glue events (`0xb41e70`, `0x46a88f`). `RegisterEvent` matches names case-insensitively and drops an unknown one (`0x702140`). The glue builds the 13 base frame types plus `ModelFFX` (`0x46a4fe`), a Model with its own show and paint (`0x46fa00`); the in-game types come only at world entry (`0x495940`).

`reference/` gains the glue event and surface tables, generated and checked against the shapes table. `UiScript::new_glue()` builds that state; a gate holds its globals to the table, with the 108 unbuilt names listed. Nothing in the app changes yet.

Part of #856

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 07:38:02 +07:00
Can H. Tartanoglu eecbf04d6e Normalize existing sources and documentation with treefmt
Apply the formatter baseline needed by the generated CI gate.

Verified the full treefmt check with vendored sources and generated MAP.md excluded. Parsed formatted Cargo manifests and compared their values with HEAD; all are identical.
2026-10-05 00:31:21 +02:00
Sam SungandClaude Opus 5.5 78a983b00e The VM speaks 1.12 alone: the Era globals and the uncalled hooks are gone, the engine's tooltip seams are Rust calls, strata/draw-layer/state-texture/sound/OnClick/quest-item/pickup take their 1.12 shapes, and the surface gate covers the production load (#573)
The Lua VM keeps no surface the 1.12.1 client lacks.

- **Removed:** the nine Era-only globals: `UnitAura`, `CancelUnitBuff`, `GetCursorInfo`, `GetInventoryItemID`, `GetPlayerFacing`, `GetTradePartnerName`, `IsGossipOptionCoded`, `UnitIsAFK`, `UnitIsDND`.
- **Hooks off Lua:** `GameTooltip:BenillaSetItemById` and `:BenillaGetTooltipOwner` are replaced by Rust-side calls. The uncalled `Benilla*` hooks are deleted.
- **Frame strata:** `SetFrameStrata` knows the reference's eight strata and raises its message for any other (`0x774450`).
- **`SetDrawLayer`** reads the layer name alone (`0x79a780`).
- **`Set<State>Texture`** reads a number as a path (`0x781b23`); there is no colour form.
- **`PlaySound`** names a kit and returns nothing (`0x4586d0`). `PlaySoundFile` returns one value (`0x458780`); benilla answers 1, a recorded deviation, since it plays after the call.
- **`OnClick`** sets only `arg1` (`0x779540`).
- **Quest getters:** `GetQuestItemInfo` and the quest-log reward and choice getters answer the reference's five values and its miss behaviour (`0x501f80`, `0x4e0b00`, `0x4e0cf0`).
- **`PickupContainerItem`** returns nothing (`0x4f9b30`).
- **Surface gates:** the bare VM's globals and every widget class's methods are held to `reference/1.12-globals.tsv` with one commented allowlist. A new gate on the full production load (core plus layer) allows beyond that only the layer's `Benilla`-prefixed globals.

Verified:
- A test per removal and per corrected form; a scripted undo of each fails its test.
- Each gate fails on a re-added name.
- `scripts/gates.sh` and `scripts/smoke.sh` are green.
- A live run showed the same warnings and 0 script errors before and after.
- In the 219-addon corpus, AckisRecipeList's bundled AceGUI-3.0 and Roid-Macros' Grid extension now behave as they do on 1.12.1.

Built on macOS; no platform seam touched.

Fixes #171

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 01:44:52 +07:00
Sam SungandClaude Opus 5.5 8952d590e6 comments cite the reference by address, not by private note (#30)
Comments that pointed into the maintainer's private reverse-engineering notes (a note by name, a
path, a section or finding id, the analysis's own name for a client function, a process word) now
carry the fact itself, cited by the reference client's address, by vmangos file and line, or as
"the reference". Nobody outside could follow those pointers.

Comment text only, plus the test-assert and log strings that carried the same pointers. No claim
changes: a comment the notes have since corrected keeps its wording here, and correcting it is
separate work.

The two reference generators, `scripts/gen-reference-globals.py` and
`scripts/gen-reference-verb-events.py`, named the private notes' layout to find their inputs. They
now take the input files as arguments (`--capture`, `--framexml`, `--names`, `--extents`,
`--disasm`). Run on the same inputs, both write the committed tables row for row; only the two
header lines that named the old environment variable change.

Checked per file:
- the code is identical: each file with its comments stripped compares equal before and after; a
  changed string literal is compared under a mask that proves only literal text moved and every
  literal kept its line count;
- no client address the old text cited was dropped;
- a second reviewer checked every added address against its derivation;
- a detector for the notes' names, paths, ids, function names and process words finds none left;
- `scripts/gates.sh` is green.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-24 12:14:08 +07:00
Sam SungandClaude Opus 5.5 7b66dac9db comments cite the reference by address, not by private note (#30)
Comments that pointed into the maintainer's private reverse-engineering notes (a note by name, a
path, a section or finding id, the analysis's own name for a client function, a process word) now
carry the fact itself, cited by the reference client's address, by vmangos file and line, or as
"the reference". Nobody outside could follow those pointers.

Comment text only, plus the test-assert and log strings that carried the same pointers. No claim
changes: a comment the notes have since corrected keeps its wording here, and correcting it is
separate work.

The two reference generators, `scripts/gen-reference-globals.py` and
`scripts/gen-reference-verb-events.py`, named the private notes' layout to find their inputs. They
now take the input files as arguments (`--capture`, `--framexml`, `--names`, `--extents`,
`--disasm`). Run on the same inputs, both write the committed tables row for row; only the two
header lines that named the old environment variable change.

Checked per file:
- the code is identical: each file with its comments stripped compares equal before and after; a
  changed string literal is compared under a mask that proves only literal text moved and every
  literal kept its line count;
- no client address the old text cited was dropped;
- a second reviewer checked every added address against its derivation;
- a detector for the notes' names, paths, ids, function names and process words finds none left;
- `scripts/gates.sh` is green.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-24 12:14:08 +07:00
SamandClaude Opus 5.5 7c17921601 comments: the generators, the tools and the reference table headers
Docstrings keep their usage and exit codes; table headers keep the
column contract and the client addresses and lose the dates, the
correction history and every path into another repository. A
generated header changes in its generator's template, so each of the
four generators still reproduces its output byte for byte, and no data
row changed in any of the seven tables.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-23 19:32:13 +07:00
SamandClaude Opus 5.5 73427e2068 comments: the generators, the tools and the reference table headers
Docstrings keep their usage and exit codes; table headers keep the
column contract and the client addresses and lose the dates, the
correction history and every path into another repository. A
generated header changes in its generator's template, so each of the
four generators still reproduces its output byte for byte, and no data
row changed in any of the seven tables.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-23 19:32:13 +07:00
SamandClaude Fable 5.1 23c14aaec1 the reference tables, the install guard and the vendored forks stop naming the maintainer's analysis
The notes and comments say what is true of the 1.12.1 client and cite the
byte address; the record numbers, the dates and the private repository's
file paths go.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-23 18:47:48 +07:00
SamandClaude Fable 5.1 9baf42d900 the reference tables, the install guard and the vendored forks stop naming the maintainer's analysis
The notes and comments say what is true of the 1.12.1 client and cite the
byte address; the record numbers, the dates and the private repository's
file paths go.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-23 18:47:48 +07:00
SamandClaude Fable 5.1 b05d5d18d5 a fresh clone gets the whole project, and the maintainer's tooling moves out
What a clone lacked: the gates went green with a thousand skipped tests and said nothing, every
login script assumed a worktree-pool slot and its probe account, the client defaulted to the
maintainer's account, a docker path and a home directory were in the code, the temp files broke
on GNU coreutils, and two generators could only run against a sibling repo.

Now the test gates print how many data-gated tests skipped and why; a scripted run logs in as
the account its checkout declares in `.probe-identity` or as the three variables name, never a
default, and the client refuses a scripted login on any other account; the event and message
tables regenerate from vendored inputs, byte for byte; the docs state the real prerequisites.

Out of the tree, into the maintainer's own tooling: the worktree pool, its hooks, the perf leg
runner, the cross-platform compile and the Vulkan container leg — a way of working, and setups
not every machine has. One hook stays: no writes into the install.

Two tests that could never run are gone with their subject: the quest-timer geometry diff
compared a copy of the window that no longer exists (and joined a chain path onto a folder, so
it always skipped), and the FrameXML flag gate now reads the stock files off the player's own
patch chain instead of an extracted folder only one machine had.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-23 17:27:14 +07:00
SamandClaude Fable 5.1 aff5203393 a fresh clone gets the whole project, and the maintainer's tooling moves out
What a clone lacked: the gates went green with a thousand skipped tests and said nothing, every
login script assumed a worktree-pool slot and its probe account, the client defaulted to the
maintainer's account, a docker path and a home directory were in the code, the temp files broke
on GNU coreutils, and two generators could only run against a sibling repo.

Now the test gates print how many data-gated tests skipped and why; a scripted run logs in as
the account its checkout declares in `.probe-identity` or as the three variables name, never a
default, and the client refuses a scripted login on any other account; the event and message
tables regenerate from vendored inputs, byte for byte; the docs state the real prerequisites.

Out of the tree, into the maintainer's own tooling: the worktree pool, its hooks, the perf leg
runner, the cross-platform compile and the Vulkan container leg — a way of working, and setups
not every machine has. One hook stays: no writes into the install.

Two tests that could never run are gone with their subject: the quest-timer geometry diff
compared a copy of the window that no longer exists (and joined a chain path onto a folder, so
it always skipped), and the FrameXML flag gate now reads the stock files off the player's own
patch chain instead of an extracted folder only one machine had.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-23 17:27:14 +07:00
SamandClaude Fable 5.1 3e12fa1d7f benilla is one repo: the working tree moves in, restructured
Until now this repo was an export of a private tree, pushed as squashed snapshots. From here on
it is the working tree itself, and the private repo is archived.

The root holds AGENTS.md and the Rust and GitHub files only. Everything an agent needs to orient
is in docs/: METHOD.md (the rules and how the project is built, 123 lines, project method only),
MAP.md (generated from the code at every land) and CONTRIBUTING.md (what gets in and how a
change is judged). One skill, `probe`, holds the procedure for running the client unattended
against the local server.

Brought over because the project needs it: reference/ (the 1.12 name catalogues 34 source
files read; the export failed its own tests without them), the gate chain and the pool
(scripts/), the hooks that enforce the install rule and the worktree rule, the full .gitignore,
the `cargo play` alias, and the original wording of eleven source files the export had reworded.

Left out: the decision records (archived with the private repo), the export tooling, the
operator's Discord and triage loop, the lab-laptop scripts and the instruments nothing
references, which live outside the repo now. What read the records is gone from the tooling:
no corpus lint, no records index, no `reserve` verb, no number-collision check.

Three hooks are gone: fmt-at-commit and the file-size nudge were redundant with the gates, and
the assets/ui guard is now a test (`assets_ui_does_not_grow`) that fails for everyone, not only
for a Claude Code session. The remaining pool hooks stand down on a machine without a pool.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-23 15:56:57 +07:00
SamandClaude Fable 5.1 64dc60f52f benilla is one repo: the working tree moves in, restructured
Until now this repo was an export of a private tree, pushed as squashed snapshots. From here on
it is the working tree itself, and the private repo is archived.

The root holds AGENTS.md and the Rust and GitHub files only. Everything an agent needs to orient
is in docs/: METHOD.md (the rules and how the project is built, 123 lines, project method only),
MAP.md (generated from the code at every land) and CONTRIBUTING.md (what gets in and how a
change is judged). One skill, `probe`, holds the procedure for running the client unattended
against the local server.

Brought over because the project needs it: reference/ (the 1.12 name catalogues 34 source
files read; the export failed its own tests without them), the gate chain and the pool
(scripts/), the hooks that enforce the install rule and the worktree rule, the full .gitignore,
the `cargo play` alias, and the original wording of eleven source files the export had reworded.

Left out: the decision records (archived with the private repo), the export tooling, the
operator's Discord and triage loop, the lab-laptop scripts and the instruments nothing
references, which live outside the repo now. What read the records is gone from the tooling:
no corpus lint, no records index, no `reserve` verb, no number-collision check.

Three hooks are gone: fmt-at-commit and the file-size nudge were redundant with the gates, and
the assets/ui guard is now a test (`assets_ui_does_not_grow`) that fails for everyone, not only
for a Claude Code session. The remaining pool hooks stand down on a machine without a pool.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-23 15:56:57 +07:00