- the world map speaks the reference's names: WorldMapTooltip is declared (six corpus addons index it; pfUI dies on it at file scope), the blackout frame takes the reference's spelling BlackoutWorld, and the four hand-written party blips become the reference's own unit-blip templates — all 44 blips as instances, each with its published $parentIcon, the name pfUI recolours group blips by class through; the 40 raid ones are declared but not positioned yet, named in the OUT list rather than faked
- the templates addons build their own buttons from are published: ItemButtonTemplate, ContainerFrameItemButtonTemplate and the bag-slot chain — most of the handler scripts were live the whole time (this client executes the reference's own container and paper-doll code off the player's patch chain), so what was missing was mostly declarations, not behaviour — the bank arm stays out and is named as the omission it is; OptionsFrameSliders becomes real, with the three Graphics rows reading it and re-reading on show, so an addon's write to a slider's bounds actually moves the slider; and the template census that had ranked these at "zero demand" learns to see a local bound to a literal — its table went from 3 rows to 7
- the bindings answer in 1.12's own shapes: Button:IsEnabled() answers the NUMBER 1 or 0 (0 is truthy in Lua, so the reference's own == 0 tests got false forever, and three of our files had hand-worked around the divergence rather than fixed it); the constructors' string arguments are four shapes, not one rule — pfUI passes a Button where a template name goes and the reference constructs the FontString and ignores it; SetInventoryItem returns THREE values, the reference's own paper doll destructuring repairCost; UnitIsVisible is object presence and nothing else (57 bytes, one branch, no distance — an out-of-range party member is exists-yes, visible-nil); the tapped pair reads the two dynamic-flags bits, and its repaint wire fires UNIT_FACTION on the tap bit — the half a passing predicate test never sees; UnitIsPartyLeader is two ORed legs covering disjoint failures (a held stranger leading their own party, and an out-of-range member with no object to read a flag from); and the four nameplate verbs take no argument and return zero values
- the ghost's wisps compose onto its body instead of over it — the four emitters drew at full strength over a body at alpha 0.5, and now inherit the instance alpha down the attachment chain the way the reference recomposes it per frame; the residual we had parked ("the wisps should inherit the tint too") is REFUTED at the bytes: a particle batch commits hardcoded white RGB, and even that never reaches the fragment — particles are never tinted, only the alpha crosses, applied to the alpha byte alone — so the shipped shader split was already right and no code changes
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- the select screen's ghost is four mechanisms off one roster-row bit, and the rest of them land: the FFX pass swap — the reference builds TWO pass pairs, world and glue, and a ghost row installs the glue DEATH pass over the whole diorama while the character list and buttons composite clean above it; the ghost-gated sun — the scene's light gather is wiped and one hardcoded overhead directional injected, its colours turning out to be Light.dbc's death preset (diffuse (94,153,198), ambient (26,56,85)) rather than the live capture we had parked them as, with the sign settled at the bytes (an authored light already carries one negation, so reusing that convention lights the ghost from underneath); and three glow weights corrected — the glue screens pin 0.30 login / 0.40 living select / 0.15 ghost where we rendered a flat 0.5 everywhere, so login and create get slightly less glow too, a fidelity correction to a value we had never verified
- a press brings its window to the front: the mouse-DOWN handler raises the capture-or-hover frame unguarded, the toplevel gate living inside the worker — which is what makes a click on a child raise the window that owns it — and the release never raises; behind it, a frame-by-frame diff against the reference put back what the transcription dropped: toplevel on 47 frames (without it every raise trigger was a silent no-op across the whole interface), the mouse on 16 window bodies (a click on the bank's or merchant's own background was turning the camera or dropping your target), and id= on 81 frames — the slot index a 1.12 addon reads, where GetID() answered 0; a new gate reads our flags off the LOADED engine against the reference's, both directions with a reason each, so the next drift can't hide behind renamed templates
- the jump stops being frame-rate dependent: the fall step becomes the reference's closed form (the mean of the endpoint velocities is the exact displacement rate, and both our movers had the error in opposite directions), taking the apex from 1.668 yd at 144 fps and 1.844 at 20 to a flat 1.640 against the analytic 1.640 — a live run apexed at 1.6410; and the knockback's freeze is its PLANTED direction bit, not a velocity test — air control opens exactly while the direction nibble is clear, the launch plants forward whatever its speed, and the bit now rides the wire, which we had never sent at all
- the walk-away leash belongs to the OBJECT: the reference's watchdog overwrites the opener's stored range on the player typemask bit alone with (10+4)², so a player-shared quest panel is leashed at 14 yards — not at the 5.56-yard NPC reach, and not never, as two earlier readings had it — while a census of all 14 arming sites confirms every other NPC window already closed at the right distance; the walk-away also sends strictly LESS than the button: an NPC panel closes silently while a share still owes its decline
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- the transcription had dropped parent= on 72 declarations the reference carries (37 to UIParent, 28 to the action bar's art frame, 7 more), so the HUD was a field of top-level frames and UIParent:Hide() reached almost nothing — which is why a cinematic had to hide the UI at the draw level and then special-case the pointer; both workarounds are deleted and the HUD hides through the reference's own route; restoring only the UIParent half would have been the dangerous part (draw order is one flat sort, so a partial restore lifts frames over the neighbours they carry), and manifest order turns out to be load-bearing — a parent name that doesn't exist yet is silently ignored, so UIParent.xml moves to the reference's own slot with a test that fails if anything declares a child first; the chat still drew over a fly-by after all that, because the reference parents the chat windows on their TEMPLATE, invisible to a name-for-name diff when both sides rename — two declarations fix it, and the sweep that replaces the method loads the whole shipped manifest, fires CINEMATIC_START and asserts the survivors are exactly three: 91 frames visible before, 3 after, and the count comes back on stop
- every cinematic boundary cuts through the reference's 0.25 s fade to black, and the next step hangs on the fade's COMPLETION, not a delay — the shot boundary is exactly where the reference does a blocking terrain load, so a delay-driven cut shows through a hitch and a completion-driven one cannot; and a fly-by now ends into black instead of a ~0.3 s loading cover: the reference raises no cover on that path, it holds black while the ground under the player loads back, so ours holds black while the stream catches up — budgeted, never an unbounded wait
- the death arc keeps its promises across a relog: the body's own state machine now dies with the session — re-entering the world as a ghost used to match no arm of the world-edge machine, so the corpse query never went out and "Resurrect Now" stayed down until the next death; and a corpse wears its owner's guild crest — the corpse descriptor carries the guild field and resolves through the same crest cache a living tabard does, where ours dressed the body crestless
- the char-select ghost gets its body kit: the screen resolves the state kit of the very "Ghost" aura a released ghost rides in the world — tint (140,185,253), alpha 0.5, and the Ghost_state wisp model at the body's attach point, pinned by a golden that decodes the row out of the shipped DBC; the airborne model is corrected before its fix lands — the address six comments called the gravity integrator is really the fall-velocity query, and a knockback is unsteerable because its launch PLANTS the forward bit, not because the arc is airborne (our guard was a velocity proxy, so a near-zero-speed knockback steered from frame 2); and the hover inspect card now decodes a picked part's mesh tag — alpha, rig slot, and both readings of the lighting payload side by side — turning a rebuild-and-two-probes hunt into a hover
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- the combat log's last eight wire bodies decode — PARTYKILLLOG, SPELLINSTAKILLLOG, PROCRESIST, SPELLORDAMAGE_IMMUNE, SPELLDISPELLOG, DISPEL_FAILED, ENCHANTMENTLOG, SPELLLOGEXECUTE — each layout read off vmangos's own writer and pinned by a byte-exact golden (DISPEL_FAILED carries no count, the list runs to the end of the body; SPELLLOGEXECUTE's POWER_DRAIN row is (amount, power, multiplier), verified at the client's bytes as well as the server's); with the eleven chat types that were waiting on them, 44 chat types become 55 — 29 sentence families, the death pair and the aura rows riding descriptor diffs because 1.12 has no "unit died" opcode, plus the six trailers ((glancing), (30 blocked), (12 absorbed) and kin) that had been missing from every family; also corrected: the durability-death line was going to the red error frame with hard-coded English, and SMSG_SPELLNONMELEEDAMAGELOG lacked its split-damage branch and its blocked wording
- PlayerModel is its own frame kind: SetUnit, RefreshUnit and SetRotation were published on Model, but they belong to the <PlayerModel> method table (0x84f1fc), and the client's lookup chains derived → base only, so a plain <Model> can never reach them — they got there from a strings scan read as ownership, and a strings hit answers whether a name EXISTS, not who owns it (SetUnit's one pooled string is referenced by the PlayerModel and GameTooltip tables and by no Model entry); the new PlayerModel → Model → Frame → Region chain unblocks CreateFrame("PlayerModel"), which is how pfUI builds every unit-frame portrait — and through pfUI, pfQuest and ShaguDPS
- a nil where a number goes is four shapes, not one law: a census of all 408 widget-registrar entries found 62 numeric positions that validate-or-raise, 43 that gate then stage an alternate, 64 that silently coerce to 0.0 and 5 that gate then store nothing — so SetMaxLetters(nil) completes and stores 0, "no limit" (the argument COUNT is checked exactly, the type is not), and the backdrop colour setters are asymmetric on purpose: a nil r/g/b channel is 0.0 but a nil alpha is OPAQUE, and reading every nil as 0.0 would have turned those borders transparent; both setters now also quantize ×255 into the packed 0xAARRGGBB byte quad the client actually stores, so 0.09 reads back as 23/255
- two more addon-killers: LIGHTYELLOW_FONT_COLOR_CODE was the one missing line of Fonts.xml's seven-line colour block (aux-addon concatenates it at file scope and died on its own first line), and the guard now enumerates the whole block l.4-20 instead of the names an earlier round had noticed absent; and the unit frames publish the reference's names — 1.12 has no *PowerBar anywhere, every bar is ManaBar and the colour table is ManaBarColor (8 of the top-20 addons read it by name), so ManaBarColor is the published table our own bars index into, with 22 more regions renamed to the reference's own
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- the name cache persists to `benilla-config/cache/<realm>.tsv`, because the reference's `namecache.wdb` / `petnamecache.wdb` do and that is why it never sees the races we lost every time — unstabling a pet raised `Usage: SetText("text")` off an unresolved `UnitName("pet")`; the header carries magic, format, build, locale and realm and any mismatch discards the file (no checksum, no TTL: eviction is explicit only, via `SMSG_INVALIDATE_PLAYER`, decoded now and never sent by vmangos), negatives persist too, written on a 10 s debounce and at exit; a stable list also seeds the pet-name cache from the names it already carries
- `SMSG_NOTIFICATION` is the red UIErrorsFrame toast, not a chat line — `.gm on` printed twice because vmangos sends both a system message and a notification and both were rendered as chat; the stand-in dated from before the errors frame existed; `SMSG_AREA_TRIGGER_MESSAGE` moves with it on the yellow arm (its handler ends `xor edx,edx` — flag 0 — where the notification's is flag 1)
- the target frame's dead text is the GlobalString `DEAD` = "Dead" resolved through `text=` like the target-of-target frame, not the key typed into `SetText` in caps, and it takes `UnitIsConnected` so a disconnected player does not read as dead; a shipped-script sweep now refuses any key-shaped literal handed to a text sink; and the Help window is one click deep — Home's button opens the ticket text box, Auto-Unstuck sits beside it, and a ticket files as category 0, which a GM's queue names "Unknown" (a guard added days earlier refused 0 on reasoning from the enum rather than from the function that reads it)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- the target-of-target frame and its option: 1.12's frame with its five display modes, fed one hop off the selected unit's own target field through the same read `/assist` runs, in four feeds (snapshot and transitions, the debuff buttons, the portrait booth, TargetUnit's click arm); ships off, as 1.12 does, on its own pair of saved globals
- talents can be unlearned again: the trainer's `MSG_TALENT_WIPE_CONFIRM` had no handler since the wipe flow was deferred, so the gossip line closed the menu and did nothing — the question is an NPC session (walking away retracts it), the popup shows the cost on the StaticPopup money variant, Accept answers it behind the client's own purse check
- Sprint's sparkles hang in the air behind you along the trail instead of collapsing into your torso: ride-vs-trail is the emitter's own file flag 0x10, not the host class — the finding wow-re returned eighteen days ago and nobody folded; the particle dump names the two flag bits it had been mis-reporting
- `/sleep` takes both movement masks (the strictest posture), correcting the day's sit gate which let you lie down on a lake bottom while `/sit` was refused; a Lua-driven selection (TargetUnit on an attackable token) starts the swing exactly as a click does, through the one select path
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- party members appear on the world map at their position and hovering names them — the party wire has carried each member's zone and coordinates since the group arc; the blip and the minimap dot read one shared position so they can never disagree, and the member's zone picks which continent the position belongs to
- the player's own frame wears the leader crown and the master-looter icon, with the reference's own asymmetry (the crown asks IsPartyLeader, the member frames compare a leader index)
- a party member outside your local area gets the generic race/sex portrait instead of an empty circle — their race and sex ride the name query, and nothing had asked for a member we never see; the roster now warms that cache, which also fills the raid grid's class column
- right-clicking a member who is nowhere near grays Trade, Inspect, Duel and Follow: the reference's bindings answer nil for a unit the object manager does not hold (carved this session), where ours defaulted "absent = in range" for exactly the farthest member; and the group-invite popup's background is measured faithful — the plate draws at the BLP's own 60% alpha
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- forty files that carried the reference's literal Lua are rewritten as our own expression of the behaviour — worst identical run 61 lines down to 7 — and the README now says exactly that
- the overlap gate measures the code itself across all four reference corpora, and ratchets: the number may only go down
- a lost session ends at the login screen instead of silently re-authenticating and stealing the account back
- a building's skybox is a real model: Caverns of Time's white ceiling becomes its painted nebula and additive stars
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- the one shared region table splits into the client's own maps: a Texture no longer answers SetText, a FontString no longer answers SetTexture, and feature-detecting addons see the true surface
- CreateTitleRegion lands whole — object and drag — so an options window that is its own drag handle actually moves
- font-object names resolve whatever their case, and the CursorUpdate/CursorOnUpdate pair arrives for the container-item templates
- GetStringHeight is pruned (1.12 has no such method) and SetPortraitToTexture moves to the global it really is
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- every ranked list now states what it dropped and `--deep` reads the whole tail — a silent top-16 over 1,946 rows had already produced one wrong "nothing left" conclusion
- the backpack and equipped gear take their seats beside the spellbook, and a rankless spell's rank comes back "" rather than nil
- a FontString answers the full Region method map as one set — a text region's GetParent works — and RaidWarningFrame and PanelTemplates_Tab_OnClick arrive for the addons that name them
- SetRaidTargetIconTexture lands: the half of a raid mark an addon draws with
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- the workspace pointed at third_party/lua-src (the Lua 5.1 fork the addon VM builds on) and the export left that folder behind — every build of today's snapshots broke at dependency resolution
- third_party/ now ships, and the sync gained a gate that refuses to publish an export that does not resolve as a cargo workspace
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Lua 5.0's generic-for and nested long strings are restored in a forked VM — 60 corpus addons stopped dying on one deleted opcode
- a day of demand-driven carving takes the 218-addon corpus from 24 addons surviving a session start to 114, with 144 loading without a single error
- Bagnon draws a real bag and answers real gestures — hover tooltip, pickup, use, drag — because our frames wear the reference's names, and the reference's own ContainerFrame.lua runs off the player's install instead of being transcribed
- the physics broad phase leaves: nothing in the client reads a contact, and it was measured at up to 41% of main-thread samples in real sessions
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- 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>
- timed quests get their countdown — a Quest Timers box under the minimap and a Time Remaining line in the quest log, kept against the server's own clock
- interiors go honest: footsteps stop crunching the terrain's snow through a building's floor, and tavern voices are authored dry, so the fake cave echo is gone
- snow is the reference's again — point-sprite flakes at the era's pixel size, and a spawn slab that leans into your run so a runner no longer outruns the field
- Stormwind stops drawing Elwynn through its walls, a looted quest crate's lid settles, cold zones puff visible breath, and the collect-quest toast fires only on a real advance
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Mouse Sensitivity and Max Camera Distance are real settings now, not frozen constants
- Status Bar Text is wired through: value/max numerals on the player and pet frames' bars, live the moment the switch flips
- Shift+W walks — a modified press falls back once to the bare binding, the reference's own two-probe lookup
- the steep-face response is horizontal only, ending the extra slide when jumping nearly straight at a slope
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- the whole loop plays: the line arcs rod tip to bobber, the bite splashes with its own sound, and clicking the bobber reels in
- the verdicts read like 1.12: yellow "your fish got away" lines, the reel-in sound, the fishing loot window
- "You feel rested." prints on the transition, rest states come from the client's own Exhaustion table, and level 60 trades the XP strip for the max-level rail
- the Skills pane lists what the real client lists: the hidden rows, the sort, gray numberless single-rank lines
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- resting flashes the zzz on your portrait, the XP bar fills its rested blue, and the exhaustion tick rides the bar with hover numerals
- a dual-wielded pair keeps both hands in the dressing room
- a footfall plays one sound, not two
- the minimap wears the time-of-day clock, and the keybinding capsules go back to 1.12's red
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- ctrl-click an item to try it on: the dressing room dresses your double, and shift-click posts the item link to chat
- the pet tab lands in the character window: paper doll stats, family and diet, the right-click menu, and dropping food on the pet feeds it
- water-only spells refuse on dry land: aquatic form gates to swimming, client-side like the real one
- the macro icon picker's white squares get their art back, and option rows explain themselves on hover
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- drink enough and the screen blurs and your walk meanders, the camera carried along with the stagger; the underwater blur ships in the same lane
- boots leave prints on snow and sand that fade away in about six seconds, paws and hooves included
- key bindings move into the Options window with the rest of the settings, and action buttons abbreviate their hotkeys the way the client does
- the pet bar rearranges by drag, a running pet spell shows its active icon and a click cancels it, and spell ribbons follow their verified physics
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- the pet gets its own unit frame beside yours, and an Attack order no longer latches as the standing command
- five rooms that always read bone dry hold their water now, the Deeprun Tram's flooded stretches among them
- macros fire through the client's own chat door, and the macro window fits its tabs and scrolls its icon chooser
- the options window grows a Nameplates page and its first dropdown, and the name-display switches apply live in the world
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>