Commit Graph
7 Commits
Author SHA1 Message Date
Sam SungandClaude Opus 5.5 fd386e75ae Comments in benilla-ui: one line of fact each, no history, no record numbers (#143)
Part of #41: the comments of `benilla-ui` (the Lua UI engine, its FrameXML loader and its widgets) are rewritten to the rule in `docs/METHOD.md`, which is what the code does and the reference fact behind it, in a line. 43,140 comment lines become 15,161.

- **The mechanical strip.** The citations that were only a private record number go first, and each edit is shown to be a pure removal.
- **Wrong facts corrected.** The rewrite corrects the comments that stated wrong facts. Among them:
  - `0x64a480` is the case-sensitive compare (a byte `repz cmpsb`), and `0x64a4c0` the case-insensitive one.
  - A frame's id sits at `+0xb0`, not `+0xb4`. `EnableKeyboard`/`IsKeyboardEnabled` are `0x776ec0`/`0x776f90`.
  - A region's unpinned edge has no fallback to its owner's rect: the owner supplies only the scale.
  - `$parent` expands to the nearest named ancestor, or "Top" when none is named (`0x76c5b0`), not simply to the parent.
  - A StatusBar fills from its internal normalised fraction, not from `GetValue()`.
  - The addresses of `StartDuel` and `StartDuelUnit` were swapped.
  - Many "untraced" notes now give the traced reference fact: the drag threshold, the per-grip sizing edges, the empty-`autoFocus` skip, and `SetTexCoordModifiesRect`'s default.
  - Stock FrameXML line citations are checked against the stock 1.12 files and corrected. `ref-` file names become the stock file names.
- **Deviation labels.** "Deviation:" now marks only a choice with a reason. A surface that exists only for the retired Era addon target says so plainly: it is not 1.12.
- **Verification.** Every file strips to identical code, and `cargo fmt --check` is clean. Nine second readers compared every file old against new, restored the facts the rewrite had dropped, and checked each new citation against the code, the stock files, vmangos and the reference.

Behaviour differences the rewrite surfaced are filed as their own issues (#131–#142), and more are being validated. The comments here state what the code does. String literals are untouched; they are #92.

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

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 01:58:49 +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
SamandClaude Fable 5.1 5af3a15d0e plate text settles, mobs stop sinking, and select goes with Lua 5.1
- a nameplate's name and level stop popping a pixel every other step as the plate slides, and the whole plate no longer jumps 19 px to the top of the screen on a rounding tie; the chat bubble takes the same fix (2172)
- creatures and other players stop sinking through the ground while the world is still streaming in, where a Stormwind patroller had been 31 yd under its street: a body our world cannot yet answer for holds the server's pose (2174)
- select and the string metatable are gone, as in 1.12's Lua 5.0: pfUI's heal prediction parses its messages with the right format, BuffCheck2's own select wins its fallback, and a method call on a string raises the reference's own error (2171)
- the camera's water collision comes back out for now: with the pivot a hair under the plane, a surface swimmer's camera snapped in and out against the waterline, so the boom ignores water again (2173)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 21:03:05 +07:00
SamandClaude Fable 5.1 c34ea85c1b the character sheet is the reference's own file
- the character sheet is the reference's own — `CharacterFrame.xml`, `PaperDollFrame.xml` and `PetPaperDollFrame.xml` off the player's chain in the reference's own order, 2800 lines of ours deleted — and the one engine verb it needed had no pixels: a bare `<PlayerModel name="CharacterModelFrame">` drew nothing here, so the swap as written would have replaced a working paper doll with an empty rectangle, invisible to every loader and gap check; a `<Model>`/`<PlayerModel>` widget now draws its window's booth, keyed on the reference's own frame names, and the booth mirrors take their yaw off `PlayerModel:SetRotation`'s own state, which is what the reference's `Model_Rotate*` write
- what the stock file calls that was not there: `MicroButtonTooltipText(text, action)` (all five tab hovers), the two scripts `CharacterFrameTabButtonTemplate` carries — without them the five tabs are DEAD, since the reference's `PaperDollFrame` is `enableMouse` with a hit inset the tabs sit inside — `GetGuildInfo` on a recognised-but-unresolvable token answering `(nil, nil, 0)` rather than raising (`0x4c9330`), and `UnitAttackBothHands` pushing four values not two (`0x518810` calls the hand accessor twice; the reference's own Lua destructures two and says `FIXME` about the off hand, so no amount of running the sheet could expose it) — both skill verbs clamp a debuff deeper than the skill to zero as `0x5188a7` and `0x519298` do
- a gate for the question that bites AFTER a swap: for every chain window, census the bare `name(` call sites across it and its `.lua`, subtract what those define, keep what the reference's own `_G` carries, and require every survivor non-nil in a VM with the whole interface up — `LootFrame.xml` had shipped load-clean and raised at line 85, and the stock character sheet would have raised on the first tab hover; the stock sheet is driven end to end over a level-60 body with a +105 buff, a −12 debuff and a resistance school whose debuff outweighs its buff, at the rendered strings

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-02 17:02:55 +07:00
SamandClaude Fable 5 0cd0a28942 edit boxes take focus the way 1.12 does, and the stable shows its pets
- the caret was a wedge in the line: it sat in flow, four units wide, so focusing a login box shoved its text right by one caret and a caret parked mid-word opened a gap; it is a zero-width seam now with the bar drawn as an overlay (a 0×26 seam and a 5×26 bar at the same x, off a node probe), the way the reference anchors its caret quad over the FontString; a blurred box collapses its selection so only the box holding the keyboard shows one; and a dialog answers only keys pressed while it was already on screen — ENTER on an empty form used to open the error dialog and close it in the same frame
- `autoFocus` defaults ON in the reference (the ctor leaves flags = 1, and every one of the ten `autoFocus` attributes in the shipped chain is an opt-out), showing an autoFocus box focuses it after its `OnShow`, and hiding the focused box releases the keyboard — the "never focuses on show" note we had transcribed came from a `call`-only census that missed a tail `jmp`; the loader's flag loop could only ever turn a flag on, so `autoFocus="false"` was a no-op, fixed before the default flipped or it would have grabbed exactly the ten boxes the reference exempts; and the EditBox does fire generic `OnChar` with the spliced string, on every typed or pasted character and never on `SetText`
- the stable master's portrait was a black disc (its session was missing from the `"npc"` token chain — the third window to ship that way, so the test is now exhaustive over every `impl NpcSession` and names the one you forgot) and its model pane draws the selected pet: a stabled pet is a database row with no world entity, so a `PortraitStandIn(display_id)` — an entity that exists only to be mirrored — feeds the existing booth code unchanged; plus the registrar's two service rows were hidden by an inherited attribute, a charter's tooltip carries the guild name and master on line 3, and the Help window drops three strings pointing at a company that stopped answering

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-29 17:22:27 +07:00
SamandClaude Fable 5 dbf9d8057b a full realm is a queue to wait in, and the login dialog is centred
- a full realm answers with `AUTH_WAIT_QUEUE`, and it used to be read as a refusal; the grammar is length-branching exactly as the reference's handler has it, so both mangos body shapes parse; the estimate is the reference's own 8-sample ring — divide before multiply, signed, no timer — whose displayed figure climbs while the queue is silent, pinned by a test so nobody "fixes" it; the dialog is the ordinary status dialog relabelled `CHANGE_REALM` (which cancels back to the login screen: no realm list exists yet), and cancelling actually leaves the queue — the IO thread used to keep its place and walk on into character select on admission
- the stable master, corrected against the binary: a stabled-pet drag rides the shared cursor at payload mode 10 (the mode census had that row's label wrong), a plain click always returns 1 and a drop always nil, the summoned pet dropped on an occupied stable slot swaps (STABLE was refused whenever both bought slots were full, silently), an unpurchased slot takes nothing, the stabled→summoned fork reads the live pet guid not the row, the client itself sends `MSG_LIST_STABLED_PETS` on the interact leg, `PET_STABLE_SHOW` fires on every list, the selection is a petNumber and every list clears it, and result codes 2–7 do nothing at all
- the login dialog's text is centred (a FontString with no `justifyH` is CENTER, and `GlueDialogText` has none), the fifteen-year-dead "see www.worldofwarcraft.com" clauses are cut at the clause, the Login click sound is unconditional (the reference plays `gsLogin` before it checks the boxes), dialog buttons play `gsTitleOptionOK`, the realmlist button's `gsClick` never existed and is `gsLoginNewAccount`, and focusing a login box selects it — a stated divergence

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-29 17:21:50 +07:00
SamandClaude Fable 5 c0b7a613a9 the stable master is in, and master loot hands drops to the raid
- the stable master: `MSG_LIST_STABLED_PETS` both ways, the four mutations answered by one result byte, two slots priced from `StableSlotPrices.dbc` (500 and 50000 copper — the cap falls out of the data, corroborated by vmangos's `MAX_PET_STABLES` and the reference's `NUM_PET_STABLE_SLOTS`), rows seated by slot never by position (a petless hunter's list starts at a stabled row), slot 0 read from the wire because a dismissed pet has a row and no live unit, a re-list after every success because no result carries one, and `GetPetIcon` reading `CreatureFamily.dbc`'s icon column — which ships `Ability_Druid_CatForm` for both warlock families, asserted as shipped
- master loot: `CMSG_LOOT_MASTER_GIVE` (the slot is a byte here where the roll family's is a u32) and `SMSG_LOOT_MASTER_LIST`; the click gate is the wire's slot-type byte and nothing else — the reference never asks who the master looter is — so a MASTER row fires `OPEN_MASTER_LOOT_LIST` instead of a take and auto-loot skips every non-ALLOW row; the candidate array is bucketed by raid subgroup into blocks of five (a dense list would have filed every candidate under the wrong "Group N"), an unresolved name is nil so `UPDATE_MASTER_LOOT_LIST` has something to repaint, and a give re-checks the row is still MASTER before sending; found on the way: a master looter in another raid subgroup lit the crown on your own portrait
- `SetLootMethod` takes its third (threshold) argument; the reference's silent reset to Uncommon when it is absent is flagged and not adopted; the stable's model pane draws nothing yet — a stabled pet is a database row with no world entity, and a booth that renders from a bare display id is the next arc

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-29 17:19:45 +07:00