293b8e57fbddb2fa7f2efca89c38b51c8a079e2e
218
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
293b8e57fb |
creatures keep their first corner, and characters never share files
- a creature walking a path no longer cuts its first corner: the path's first waypoint was dropped at decode (2342) - two characters whose names differ only in accented or non-Latin letters no longer share macros, bindings and SavedVariables; a file that failed to load is not overwritten at logout (2342) - custom chat channels survive a logout, a collapsed quest header keeps its quests watched, and a trackpad swipe scrolls as far as it adds up to (2342) - a hearth off a zeppelin no longer lands back on its deck, and an opened lockbox with loot left in it unlocks (2342) - every snapshot runs on Vulkan, in a container, before it ships (2344) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> |
||
|
|
9c49f10882 |
items are objects in the one index, and three more packets are answered
- an item is an object in the one index, and its enchant and lifetime countdowns are its own (2334, 2340) - the server's stand state applies, a bag equipped into a bag slot fires BAG_OPEN, and the inspect echo is dropped on purpose (2339) - the schedule census counts declared orders only, and the architecture walls gate leaks rather than the API (2337, 2338) - one queue for every event into the UI is not built: the reference orders its events per mechanism, not by the wire (2341) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> |
||
|
|
14eadba199 |
the spell owns its cast ladder, and landing checks the other platforms
- the cast ladder moves under the spell: try, target bind, the usable walk and the refusal rungs live in one place, and the cast reply sends a chained cast itself (2330) - every server packet decodes through one exhaustive match, and an opcode-coverage script joins the reference's 387 handled opcodes against ours (2331) - a landing that touches a platform seam compiles Linux and Windows first, and the seven WMO portal-cull audits join the tests (2331) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> |
||
|
|
d0e29635d0 |
the NPC, loot and quest windows register their handlers
- the six NPC windows — gossip, vendor, bank, trainer, stable master, taxi — register their own packet handlers and net/apply/npc.rs leaves the drain; a handler call measures ~25 ns, so the table can carry the busy families as it is (2318) - the loot window, the group rolls and the inventory refusal register theirs (2319), then the questgiver panels, the quest log and the party share (2320): 273 → 149 kinds in the dispatch match since the table opened - the show cascade is pinned against the reference's: ours notifies a parent before its children and snapshots the list, theirs is post-order and re-reads — a recorded gap, held by a test on the auction window (2317) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
5381a79842 |
PlayMusic and StopMusic are in, and an addon's own audio plays
- PlayMusic and StopMusic are in, one engine verb with a NULL arm as the reference has it: the track loops on the Music slider, the zone music fades out under it over 4 s and comes back 6 s after a stop (2309) - a PlayMusic whose file does not open leaves the zone track alone, and the server-pushed music slot is named — three fades the reference keeps apart that our one slot folds together, the next move (2315) - an addon's own sound file plays: every by-path asset read walks the patch chain, then the loose AddOns folder — the rule art and fonts already had, now one function that audio shares Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
66c9b1b243 |
widget calls cost one index, and a reparent keeps the layout ledger
- a frame's __index is its kind's method table and the Region map's 19 shared verbs dispatch in Rust: a widget method call costs one table index instead of a Lua re-entry — the idle UI tick ~20 % lighter, client-wide (2310) - SetParent names the subtree it moved instead of giving the layout ledger up: a pooled map note's recycle no longer re-derives the whole interface, and a Questie quest-log change's worst frame halves, 166 → 83 ms (2314) - thirteen single-store windows — honor, talent wipe, the dialog verbs, scoreboard, battlemaster, battle map, book, mirror timers, minimap ping — register their handlers; 18 kinds leave the match (2313) - the addon-enable RE lands: DefaultState is a seeded byte, the node set is the character list, and a character the store has never seen inherits nothing — 2311's one wrong branch corrected (2316) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
5916ec4b15 |
the create screen marks your pick, and a new character inherits addons
- the character-create screen marks the chosen race, gender and class again — a lit square and its name on the icon, as the reference's LockHighlight draws it; a query term had filtered all eighteen icons out since 2072 - a new character inherits the addon enables the realm's other characters agree on, as the reference computes them: a Disable All saved just before no longer comes back all-checked (2311) - an auction list-update event names one list: a first search on Browse no longer throws the stock Auctions tab's page error, and a sale or outbid notification never fetches a list the window never asked for (2308) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
aa207b4050 |
settings live in one registry, and the net drain starts to peel
- the CVars are one engine-side table that outlives every interface reload: a change fires its observer, the eight latched rows wait for RestartGx, and /console gains set, cvar_reset, cvar_default, cvarlist and help (2303) - every push into the interface runs in one feed phase after the net drain and before the tick, held by a structural test on the built schedule (2304) - subsystems own their packet handlers, dispatched in packet order; the auction house is the first family out of the 273-arm drain (2305) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
6019703a14 |
the battle map draws, and the talent modifiers land
- inside a battleground the battle map draws its terrain, overlays, arrow and blips: the world map's selection carries the instance maps as the reference's third cell (2298) - talent spell modifiers land: the 45 packets a level-60 login threw away fill the reference's two tables, and a spell's power cost reads them, so a cast you can afford is no longer refused (2298) - a ghost's Accept on the spirit-heal dialog can no longer be eaten by frame order, and a latched spirit guide no longer follows you into the next character's session (2298) - the battleground probe refuses GM mode, exits when done, and reads the scoreboard before toggling it (2298) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
00150c55b5 |
a crash leaves a report, and the wire's counts are capped
- a panic writes benilla-config/Diagnostics/crash-<time>.txt with the build id, the location, a backtrace and the last 200 log lines, and names the file as its last line, so a bug report can attach it (2266) - every wire-count allocation hint is capped and the compressed update object reads through the cursor, so a malformed packet can no longer ask for gigabytes (2266) - the 23 in-world run conditions are one set, the 45 probe variables one registry, the install-gated tests say when they skip, and every gate is timed (2266) - one workspace-level lint allowance replaces 413 per-site attributes, and the decision corpus gets a lint in the gate (2266) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
cbe8c8557c |
your own name survives the first login, and four cold pipelines warm
- your character's own name no longer goes missing on the first login of a fresh start, so KLHThreatMeter stops erroring: the four "player" verbs read the login record, as the reference does (2260, 2261, 2263) - four pipelines that compiled live mid-play now warm under the loading screen: the model tile atlas's orthographic view, the minimap composite's quad, the glow combine pair and the indoor pool's liquid layout (2262, 2264) - a hoverable sign seats its tooltip where its template says, at the cursor or in the corner, not by its object type: Brill's signpost still follows the cursor (2259) - three warnings that fired when nothing was wrong are quiet, and the lane-coverage gates walk every crate instead of one (2264) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
b7c1d84729 |
a nameplate takes a right-click, and four wrong verb rows come off
- a right-click on a nameplate selects and interacts again: the plate registers the right button, as the reference's does (2233) - the verb-events table files each fire site against its function's verified extent, and four rows it had misattributed are gone (2257) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
5bc2e19501 |
signpost tooltips survive the map, and the quest log stops blanking
- a signpost or mailbox tooltip shows with Questie loaded, and after opening the map: the cursor-seated plate carries an owner, so Questie's OnShow hook no longer hides it (2255) - picking up a quest whose template is not cached no longer blanks the quest log or jumps the selection: the missing quest is skipped, not the pass (2256) - the spellbook's skill-line tab flashes when a spell lands in it (2252) - the GPU meter's resolve rides the frame's own encoder, with no submit or poll of its own: −1.8 ms on Intel's DX12 driver when armed (2254) - the audio starvation watch no longer charges a stream's own spin-up as silence (2253) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
60138f5d5d |
every objective line shows, the detail follows the row, and 1.98 lints
- a quest objective that carries both a creature and an item is two lines in the quest log, as the reference's four passes enumerate it: Graverobbers shows its Embalming Ichor (2249) - the quest log's detail follows the live selection inside a frame, so a quest addon's log walk reads the right quest; Questie no longer files a chain quest under its shortest sibling (2247) - a UI tint change is not a material change: a run's colour rides the batch's instance tag, so the PlayerFrame glow no longer re-prepares a material every frame (2245) - the workspace lints clean on rustc 1.98: constant-size chunks become as_chunks, one slice fill, two unused globs - WOW_HOVER_PROBE aims the pick in a headless run, and the inspect card names the tooltip's ladder stage (2248, 2250) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
b249e6fbb6 |
learning a spell says so in chat, and the map's backdrop is back
- learning a spell prints "You have learned a new spell/ability/recipe" in chat, and unlearning one prints its line, on the reference's own gates (2243, 2246) - the world map's dark backdrop is back: the screen size is seeded before the interface loads, so BlackoutWorld is sized from the real window, not 1024x768 (2242) - the trainer filter repaints again: the engine fires TRAINER_UPDATE from inside the filter verbs, as the reference does (2244) - the zone channels, the keybinding table and the default language seed at the entry edge, before any addon asks (2241) - WOW_UI_COST=1 counts the frame's UI material asset events and names the first hundred modified (2236) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
1727b748ad |
the world gets its own Lua state, and the trainer follows the spell
- entering the world builds its own Lua state instead of adopting the character screen's, so a login one-shot fired into the frameless glue VM is spent again against the interface (2226) - after training, the trainer's detail pane moves on: the selection is the service's spell id, re-found by scan, and a filtered row is hidden, not removed (2231) - a spell's miss or resist floats in spell gold, and a travelling spell's word waits for the projectile; only a white hit's miss is white (2229) - a press that lands on a nameplate is the plate's: no freelook, no camera turn, the plate's own click slot (2233) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
58164abde7 |
right-click works on a nameplate, and the honor tab names your rank
- right-clicking a nameplate acts again: both buttons read the press pick, as the reference picks once on the down edge and never re-picks on release (2230) - the honor tab's Highest Rank and title name the rank: a rank title's team digit is the race, not the faction group, so a GM-flagged character keeps its rank (2227) - a raid's party feed watches only its members' descriptors, and the empty 2D opaque pass is skipped: ~0.7 ms a frame in a crowd (2225) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
ec3085ea42 |
names are a session, Martin Fury fires, and Windows gets its clocks
- player and pet names are a world session, not a file: the reference never persists them, so a character created after a server wipe no longer wears a deleted character's name (2223) - Martin Fury and every item whose spell targets where you stand raise the cursor and cast: the targeting word is a mask, not one bit (2218) - the guild line prints ahead of the realm's welcome lines by declared order, as the reference's chat latch paints it (2221) - the performance journal's CPU clocks answer on Windows, and a run with no install no longer panics on the cinematic narration (2219) - SetInventoryItem's nameOnly argument builds the reference's compact tooltip (2224) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
c494162113 |
the guild MOTD prints at login, and a maximize no longer crashes
- the "Guild Message of the Day:" line prints in chat at login: our own guild id arriving is not a guild change, and the guild feed waits for the interface it fires into (2214) - maximizing or resizing the window after entering the world no longer crashes the client: the dismissed loading tip asks for a re-shape (2212) - the vendor's compare plate is the worn item's full tooltip with one gray "Currently Equipped" line first, its name in its quality colour (2216) - the login chat drain waits for the chat frame it prints into, so a realm's welcome line is never lost one login in six (2220) - the GPU meter never resolves a query set nothing has stamped yet — the Vulkan device loss and hang the lab met (2211) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
1fc52f754b |
no hover compare, UnitIsPlusMob answers, and $parent names land right
- the shift-hover item compare is gone: 1.12.1 compares only from the vendor and auction rows, and the plate those seat picks its side so it never slides back over its own tooltip (2210, 2207) - UnitIsPlusMob is implemented, off the flag bit and not the creature rank, so an addon that calls it no longer raises (2209) - a top-level frame named $parentX with a parent= attribute is published under that parent's name, so ClassIcons loads (2208) - a parent= that resolves to nothing leaves the frame parentless and logs it, as the reference does, instead of falling back to the enclosing frame (2213) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
7ba4c7f0b9 |
loot rows wear their art, W holds through chat, and food greys in combat
- loot rows show their Quickslot border, depress on click and light up under the cursor: the stock `<LootButton>` is parsed by the Button loader, as the reference's vtable has it (2195) - holding W keeps you running through Enter to chat and M to close the map: a UI frame eating a key never releases a held movement binding (2196) - food, drink, bandages and mounts grey out on the action bar in combat: an ITEM slot runs its on-use spell's usable walk, and its cooldown gate is the item-keyed on-hold record (2200, 2201) - re-clicking the character you already have selected keeps its facing instead of snapping it square (2194) - the shift-compare plate seats beside the tooltip and is owned by the engine, so a stale plate never rides over the next hover (2202) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
eb9ecdcb3e |
the map opens full screen again after an addon windowed it
- the world map opens full screen again on a character that once ran Cartographer's windowed map: a saved frame position or size outlives the addon only while the frame is movable or resizable (2193) - the layout cache gates both the write and the apply on `userPlaced AND (movable|resizable)`, the reference's four sites, where benilla had only the setter's (2193) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
bd6b0282ab |
empty tooltips hide, the map opens on your zone, Questie's arrow lands
- Questie's arrow points at the turn-in, not 100 yards off: the map selection sits on your zone from the moment you enter the world, as the reference's does, so Astrolabe reads the right sheet (2192) - an area the map has no row for sends the selection to your continent, not the world view; the reference fails its zone lookup and its continent lookup separately - a tooltip shown with no lines hides itself instead of drawing an empty plate at the last hover's size, as Questie's tracker did on some quests; each fresh hover restores full alpha, so a plate an addon dimmed does not stay dim - Questie's minimap button turns the quest icons back on: a nil handed to a colour setter stores zero and carries on, as the reference does, where benilla raised and jammed Questie's event queue from login (1973) - MonkeyDev loads without three red dialogs at login: an unknown frame type in an addon's XML is logged and skipped, as the reference does; only a script creating a frame of a bad type still raises (2191) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
667d7cadb7 |
brightness saves, the glue box holds still, and Questie's notes hover
- the Brightness slider in the options window changes the picture and keeps its value; it was writing to no setting at all, so every reopen read 50% again (2186) - the login, realm and character screens share one letterboxed frame, so clicking down the character roster no longer slides the backdrop and every panel over it; at 4:3 nothing changes (2187) - Questie's world-map notes show their tooltip on hover: the note hands the tooltip a frame where an anchor name goes, which benilla refused with a script error and the reference reads as the default anchor (2176) - with OmniCC installed, a warrior in a stance sees the countdown on action bar 1 again: raising that bar's buttons by script carried their cooldown sweep up over the count (2189) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
e40a4084d5 |
camera rows land in Options, brightness arrives, /reload loses nothing
- fourteen settings get their switch on the Options window: the Camera box from Follow Terrain and Head Bob to Water Collision and Smart Pivot, plus Attack on Assist, Auto Clear AFK, Auto Self Cast, Enhanced Tooltips, Player Guild Names and Show Target Damage (2180) - the Graphics page gains Weather Intensity, scaling rain, snow and mist, and Brightness, applied as a final pass over the whole finished frame; GetGamma and SetGamma answer in the slider's unit (2181, 2182) - hovering a disabled button fires no OnEnter, no OnLeave and no highlight, as the reference's does, so AtlasLoot's unset QuickLook buttons stop throwing a Lua error on every hover (2183) - a chat window dragged, resized, recoloured or renamed just before a /reload keeps the change, and the meeting stone's minimap icon comes back after a /reload while you are still queued (2184) - swimming at the surface, the camera stops snapping into your character every couple of seconds: the water leg of the camera trace is a bare ray, as the reference's is, so the boom stops on the plane rather than a probe radius short of it (2185) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
9e528e6f86 |
the video options window goes stock, and water collision returns whole
- the reference's own video options window loads hidden, so pfUI's video skin and any addon reaching for its sliders and check buttons by name finds real frames; our own options window is BenillaOptionsFrame now, and ESC still opens it (2177) - GetScreenResolutions, GetCurrentResolution, SetScreenResolution, GetRefreshRates, GetVideoCaps, RestartGx and RestoreVideoDefaults answer off the monitor's own modes, so CT_Viewport loads clean (2177) - three of those verbs were corrected against a second read of the binary: GetRefreshRates answers nothing on a device with no rates, GetVideoCaps always gives a number for triple buffering, and RestoreVideoDefaults writes the ten rows the verb writes (2177) - the camera's water collision is back with both halves: the boom stops at a water surface, and a swimmer's camera keeps a constant 2/9 yd clearance over the waterline whatever the body underneath does (2179) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
e72016630c |
NTFS load order, a title-sorted AddOns list, and tooltips at the cursor
- addons load in the order NTFS lists a folder, case-insensitive with an underscore before the letters, the order the vanilla corpus was written against and the one that decides which addon provides a shared library (2178) - GetNumAddOns and the index form of every AddOn verb walk a title-sorted list that hides the Blizzard addons the server says to hide, and the character-select AddOns list is in title order (2175) - SetPoint and SetAllPoints raise the reference's own errors for a frame name that does not exist or an omitted relative frame instead of quietly anchoring to the parent, and an explicit nil means the screen root (2176) - a tooltip owned with ANCHOR_CURSOR follows the mouse, which pfUI's tooltip, xpbar and chat modules, pfQuest's browser and TipBuddy ask for; an omitted or unknown anchor is ANCHOR_LEFT (2176) - a $parent name handed to CreateFrame, CreateTexture or CreateFontString expands as it does in XML, so FonzAppraiser's thirty dropdowns and pfQuest's search icon get the names they asked for (2176) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
a61b9159ac |
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> |
||
|
|
64296b306f |
dodge, parry and block answer, and the camera boom stops at the water
- GetDodgeChance, GetParryChance and GetBlockChance answer the numbers the character sheet already had, so the addons that ask for them get a figure instead of a nil (2166) - with Follow Terrain on, pressing mouse-look no longer jolts the view: the terrain lean folds into the angle you drag and comes back out on release, and smart pivot holds its bias while a server-driven turn runs (2165) - entering water, the camera's pivot eases down to the model's own swimming height, so the eye no longer sits at a different height for the same zoom (2165) - the camera's water collision is back as what the option actually is: with it on, the camera boom stops at a bare water surface instead of passing through it; the pivot corridor that snapped last time is not rebuilt (2170) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
3b084ba052 |
pfUI's hdgraphic runs, the plates settle, and the water camera comes out
- pfUI's hdgraphic module runs: SetWorldDetail and GetWorldDetail are real verbs with the reference's three stops, and the near clip plane is a live setting at 0.100 yd rather than a frozen 0.111 (2163) - nameplates stop drawing a black box on hover or click, stop jittering a frame behind a moving creature, and a unit that walks into range later gets its plate; a unit with no level wears no skull, and the wheel zooms over a plate (2168) - the faint one-pixel box around every letter of a magnified overhead name is gone, each glyph now carrying its own transparent padding; interface text drawn at 1:1 is byte-identical (2169) - the camera's water collision comes back out for now: its pivot corridor dropped the camera a yard in one frame at head depth, which is the snapping reported around the surface while swimming (2165) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
5f5d0023a7 |
a melee spell's range is in yards, and item tooltips read their data
- a melee spell's tooltip says 5 yd range instead of Melee Range and grows with the reach of whatever you are auto-attacking; Heroic Strike and Bloodrage show no range line at all, as the reference does (2158) - an item's resistances list Arcane first, and its type word comes from ItemSubClass.dbc, so every container names itself: 24 Slot Soul Bag, 8 Slot Quiver, 6 Slot Ammo Pouch (2080, 2158) - weapon damage rounds the client's way, floor on the low bound and ceiling on the high, so Fang of the Mystics reads 38 - 86 not 39 - 86; ammo reads Adds 1.5 damage per second (2158) - an arrow's slot line reads Projectile | Arrow and a bullet's Projectile | Bullet, the word the reference takes from ItemClass.dbc where we printed the type alone (2158) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
6af2bfcb73 |
plates take the mouse, Auctioneer loads, and the damage font is yours
- hovering a nameplate lights its unit and clicking one selects it, pfUI's click-through works, a drag that starts on a plate still turns the camera, and turning plates off with V clears them (2159) - Auctioneer's XML documents open (the reference has no XML namespaces), a .toc line reaching Blizzard_AuctionUI's templates resolves for Auctioneer, BeanCounter and SpecialTalentUI, and a missing include logs rather than raising the red error dialog (2155) - a .lua reached through <Script file=> carries the same Interface\AddOns\ chunk name as a .toc-listed one, so Ace2's debugstack split works and AtlasLoot keys its database; 26 more corpus addons load, 176 of 219 (2155) - the floating combat numbers draw in whatever DAMAGE_TEXT_FONT holds at world entry, so MikScrollingBattleText and pfUI pick the font (2156); a dodged swing prints no line and floats no word, and happiness leech lines print (2157) - an unknown frameStrata in XML logs and keeps the default instead of raising, so EQL3's log window loads; FrameXML_Debug is a real switch, so ImprovedErrorFrame loads (2160) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
38e45badb9 |
nameplates are frames, guild names go overhead, and the camera pivots
- a nameplate is a real frame under WorldFrame, six regions and a health bar in the reference's order, so pfUI, ShaguTweaks and _Nameplates find and restyle plates instead of seeing none; the plate stays out of the mouse's way in this cut (2148) - a player's guild shows under their overhead name in angle brackets, the line an NPC's subname already used, gated by the UnitNamePlayerGuild option at its stock on (2149) - smart camera pivot is on, as 1.12 ships it: a mostly vertical drag with the camera pressed against something tilts the view instead of swinging the arm, easing home on release; in water the pivot rises for a swimmer (2149) - Follow Terrain and head bob are built and ship off, as in 1.12: Follow Terrain leans the camera up or down the slope you are walking onto, and head bob sways the first-person eye in a figure of eight while you move (2149) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
7d100d8a36 |
a bad macro fails on its own, and script errors name their frame
- a macro with a Lua error fails on its own and lands in the script error channel instead of aborting the UI function that ran it; RunScript names its chunk by the source text, and a bad or empty argument is a quiet no-op (2136)
- a script error or debugstack frame names its handler as Frame:OnClick instead of a whole CreateFrame sentence, an inline <Script> block is no longer mistaken for the .lua beside it, and a handler's line numbers stop reading one too high (2136)
- GetAddOnInfo and its seven siblings raise the reference's own Usage and out-of-range messages, GetAddOnInfo("2") is the second addon, and assert(a, b) answers one value, as the client's Lua 5.0 does (2139)
- frillDensity and gxApi are real settings: pfUI's hdgraphic module reads world detail through frillDensity, its system tooltip names the live render backend, and the two spellings of the ground clutter knob stay one knob (2151)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
||
|
|
e3c44456ce |
fourteen settings go live, /leave holds, and /assist can swing
- mouse-look speed is cameraYawMoveSpeed and cameraPitchMoveSpeed, so pfUI's afkcam does what it asks and an addon driving the stock Interface Options window runs its load and Defaults walks to the end; the shipped feel does not move (2147) - the eight combat-log range sliders are real settings, so BigWigs' Range plugin and DPSMate read and write them, and the Show Pet Melee Damage and periodic-spell settings genuinely silence what they gate (2147) - the stock Sound Options window loads hidden beside ours for addons to find, and its three check-box settings are real: the listener sits at your character, emote voices can be muted, zone music can loop without its silence gap (2147) - /assist with assistAttack set selects and starts swinging; /leave General survives a relog, a /join puts the channel back in its chat window's list, and SetGuildRecruitmentMode joins and leaves GuildRecruitment - City (2144) - wipe, strsplit, strjoin, strtrim, strconcat and tostringall are gone: no 1.12 client has them, and the addons that call them are multi-client builds whose vanilla path raises on the real client too (2146) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
fed2c96ec8 |
the mailbox takes typing again, and events carry their real arguments
- the mail window's send tab takes typing again: the subject, body and money boxes were taking no input while the recipient box swallowed every key, and a sent letter clears its subject and item icon instead of putting them straight back (2145) - seven events fire the way the reference does: UNIT_DYNAMIC_FLAGS fires at all, swapping two identical stacks between bank slots fires PLAYERBANKSLOTS_CHANGED twice, the pet sheet's training points repaint, and ITEM_LOCK_CHANGED loses its invented arguments (2140) - nine widget methods 1.12 addons probe for are in: ShaguTweaks stops recolouring textures the reference leaves alone, pfUI and _Nameplates stop raising on a tooltip's GetAnchorType, and 63 AceEvent addons get RegisterAllEvents (2142) - six post-1.12 methods leave the widget surface (SetSize, SetShown, HasFocus, SetFormattedText and two tooltip verbs), so an addon reaching for a later client's API finds what a real 1.12 client gives it (2142, 2146) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
3f3cf21afa |
a slider snaps to its step, a pushed button releases, and warnings show
- a slider with a value step snaps to it: a stepped drag fires once per row instead of once per pixel, a scrollbar cannot rest between two rows, and one wheel notch on the trainer list reaches the bottom (2133) - setting a step on a live slider moves its value onto the new lattice and runs its handler, which an addon on the real client can count on (2143) - a button pushed from script releases on the next mouse-up, so Tablet-2.0's rows stop staying pressed forever; a release off the button's rect un-presses it, and a locked state holds (2134) - the mail body and the GM ticket box scroll as you type past their bottom, and the Use UI Scale checkbox reads a registered setting (2141) - an engine warning, a call that was accepted and did nothing, reaches the /errors window in grey instead of one terminal line; a text row trimmed mid-character no longer kills the window's repaint (2135, 2138) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
505d1ac9c0 |
two addons that need each other load, and pfUI's memory row fills in
- loading two LoadOnDemand addons that depend on each other loads both instead of killing the client with a stack overflow; each is counted loaded before its own files run, as on the real client (2139) - the memory report gets its second number, so AceAddon-2.0's memory line (36 copies in the corpus) stops raising and pfUI's panel prints a figure where it printed UNAVAILABLE; garbage collection takes a number and answers nothing, like 1.12's (2136) - a disabled addon you have uninstalled keeps its row in AddOns.txt through a logout, and a hand-edited name keeps its spelling instead of taking the folder's case (2139) - a loaded chunk's error lines name it the way the real client does, and a /console argument containing ]] no longer trips a syntax error the 1.12 lexer would raise (2136) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
374bc5898d |
an addon's font draws in its own face, and Bartender2 keeps its profile
- text shapes in the face an addon asked for: MikScrollingBattleText draws in its own Porky instead of a system sans, and Arial Narrow and Friz Quadrata are no longer drawn by the Mac's own fonts (2123) - Bartender2 and Cartographer stop resetting their profile at every login: a stack trace opens on the caller, where AceDB reads its addon's folder; a font's reported height is a number before its face resolves, which Tablet-2.0 does arithmetic on (2121, 2129) - a button highlight built from a texture object draws, so Bongos' bar-drag button, _Nameplates' mouseover glow and Quiver's option rows show theirs; clearing a state texture removes it instead of drawing it in every state (2124) - a toc's repeated SavedVariables lines add up, so all 25 of CT_RaidAssist's saved globals persist instead of seven; colour-mapped TGA icons decode, so FonzAppraiser's and FuBar_WeaponRebuffFu's draw (2126, 2128) - MikScrollingBattleText's DoT lines are back with their school tints, and the school word is capitalised; a chat line with no colour stays white, and the short colour-id form of adding a message works (2127, 2125) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
d49fe51e0e |
cooldowns survive a relog, the MOTD prints, and lost channels come back
- a cooldown still running when you log out and back in keeps sweeping instead of vanishing, and another character no longer inherits the previous session's cooldowns (2116) - the server's Welcome and Patch 1.12 lines print at login in system yellow, and a character whose General, Trade and LocalDefense had gone silent for good gets them back at the next login (2119, 2120) - the stock Interface Options window loads hidden beside ours, so pfUI's options skin finds the real thing; the Auto-join Guild Recruitment Channel row has a real store, and a /reload no longer trips on its camera dropdowns (2115) - the combat log words a power gain on the display scale, so MikScrollingBattleText shows +1 Rage where it showed +10; a 1.12 predicate answers 1 or nil rather than a Lua boolean, the test ColorPickerPlus makes (2117, 2118) - a Lua error quotes a program element with a backquote the way 5.0 does, so AceLibrary's argument checks report their caller instead of raising inside the error path (2122) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
c775181933 |
the cooldown pie survives a /reload, and Bagnon's bags keep their order
- the cooldown pie, the GCD sweep, minimap pings and the map arrow draw again after a logout, login or /reload; they went blank until a restart, which read as OmniCC killing the cooldowns (2113) - an addon's own font on a button label keeps its face, size and outline instead of being undone every frame, MikScrollingBattleText's reported look (2112) - an empty label reads as nothing rather than an empty string, so Cartographer's map label keeps its colour; a slider thumb with no authored size takes its art's own size, so Dewdrop's Look'n'Feel slider moves (2109, 2110) - Bagnon's saved bag list comes back in the order it was written, so the keyring stops jumping to the front after a restart; hovering a Bagnon bag costs a third of what it did (2111, 2114) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
d8de29bd9b |
idle sits you down and camps you, and the addons anchor, parse and draw
- five idle minutes sit you down and flag you AFK, thirty log you out through the ordinary countdown; holding a key is idle, moving the mouse is not, and a swimmer stays afloat (2092) - a knockdown no longer wedges: the landing froze the clip that held the base-animation lock, leaving a knocked-down player on their back for the session (2098); the perf cost pill starts hidden (2099) - Lua is exactly 1.12's 5.0 — no vararg expression, no #, no %, the remembered table size — so Cartographer loads without errors and Mik's Scrolling Battle Text shows its text, in its own shipped font now that addon TTFs load (2101, 2102, 2103) - a widget name is a Lua global for SetPoint and its kin, so Bartender2's bars spread out; a button's NormalText disowns its justify, the raise renumbers hidden frames too, and a missing toc file warns instead of erroring (2105, 2100, 2104, 2107, 2106) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
057a3061c4 |
glue chrome in the box, a knockdown holds, and loot closes on a step
- on a 21:9 display the login, select and create chrome lays out on the boxed scene instead of the black bars beside it; at 16:9 nothing moves (B377, 2091) - a <Model> tile draws only inside its own cell of the shared atlas, so the pet bar's autocast shine no longer bleeds a golden bar onto a bag slot's cooldown (B379, 2093); a slider's first value always fires its handler, so Atlas's options load (2095) - a knockdown plays out: the reference locks the base animation for Knockdown, LiftOff and Land until the clip ends, and benilla re-picked Stand ten milliseconds in (2096) - the loot window closes and releases the corpse on your first step, strafe, turn or jump, the reference's movement-start guard; a distance leash shipped first and was a mislabelled census row (2094 → 2097, B381) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
b81e481348 |
afk and dnd work, the stun swirl shows, and the world drop is back
- /afk and /dnd send instead of printing Unknown chat type: the flag sets, <AFK> shows over your head at once, the four echo lines are the client's own, and moving clears AFK under the real autoClearAFK CVar (2082, 2088) - the stun swirl and the other state-kit visuals show — a cache the login map change cleared lost them nine runs in ten — and a state kit's animation id is the base recompute the reference runs, never a play, so the stray Stun one-shot is gone (2085) - dropping an item on the world brings up the destroy prompt again: since the stock WorldFrame landed, the world is a frame, and the drop's gate had been written for the absence of one (2089, B380) - the mouse no longer snaps to the window's centre when the loading cover drops on /logout; the cover hands the pointer back only where it knows it is (2090) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
663851b17d |
every line is a key, four find their sound, and the ding prints once
- the last app-side lines become GlobalStrings keys — tooltip cells, party, petition, duel, quest, PvP and rest lines read the install's own wording, so a non-enUS chain shows its own text (2045, 2080) - a locked chest says Requires Pick Lock, ammo and thrown weapons drop their invented slot word, a met set bonus reads Set: without the count, and a 100 s cooldown reads 1.67 min as the template prints it - the level-up block and the free-professions line printed twice in chat and print once; a declined invite, a friend coming online, a duel request and a failed quest play the sound 1.12 gives them - Duel cancelled. is the yellow line at the top of the screen, and a trainer refusal or a failed quest with no cached template shows nothing, as on 1.12 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
520b6dc2aa |
the leader crown updates, the trail darkens, and four dead options work
- the party-leader crown on your target's portrait only ever appeared or vanished when you re-targeted them: `PLAYER_FLAGS_CHANGED` was one of eighteen events the migrated stock windows register that nothing here produced, and the census row naming it said "TargetFrame.lua — the AFK/DND badge", which sent the first look at the wrong window — 1.12 draws no AFK/DND badge on any unit frame and build 5875 has no `UnitIsAFK`/`UnitIsDND` at all (ours are a deliberate invention, 2043; the `<AFK>`/`<DND>` the era shows is the chat line's `arg6`), and the event's sole FrameXML consumer is `TargetFrame.lua:88-95` re-running `UnitIsPartyLeader("target")`, whose descriptor leg is bit `0x1` of this very dword; the handler `0x5ee990` XOR-diffs old against new at `0x5ee9b8` and fires 407 at `0x5eea3d` with no bit test in between and ABOVE the local-player GUID gate at `0x5eea93`, once per unit token naming that GUID through `0x515e50`'s fan-out (`arg1` = the token, no `arg2`, and a zero token count skips the fan-out so a stranger nobody targets signals nothing — free here, since `fire_transitions` only ever runs per token); so the trigger is the RAW dword, `UnitState::player_flags`, the `flags`/`UNIT_FLAGS` pattern one field over, because firing off the two bits the struct decodes would under-announce AFK, DND, GM, PvP-desired, helm, cloak and both play-time bits, and `prev.is_some()` keeps a unit's first snapshot silent as its CREATE runs no notify pass; reading the whole handler found an over-fire that was inherited, not invented: benilla fired `PLAYER_UPDATE_RESTING` on ANY flags delta because wow-re's rested-XP note said in as many words that `0x5eeaf2` fires "on every flags change, not only the resting bit", and the bytes say otherwise — `0x5eead0` `f6 45 fc 20 / 74 26` is `test byte [ebp-4],0x20 ; je 0x5eeafc` and the fire sits inside that arm — so every helm toggle, leadership pass and AFK flip had been announcing a resting change to the whole UI; narrowed to the resting bit's own edge, and the same handler's `0x5eeb65 test ah,0x30` arm becomes `PLAYTIME_CHANGED`, whose consumer `PlayerFrame_UpdatePlaytime` already had all three verbs it reads; the claim is corrected in wow-re by a four-derivation round that confirmed all three arms plus the CREATE question; three tests pin it — the producer with a control on `0x400`, a bit no field decodes; the over-fire regression on the real feed, where a helm bit moving fires neither self event; and the crown itself on the stock `TargetFrame.lua`, leadership passing to a held target lighting it with no re-target and the same event for `arg1 = "player"` not — a fixture that first failed on its opening assertion because `UnitIsPartyLeader`'s second leg is a raw GUID compare with no zero guard, so a default `guid: 0` equalled the zeroed leader of an empty group (verified 1.12: it is why `UnitIsPartyLeader(nil)` answers 1 while solo); the unproduced-events census goes 18 → 16 per window, 31 → 29 whole (2078)
- the weapon swing trail darkens with the scene instead of burning at its authored colour: 2076 shipped it unlit and said why — the draw callback turns lighting ON (EGxRs `0x0e = 1` at `0x6c6847`) over vertex format 7, position + packed colour with no normal, and the state bit alone does not say what fixed-function produces from that; the bytes now do: `0x5a1e30` sets DIFFUSE- and AMBIENTMATERIALSOURCE both to `D3DMCS_COLOR1` off the format's diffuse bit, so the vertex colour IS the material; the normal is explicitly disabled rather than stale (`0x592a60` replaces the format mask instead of OR-ing it, `0x59c100` issues `glDisableClientState(GL_NORMAL_ARRAY)` when the bit is clear, and D3D's format-7 descriptor carries −1 in the normal column), so there is no N·L and the diffuse half contributes nothing; and the global `D3DRS_AMBIENT` (EGxRs id 6) has zero writers image-wide and defaults to 0, an earned zero — leaving `out = (Σ enabled lights' ambient) × authoredColour + inherited emissive`, which is why this does not take the lit emitters' `clamp(ambient + diffuse·max(N·L, 0))` term, a sun the reference does not have; `weapon_trail.rs` multiplies the trail's RGB by `WowLighting.ambient`, folded on the CPU into the vertex colours because a per-draw constant rides the vertex stream on this lane, drawing as `EffectLighting::None` and at the authored colour until the first lighting resolve; two named approximations of the class the fishing line already carries — the scene ambient rather than a per-model light collector, so an interior trail takes the exterior ambient, and no emissive, since `EMISSIVEMATERIALSOURCE` is set nowhere and reproducing it would mean inventing a constant; the other half of 2076's open list was a deviation benilla does not have: it claimed the combat-over-combat fast path (`0x5fe43c` returning at `0x5fe48b`, before the trail latch's only read at `0x5fe48e`) was unmodelled and cost trails starting one play early — both wrong, because `0x60d835` arms a one-slot field with a plain `mov` so a second proc OVERWRITES the first and firing on every request would draw superseded arms with superseded colours on 23 of the 34 type-8 kits, and because the driver's request loop already fast-paths it (0406, `select::is_combat_anim` = `0x5fcc10`'s byte-decoded set) and `continue`s without playing, so the edge never rises; a negative asserted about our own code from having written it rather than looked, shipped to wow-re where it drove a build-it verdict for something already built — now pinned by a test that names both mechanisms; and `benilla-extract charprocs` prints `CharParamOne` beside every trail row: wow-re's note justified "not read by this arm" with "every shipped type-8 row carries 20.0 there", and over the 34 kits the column takes six values (22 at 20, six at 15, two at 25, two at 0, one at 17, one at 22 — Sinister Strike's kit 399 is a 15); nothing here reads it either way, but a census that hides the one column a note asserts about cannot catch the note being wrong, and wow-re's re-measure agreed value for value and found the column live at four sites in `0x60d7c0` for other proc types (2079)
- four options that ticked and did nothing — Show Tutorials, Tip of the Day, Profanity Filter, Disable Spam Filter — get their backing, and two of the reasons they were dead were wrong: none of the four was a row in our window at all; they sat in the transcribed `UIOptionsFrameCheckButtons` declaration table beside thirteen more whose features benilla lacks, and these four are exactly the ones where the feature existed and only the setting was missing; `SHOW_TUTORIALS` is a bare `{ index = 28 }`, which an earlier census read as "an index-only entry with no store at all" — wrong, the store is the three special-case arms `UIOptionsFrame_Load` (l.239), `_Save` (l.318) and `_SetDefaults` (l.645) keep for the key, `TutorialsEnabled()` reading the acknowledged bank and `ResetTutorials()`/`ClearTutorials()` writing it, verbs benilla has had since 1976, so the row was one `func` pair away, and the reference's `~=` guard comes with it because without it a Defaults click on a page where tutorials are already on would `ResetTutorials()` and re-arm every popup the player has dismissed; that census moves out of prose into a test checked both directions, the posture the CVar defaults already hold — a name the reference's table carries that nothing registers and no listed blocker fails, and a listed name that has since been registered fails too, twelve rows listed today with the feature each waits on; the two chat filters are PCRE over shipped DBCs, not word lists: `ChatProfanity.dbc` (2289 rows off `patch.MPQ` — `dbc.MPQ`'s copy is 1512) feeds the masker `0x4a1a60` and `SpamMessages.dbc` (28 gold-seller URL patterns; `dbc.MPQ` has none) feeds the predicate `0x4a1ca0`; Blizzard PATCHED PCRE's escape table (`.rdata 0x812330`) so `\<`/`\>` alias onto `\b`, and an unpatched engine makes them literals and silently kills the whole ASCII half of the profanity list while looking correct; CASELESS folds ASCII only, so pattern and subject are both ASCII-lowercased and matched case-sensitively rather than through `(?i)`, which would match `É` where the reference matches nothing; the masker is in place and length-preserving, one token per byte cycling `!@#$%^&*` from a process-global index never reset for the session, patterns in list order not text order — wow-re's oracle transcript reproduced against the real list, "you are a twat and a faggot" → "you are a &*!@ and a !@#$%^", the later word taking the earlier characters because its row (507) precedes the other's (530); two corrections to what this tree believed: `spamFilter` is armed for every chat type EXCEPT `CHAT_MSG_FILTERED` (`0x49aad2`'s `jne` skips the disarm, which the older note read backwards, so our comments claimed the filter bit only on the one type it is exempt from), and `profanityFilter` gates INSIDE the masker at `0x4a1a66`, covering all thirteen call sites rather than the guild MOTD alone; `CHAT_MSG_FILTERED` (`0x5B`) comes with them — it was on the "never `SMSG_MESSAGECHAT` wire" list and is the server's "your message was filtered" notice `ChatFrame.lua` renders at l.1405, dropped with a warning before and delivered now; the chokepoint runs spam, then mask, then fire, in the reference's order, since a dropped line must not consume mask indices; named rather than faked: the other twelve masker sites (mail, guild, item text, the send path) and their `dl = 1` memo, and the whisper leg's `CMSG_CHAT_FILTERED` report whose body is a wow-re DEFERRED with no vmangos handler; each row sits in 1.12's own seat — Profanity Filter closes the Basic Options Display column, Show Tutorials and Show Loading Screen Tips open the Help box, Disable Spam Filter is the last link of the Advanced chat chain and value-inverted, checked ⇔ `spamFilter == "0"` (2077)
- the loading screen shows the tip of the day: `GameTips.dbc` is 74 records in the 5875 enGB chain, off `patch.MPQ`, ids unsorted (the file opens on 396 and closes on 412), so the index the client persists is a record index in load order, never an id; `gameTip` holds the NEXT index, not the one on screen — the client reads it, shows that row and stores `read + 1`, so on-disk values run 1..=74 and never 0, and the reference's own `Config.wtf` reading `SET gameTip "34"` while showing row 33 is exactly what an off-by-one anchors on; the wrap is a clamp, not a modulo (`if (i < 0 || i >= count) i = 0` at `0x46b682`), the walk is sequential, and both guards — `showGameTips` off and the roster's level-zero flag — jump past the `CVar::Set` as well as the draw, so turning tips off freezes the cursor rather than burning through the table invisibly; it draws only on the glue→world transition, because the setter `0x406630` has exactly one caller inside `EnterWorld` and neither `SMSG_TRANSFER_PENDING` arm reaches it, so the pick hangs off the loading screen's world-entry raise and a portal or worldport screen carries no tip; placement is the reference's: `s = 515/(a·1024)` with `a` = aspect × 0.75 (not W/H, which inflates the wrap width by a third at 16:9, and not the FrameXML-length idiom, which is off by 1.25 at 4:3), the block at `(0.5 − s·0.5, 0.1)`, left-justified, body `0xd7c8c8c8` with an opaque black shadow at `(+0.001, −0.001)`, laid out once per raise between the backdrop and the progress bar; the one term deliberately not applied is `yoff = (1 − a)·0.5`, which wow-re left unreconciled (`0x406a60` already applies the letterbox as a viewport and `yoff` is the same term added again inside it, a possible double count on a display narrower than 4:3) — benilla's loading screen is a 4:3 content box by construction and at 4:3 the reference's own `yoff` is zero, so the tip sits at the reference's layout on the one aspect where the ambiguity cannot bite; the `|cffffd100Tip:|r ` prefix and the trailing CR-LF are in the data and the escapes are interpreted, so the gold "Tip:" is markup and the line is built through the markup tokenizer; the cursor persists through the VM's own CVar table (`write_host_cvar`), since the config file is composed from that table and a host write stopping at the knob would reset it every launch — a live run reads `74 game tips` → `tip 0 of 74` → `tip 1 of 74` with `gameTip = "2"` left in the config, and an earlier live run is what caught a `GameTipSetting` the test harness initialised and the real app did not, a panic no unit test could see (2077)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
||
|
|
0d5ff18fa2 |
the player picks the realm, and a harmful spell flinches its victim
- the player picks the realm: benilla connected to whichever realm the auth server listed first — not a policy but the absence of one — with the reference's Change Realm button drawn permanently disabled and the character screen's banner reading "Connecting…", a string 1.12 does not have, invented because the realm only ever arrived as a passenger on the character list (`CharacterSelect.lua` l.66 ends that ladder with `CharSelectRealmName:Hide()` — no name, no banner); `read_realm_list` had read the flags byte, the category byte and the realm id into `_` locals and stringified the population on arrival, and all four are load-bearing; the IO thread gains a third park — logon → which realm? → world handshake → which character — publishing `SessionEvent::RealmList` and blocking on `RealmRequest::{Enter, Refresh, Abandon}` exactly as at the other two, `Enter` carrying the realm's name and not its index since the list is re-requested every 5 s (`RealmList.lua`'s `REALM_LIST_REFRESH_TIME`) off a realmd socket `Logon` now keeps; Change Realm hands the logon forward (`HeldLogon`) so a different realm costs a world dial, not a re-authentication, and a deliberate ask arms `Realms::forced` for exactly one list, because the realm remembered from last time is precisely the realm you are standing on and asking to leave — without it the button re-entered the same realm and appeared to do nothing; the auto-answer ladder is a pure `auto_answer` — `WOW_REALM`, then the remembered `realmName` CVar (which `set_realm_name` had poked into its slot in place, never reaching `cvar_changes`, so the persisted CVar whose whole job is "the last realm connected to" was absent from disk forever; it writes through `set_from_engine` now), then an unattended run takes the first realm that is up, every arm requiring the realm to be up — and the screen is `RealmList.xml` rebuilt on the same 640×512 HelpFrame plate the AddOns list uses, eighteen rows at the authored 20 px pitch, four sortable columns; the Population word is a BAND, not the float: `realm_load_stats` (0x46e510) takes the mean and `sqrt(Σ(pop − mean)² / (n − 1)) · 0.6`, `realm_load_classify` (0x46ec60) reads the sentinels first (0x20 → Recommended, 0x40 → New, 0x80 → Full) then strict `pop < mean − stddev` → Low, `pop > mean + stddev` → High, else Medium — so the same realm reads High on a quiet list and Medium on a busy one, and a lone realm is banded against the `n ≤ 1` short circuit's literal 1.0, so a local vmangos realm at 0.06 reads Low, not Medium; then wow-re's cross-check of `RealmList.cpp [0x46e3bf, 0x46fa05)` confirmed 0x01 = invalid / 0x02 = offline and that the real client does auto-connect by `realmName` without raising the list (`0x5ab800` resolves the stored name against the fresh list, its success leg calling no `SetStatus`), and corrected four things the first cut shipped: the statistics are GLOBAL — `0x46e510` walks the flat all-categories array unconditionally (`0x46e5ee fadd [esi+0x12c]`), the per-category bucketing in the same loop a side effect and never a bound, so scoping them to the tab made the same realm read a different word per tab; Recommended/New/Full never travel as flag bits at all — the parser recognises magic populations by bit pattern and rewrites them, 600.0 → 0.0 + 0x20, 200.0 → 0.001 + 0x40, 400.0 → 8.0 + 0x80, and it has to happen in `read_realm_list` before anything averages, since one realm advertised Recommended arriving as 600.0 drags the global mean past every other row; pvp/rp is a `Cfg_Configs.dbc` join on the type dword at `[realm+0x04]`, and the shipped rows make types 3 and 5 PvP and 7 RP where the 1/6/8 match had all three Normal; and the default sort is `[characters, load, name, mode]`, all ascending, written once per process by `0x46e300` — a four-key fallthrough where "ascending" characters means higher count first, a column click being move-to-front (`0x46e9b0`) that keeps the column's direction unless it was already in front — with the reference's non-antisymmetric characters comparator (its tie-breaking `strcmp` result clobbered one instruction later at `0x46e846`) deliberately not reproduced; `RealmWizard`, the `REALM_IS_FULL` confirm and the category tab strip are deliberately not built, each for a stated reason (2056, 2062)
- a re-played effect REPLACES the same record at the same attach point: the director's report that the reference draws far fewer impact effects when many mobs beat on one warrior — and named the star burst on both hands on every crit — is not a limiter but a replace, recorded in wow-re for weeks: `CEffect::AddEffect` (0x61fdd0), the path every kit slot and the melee blood spurt take, opens with `0x6208e0(owner, rec, tag)`, which walks the owner's `+0xb4` list and destroys every node carrying the same `SpellVisualEffectName` record at the same attach tag (bounded `[0x6208e0, 0x62092c]`), skipping `tag == -1`; benilla replaced only persistent instances, on the narrower `(spell_id, class)` key of the spell-id reap `0x614150`, and pushed every one-shot unconditionally — a gap seen and scoped to one caller four times (0850, 0927, 1149, 1518) without being generalised — so five attackers landing swings on one body held five blood spurts at `(UnitBlood, 0xf)` where the reference holds one, linear in the attacker count on additively-blended emitters where the reference's is flat, and near-identical in a 1v1, which is why it survived; the sharpest case is Flurry (12966–12970), applied on every critical strike, whose visual 2759 hangs record 416 — `Spells\Strike_Impact_Chest.mdx`, the gold chest-impact flare reused at the hand tags 0x15/0x16 — on both hands via cast kit 3010 over a persistent `BloodLust_State_Hand` glow from state kit 3009, and every crit stacked another pair; `spell_fx::replace_same_slot` now runs per slot at every Begin for persistent and self-terminating instances alike, keyed on the RECORD id threaded through the fx lane (`FxSlot { tag, effect, path }`, the hardcoded map becoming name → (id, path)) and not the path, because two rows may name one .mdx and the reference lets those coexist, with both exclusions kept — the world plant and an already-decaying node — and four tests pinning the key's two halves and both; the other half of the report, that the burst is too large and too long, is a separate mechanism and is not touched — and the instrument that would have measured it was lying: `m2part` read a burst emitter's `peak_rate()` as its particle count, while the reference fires on the rising edge of `enabled != 0 && rate > 0` sampled on one clock, and `Strike_Impact_Chest.m2`'s gold flare steps its gate 1 → 0 on the very keyframe its rate steps 0 → 50, so the two are never true together and that emitter emits NOTHING; the tool printed "burst of ~50 particles, life 0.50s" and a diagnosis started 2.7× over on count and 1.7× over on duration off that one line; `EmitTiming::first_burst` walks the slot's keyed span at 60 Hz and returns the first instant the predicate holds or `None`, the dump prints the real count and time or `NEVER FIRES`, and a real-asset test pins that model's emitter #0 as never and #1 as exactly 30 (2057)
- a harmful spell's impact flinches its victim: benilla had one spell-side wound path, `play_kit`'s `[8,10]` branch — the kit player's own `0x60f3ad` test — carrying the KIT's anim id, so a spell whose impact kit names no wound anim, which is nearly every one (Fireball, Frostbolt, Shadow Bolt, Sunder Armor, a mob's Strike), twitched nothing, and a kit naming CombatCritical played 10 where the client plays 9 or 8; `0x60ea70` has six callers, not the three an earlier sweep found (`grep "call 0x60ea70"` over the full objdump was the one command it never ran): the missile hand-off `0x61dc50` lays the flinch before the impact kit for every living target (`0x61dc74`, HEALTH > 0; the already-dead arm `0x60ea30` plays Death/SwimDeath instead), the instant-hit ImpactKit loop `0x6e8bf0` lays it after the kit when `0x6ea280(SpellRec) == 2` (`0x6e8c89`), the reflect kit `0x6e8cb0` does the same on the caster, and every spell-side call pushes severity 0, so the id is always `0x60ea70`'s own `(severity, engaged)` pick — CombatWound(9) engaged, StandWound(8) otherwise — never the kit column; `0x6ea280` is the spell's hostility class and `== 2` ⇔ the spell targets enemies: Targets bit `0x100` → never, `0x80` → yes, else `EffectImplicitTargetA[i]` then `B[i]` for effects 0..3 indexed into the byte tables `0x6ea338`/`0x6ea378`, whose case-0 ids `{2, 6, 15, 16, 24, 28, 53, 54}` are exactly the modern enum's `*_ENEMY` set; so `WoundAnim { entity }` loses its id and the driver resolves every spell edge as `wound_anim(0, engaged)`, `play_impact` takes an `ImpactPlay` with `flinch` — the instant hits pass `SpellDisplay::is_harmful()`, a missile arrival passes true — `SpellDisplay` gains `effect_implicit_target_a/b` (columns 82–84 / 85–87) and `is_harmful()`, and the flinch is laid as the same secondary-blend overlay as a melee wound, over a cast, a swing or a run, never replacing them; pinned against the real 5875 `Spell.dbc` — Fireball, Charge and Sunder Armor harmful through A, Frost Nova through B alone, Renew, Healing Touch, Arcane Intellect and Battle Shout not — and the driver never picks CombatCritical for a spell edge; `WOW_MOVE_TRACE` gains `fct wound trigger/evict/expire` lines, since the whole flinch lifecycle was invisible in a trace; and the report this was chased under — the warrior's swings reading as cut short by incoming impacts in a many-mob brawl — stays open, with one reference gate found on the way that benilla does not model: `0x60ea70` aborts while any attached CEffect on the victim carries `+0x2c & 0x4` (`0x60eab6`), and which kit-spawned nodes carry that bit is the question dispatched to wow-re (2058)
- other players' roots, levitation and blinks now relay to onlookers: a report that a nearby player getting rooted, water-walking or Blinking slid or stood in the wrong place until their next movement packet was exactly right — a movement mode has three legs and benilla carried two, the mover's own acked handshake (`SMSG_FORCE_MOVE_ROOT → CMSG_FORCE_MOVE_ROOT_ACK`, 0866) and the server-driven `SMSG_SPLINE_MOVE_*` twelve (1780), while the third, what observers are told once the mover acks (vmangos `MovementPacketSender.h:30-60`, broadcast by `SendMovementFlagChangeToObservers` / `SendTeleportToObservers`), fell through `parse_server` to `ServerPacket::Other` and was dropped — so a rooted player kept sliding for the ~500 ms to their next heartbeat, a Levitate on someone else was never rendered, and a Blink left them standing at the old spot; six opcodes — `MSG_MOVE_ROOT`/`UNROOT` (236/237), `MSG_MOVE_HOVER` (247), `MSG_MOVE_FEATHER_FALL` (688), `MSG_MOVE_WATER_WALK` (689), `MSG_MOVE_TELEPORT` (197) — all the ordinary `[packed guid][MovementInfo]` shape and all sharing the client's one relay handler `0x603bb0` with the 22 already carried (wow-re's opcode-handler table has thirty rows on it; the remaining two are cheat opcodes vmangos never constructs), so admitting them to `is_movement_relay` is the whole fix for five: apply/unapply rides the flags word rather than the opcode, since vmangos runs `SetHoverReal` &co. before the broadcast and the word on the wire already carries the bit's new state, and `apply_move` already commits it wholesale into the union the ground resolve reads for hover's offset and the water-walk plane — the pose the packet carries beside the mode is half the value, a rooted player's stopping place being news too, and the root arrives already post-wipe with `MOVEFLAG_ROOT` forced back on, so no wipe of ours is invented; the teleport is a relay in shape and a discontinuity in meaning, so `RelayMove::reconciles()` excludes it from the pre-fire reconcile beside the heartbeat, for the opposite reason — the heartbeat because the dead-reckon has already converged, the teleport because there is nothing to converge to, and lerping toward a Blink's destination would drag the mover across the twenty yards the Blink exists to skip, sweeping the shared capsule through every wall between — while it still rides the unit's relay chain rather than snapping at arrival, because replay is paced against the sender's own stamps and applying it early would put the player at the destination while their walk to the launch point was still replaying; a `tp` tag joins `hb`/`tr` on the `rly` trace line; and parse and decode of all six are pinned against golden bodies asserted four bytes shorter than the counter-carrying `MSG_MOVE_TELEPORT_ACK` form, so a counter is provably not being read (2061)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
||
|
|
f1a1b68c1a |
strings become keys, hidden tiles park, and the water stops breathing
- a reference string is a key, never a Rust literal: display text is a key into `GlobalStrings.lua` in-game or `GlueStrings.lua` on the glue screens, resolved at runtime from the player's own install, and a literal is legitimate only as a fallback beside a lookup — the reference's own `UNKNOWNOBJECT` shape — because a re-typed sentence costs the wording nobody diffed, the surface and the voice a composed string has no catalog record to read off (1770, 1815), and localization; the tripwire in `reference_strings.rs` is the check a comment could never be: it walks the workspace, normalises both sides and fails on any literal matching a shipped value — 273 re-typed literals over 34 files, after calibration threw out three false-positive classes (a path-mangling bug, the 85 fallbacks beside a real lookup, and `#[cfg(test)]` modules whose fake tables match by construction — the first run's 378 would have enshrined ~50 phantom sites); `ALLOWED` is a per-file ratchet whose counts may only go down and whose stale rows fail too, regenerated from a clean tree at 253 over 33 files — the first baseline was captured mid-edit and the land gates failed on a row claiming drift in a file that had none — then 252 over 32 as `ui_trade`'s row retired behind a neighbouring conversion to `ERR_TRADE_BLOCKED_S` (2042); stated in its own doc: it cannot find an INVENTED sentence, which matches nothing; and `benilla_ui::strings::fill` is the one template filler — ordered `%s`/`%d`, positional `%N$s`, `%%` collapsing, a starved specifier copied through visibly so a mis-modelled template looks wrong rather than plausible — replacing eight hand-rolled copies that disagreed, one of them `str::replace` filling every `%s` with the same argument, latent only because no message on that queue carried two yet (2045)
- two families convert, and both assert the identifier, not the sentence: the character-create result line resolves its key off the player's chain with the literal as fallback, and three bugs the 23-arm literal table had hidden come out — `0x36` re-typed without its second sentence ("Please try again during off peak hours."), `0x50` invented (there is no `CHAR_NAME_CONSECUTIVE_SPACES` in 1.12, so it takes the default arm), and `0x4B` naming `CHAR_CREATE_NAME_IN_USE` where the code means `CHAR_NAME_RESERVED` — both read "That name is unavailable" in enUS, so no assertion on displayed text could ever have caught it, and a sentinel test that rewrites `CHAR_NAME_RESERVED` in a copy of the real table proves `0x4B` moves while `0x31` does not; the ratchet's first row retires, 21 → 0; and `SMSG_PARTY_COMMAND_RESULT` returns the catalog message the reference's own jump table names — handler `0x5e68b0`, `dec eax; cmp eax,7; ja <silent>; jmp [4*eax+0x5e6a14]`, results 1–8 onto `ERR_BAD_PLAYER_NAME_S` … `ERR_IGNORING_YOU_S` plus `ERR_INVITE_PLAYER_S` (`0x3a`) and `ERR_LEFT_GROUP_YOU` (`0x42`) on result 0 — so text, surface and sound come off one row: `ERR_PLAYER_WRONG_FACTION` (`0xff`) is the red line where the other nine are chat, and three inputs the reference is DELIBERATELY silent on (result ≥ 9, result 0 outside op {0, 2}, an invite with an empty name) stop printing an invented "Party command failed (N)."; tests assert the message id, since no English distinguishes a right key from a wrong one here, and `ui_party` goes 22 → 12 (2045)
- a hidden `<Model>` tile is parked: every orthographic pane shares the atlas's one camera, deliberately kept active whenever any cell is packed because it is the camera that clears the sheet, so `booth_frozen` — exact for every booth ever built, one camera one scene — answered "drawn" for every pane that had left the paint list, and a hidden autocast-shine pane's four spline emitters kept integrating and pushing quads for the whole 600-frame linger at a cell the packer had since given away; `sync_tiles` gains a sixth stage that parks any live tile with no cell this frame — `AnimParked` on the root, which holds the pose evaluator, the compose, the palette write and the global-sequence bone writes, and `ParticleEmitter::set_frozen` on every emitter — with `scene_frozen` stating the freeze law in one place and the park verdict pinned to the composite by a test, so a repack or a full atlas cannot freeze a visible pane's cloud; the bone global sequences move onto the pane's clock, where the material rows have been since 2019: the kernel's Phase B cursor is `(sceneClock − attachSnapshot) % duration` off the scene that owns the instance (`[model+0x2c]`, the snapshot at `CM2Model+0x68` stored at `0x70eae1`), and a `<Model>` widget owns a private `CM2Scene` at `CSimpleModel+0x314` that only its own advance at `0x76d863` moves — so the ping's spinner holds while hidden and resumes where it stopped, with no accumulator of ours; measured with a cooldown pane holding the atlas alive: twelve hidden shine panes cost 54 effect items / 63 transparent draws before, 34 / 43 after, the pool held rather than drained by design; and the particle census's `gated=` column, which printed `fade.is_some()` and read backwards as the gate verdict, is renamed `has_fade=` (2046)
- a doodad is not an entity: `[def+0xa4]` has exactly four writers image-wide — ctor `0x6a7d73` (0.0), WMO doodad-set commit `0x695bb3` (1.0), ADT MDDF commit `0x6b01bb` (1.0), MCSH refresh `0x698cb4` (0.5) — and the 2.5-producer `0x69e280` and the ramp `0x69e770` are reachable only through the entity-attached `[obj+0xe0]` path, which contradicted the §6 both lit-ground sites cited and a capture with gains up to 2.5, so the premise was marked contested at both sites first (the shader's own note told a future session to cut `min(I, 1)` and `LIT_T` together on its strength); wow-re then settled it — two C++ classes inline the same base and share the offset: `CMapDoodadDef` (vtable `0x810a74`, `"WDOODADDEF"`, size `0x198`, serving ADT MDDF and WMO MODD) and the WENTITY light node (vtable `0x810810`, size `0x108`, off `[obj+0xe0]`) that `0x69e770` ramps at 3.3333/s; on the doodad class `+0xf8`, the field the ramp reads its target from at `0x69e894`, is `m[2][3]` of the world matrix — it has no target field — and six trace frames put 111 MDDF placements over 356 draws at gains only in {0.5, 1.0}, none changing, against an entity walking out of shadow at 0.5 / 0.81 / 1.09 / 1.3367 and rising; so ADT map doodads join the fixed-1.0 family with the exterior WMO props, `ShadeSel::Lit` is entity-only, the retained lane's Matte arm drops its prop requirement, and no pixel changes — the cap was faithful for trees all along and lifting it is now an entity-only look change for the director to call; `WORD_SHADE_LIT` is left as a documented dead bit (2050); and the far water's 1.25 s breath is flattened: the director's recording autocorrelates at lag 75 @ 60 fps = 1.250 s (r = +0.60), the 30-frame ocean flipbook at 24 fps, whose frames do not share a mean — alpha 55.985..57.628, DXT3's 4-bit alpha swinging 1.64 at mip 0, 3.72 at mip 5, 6.38 at mip 6 — so at distance the mipped sheet moves together, 0.8..1.84/255 on screen, fogged out at `farclip` 300 and visible at 777; wow-re proved the reference breathes too (`0x68abab` creates the flipbook with `applyGlobal = 1`, the upload hands the driver `Levels = 9`, LOD bias 0, the loop period `[0x8102b8]` 1.25 s over 30 frames), so ours was faithful and it is flattened anyway by the director's eye: each frame's DC equalised per level and per channel at texture-build time as an exact integer redistribution in ±1 steps on a coprime stride (1.64 / 3.72 / 6.38 / 0.555 → 0.000), water and ocean only since magma and slime take the sheet as their body colour, `WOW_LIQUID_DC=raw` restoring the authored art for the A/B (2051)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
||
|
|
f7e232b2db |
swing refusals latch and repeat, and the trade arc stops being silent
- a refused auto-attack is no longer silent, and the display is a latch, not a toast: six opcodes, four arms — `0x145 SMSG_ATTACKSWING_NOTINRANGE` and `0x146 SMSG_ATTACKSWING_BADFACING` latch a code through `0x5ecdb0`, which writes `[0xc4d758]` and `[0xc4c270]` together; `0x148 DEADTARGET` and `0x149 CANT_ATTACK` share arm `0x625ab8` verbatim (StopAttack, no message), so the client cannot tell them apart and `AttackSwingError` collapses them into one `DeadOrUnattackable`; `0x147 NOTSTANDING` is never registered by the reference and `SendAttackSwingNotStanding` has zero callers in vmangos, so a test pins that it stays an unknown opcode; and the fourth arm hides: `0x14e SMSG_CANCEL_COMBAT` is registered at `0x5e3303` by the SPELL TU, not the combat one, so the eight-opcode census every note quotes did not contain it, and its handler `0x5e7dd0` is arm 4's body instruction for instruction; vmangos sends each refusal on the edge alone, so the repeat the player sees is the client's own: the tick `0x5ec950` — `CGPlayer_C` vtable `0x80af78` slot 14, dispatched once per object per rendered frame on the `CWorldFrame::OnPaint` chain, so a Bevy `Update` system is the exact cadence — prints `ERR_BADATTACKPOS`/`ERR_BADATTACKFACING` (catalog rows `0xd8`/`0xd7`, both red) at once and again every 4000 ms while an attack target is set, and a landed swing clears it: `SMSG_ATTACKERSTATEUPDATE`'s arm calls `0x5ea800`, whose first act is `0x5ecdb0(0)`, gated on the attacker being the active player AND the victim resolving (both gates kept — wow-re's round had glossed the second away, and sending that back corrected the note); the latch is one `Option<(Latched, Duration)>` because `[0xc4c270]` has no meaning while `[0xc4d758]` is 0, a second refusal packet defeats the cooldown and the re-arm precedes the print (both tested), the clear also runs once per world entry (`0x5e2510`), and both edges ride ONE `SwingRefusalEdge` stream so a refusal and a landing in the same frame stay in packet order; `SMSG_FEIGN_DEATH_RESISTED` (`0x2b4`) arrives beside them and is built differently because its handler `0x6e9800` is two instructions — a bare `DisplayError(421)` = `ERR_FEIGN_DEATH_RESISTED`, the single word "Resisted" — so it takes the plain `UiErrorKeys` route with no latch; the `--attack` world probe now reports the refusals it tallies; and two remainders are named, not built: `0x5ea800`'s post-swing leash — `R = 4.0 * max(5.0, reach(victim) + reach(self) + 1.3333333730697632)`, floor 20.0, sending a bare `CMSG_ATTACKSTOP` past it — a new packet-sending behaviour left for the director's call, and `StopAttack 0x5ecac0`'s two one-shot tutorials (10 low-health, 11 low-mana), which benilla's copy has never fired (2037)
- the trade arc stops being silent: eighteen of the twenty-three `SMSG_TRADE_STATUS` arms print where benilla printed none, all through `UiErrorKeys` so the text is the player's own `GlobalStrings.lua` and the surface is the catalog record's `+0x04`; the four-row start was the trade block's own emit-site census, which answered "which arms raise a TRADE-keyed message" — eleven of the ids come from elsewhere in the 465-row table (`ERR_PLAYER_BUSY_S` `0x3e`, `ERR_PLAYER_DEAD` `0x7e`, `ERR_GENERIC_NO_TARGET` `0xb8`, `ERR_PLAYER_WRONG_FACTION` `0xff`, `ERR_IGNORING_YOU_S` `0x13d`, the stunned pair `0x191`/`0x192`, the logout pair `0x19d`/`0x19e`, `ERR_RESTRICTED_ACCOUNT` `0x1be`, and `ERR_TRADE_WRONG_REALM` `0x1ca`, whose text is the ONLY_CONJURED sentence), and the surfaces do not follow the English — a successful trade's two lines are the yellow ones, `ERR_PLAYER_BUSY_S`/`ERR_IGNORING_YOU_S` are chat lines, the refusals red; `TRADE_REQUEST_CANCEL` fires from the top of the CANCELED arm (`0x4bf832`, the dispatcher's one `SignalEvent`) where nothing had fired it; `ERR_INITIATE_TRADE_S` prints — it is client-emitted from inside the `CMSG_INITIATE_TRADE` sender, at once on a name-cache hit (`0x5d4042`) and from the query callback on a miss (`0x5d40ca`), so clicking Trade had produced no text in either direction; the three arms that name a player (0/5/14) read the network handler's guid cell `[0xc4bed0]`/`[0xc4bed4]` behind the outbound-initiate latch `[0xc4bec8]` — `InitiateTrade 0x5d3fb0` writes the target's guid and then the latch, the `BEGIN_TRADE` arm writes the initiator's and no latch — which is what keeps a client that just ignored a trade from printing "X is ignoring you." to itself, and behind `0x468460(guid, TYPEMASK_PLAYER)`, a live-object test the initiate line does not share, so `NamedLine::needs_live_object` drops a status line the moment its player stops being streamed while an initiate line waits; a network-cell clear is not a window close: `0x4bf4e0` has four call sites in the dispatcher — one opens, `{3, 8, 12}` close — and the other fourteen run the handler's tail `0x5d490a`, which drops the latch and the pending guid and leaves the window standing, so `close()` splits into `close_window()` and `clear_pending()`; `REJECTED` drops only the partner's accept, `BACK_TO_TRADE` reaches `0x4bf230(0)` and sends `CMSG_UNACCEPT_TRADE` on a real change, `ONLY_CONJURED` bounces the offending slot out of our own offer; `CLOSE_WINDOW`'s message is deliberately not built (`0x4bfd70` maps `result` over a 61-id range with a flagged self/other polarity inconsistency, and vmangos never sends status 12); and `ERR_TRADE_BLOCKED_S`'s transcribed English literal is deleted along with `ChatLog::pending_texts` (2042)
- both halves of B373's lighting closed: `MeshTag` bits 6..=13 mean two things — the exterior payload's ground-shade byte and the low eight bits of the interior payload's 13-bit probe slot — and the overlap cannot be removed (the four mode-independent fields cost 19 bits, leaving 13 for a payload region the two modes want 21 of), so the payload question becomes a witness the accessors demand: `mesh_tag::ExteriorPayload` is a zero-sized proof only `exterior_payload(on_bake_law, own_probe)` mints, when both probe-slot populations answer no, and `with_shade`/`shade_of` take it, so no expression in the crate reaches those bits without having asked; `describe` alone reads the raw masks and prints both readings (2041); and a transport's deck cargo is lit by its own doodad def, not by the boat (B373): a transport's WMO is linked into the same global `TSExplicitList<CMapObjDef>` at `0xca7d98` the ordinary scene walk iterates, so its MODDs are ordinary doodad defs; `[def+0xa4]` has exactly four writers image-wide — the ctor `0x6a7d73` (0.0), the doodad-set commit `0x695bb3` (1.0), the ADT MDDF commit `0x6b01bb` (1.0) and the MCSH refresh `0x698cb4` (0.5) — and none is the light node, whose 2.5-producer and ramp are reachable only through `[obj+0xe0]`, a path a doodad def never takes; the MCSH sample is one-shot (`0x698c50` unlinks each entry) and its null-tile legs return lit; so we had the wrong source, the wrong cadence and the wrong mechanism: `entity_shade::DoodadDefLit` marks every WMO-gameobject prop batch from inside the placed-model assembler — the engine asserts it, not the caller; the world-API wall failed the first cut, and a following card is reachable only there — both shade write sites skip it on ownership, separately from 2041's payload question, and exterior props take one `doodad_ground_shade` at their own footprint at spawn, frozen, which answers lit for a non-resident tile so a boat at sea needs no special case and the unverified "a boat is never MCSH-shadowed" goes; 749 prop parts under a shade root carry the marker on a live run — the same 749 B373 measured reading a foreign probe — and the ADT doodad path is deliberately untouched, since the D3D capture's measured 2.5 gain outranks the closure (2047)
- 2043's unit-predicate law is confirmed byte-exact by the round it dispatched — all 29 `Unit*` predicates push the constant double 1.0 or nil, exactly one value at every live `ret`, and a BFS from all 83 bindings in `0x850438` reaches 460 functions without hitting `lua_pushboolean` — and three of its supporting citations are corrected in the comments, no behaviour changing: `lua_pushboolean 0x6f39f0` EXISTS with seven call sites, one of them the registered FrameScript binding `IsPetAttackActive 0x4be0e0`, which answers a real true/false and never nil (ours already did, and its doc already named itself the exception), so 2043's "no boolean on its binding surface at all" is withdrawn for the scoped claim 1830 actually made; `IsEnabled` is `0x7800b0`, not `0x780270` (that is `SetButtonState`), and its number-1-or-0-never-nil fact stands; and `UnitReaction 0x5167e0` pushes `0x6061e0(u1, u2)` PLUS ONE, so 0 is unreachable and its nil means only that a token did not resolve — our `reaction == 0` → nil stays, named now as a feed gap rather than a mechanism the binary does not have (2048)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
||
|
|
eadacac998 |
a hundred stale claims retire, and text= was never a divergence
- a comment that justifies code by an engine difference is a claim with an expiry date, and the tree had ~96 expired ones across `assets/ui`, `ui_script/` and `benilla-ui` — a hygiene pass, no behaviour change: dangling `Benilla*` names with zero definitions (`BenillaMoney_*` at thirteen sites after 1937/1962 converged the coin cluster onto the stock `SmallMoneyFrameTemplate`; `BenillaGossipRow_Resize`, `BenillaErrorsFrame_AddMessage`, the digit feed 1285 deleted, `BenillaMerchantItem_OnClick` and three more), "the shipped `assets/ui/<X>.xml`" for thirty-odd files the directory no longer holds — it holds nine — each site now naming the chain file that actually loads, `UiPanels.xml` in the present tense after 1988 took the panel manager and the dialog engine stock, and expired self-deprecation: SimpleHTML "a widget kind we do not have" (1337 built it), "benilla has no console" (1948 bound `ConsoleExec`), `Model`'s "seven verbs not published yet" and "`ClearFog` is a guess" (all 23 are published, the carve sits 500 lines below, `UNBUILT` has been `[&str; 0]` since 2027), `frame_flag_gate`'s doc describing four groups of accepted mouse divergences over a `KNOWN` list that is empty (the empty array and its enforcement stay), five comments saying key delivery is not gated on `keyboard_enabled` where `script::keyboard`'s walk filters on exactly that field (1319), `SetRaidTarget` called a verb this house lacks beside an assert that its intent IS queued (1820), two questlog tests deferring to a screenshot for `GetPoint`/`IsVisible` the regions already answer, `benilla.toc`'s "trade still needs four engine verbs" (all four bound, 1966) and its ping `Model`s "this engine draws no pixels for" (2013 renders `MinimapPing.mdx` itself), and `rig_anim`'s `set_paused` naming a booth caller it does not have; and the code the prose was propping up goes with it: `GameMenuFrame.xml`'s six `<OnLoad>` label setters, because `text=` on a `<Button>` is a global-string lookup at the loader's attribute step (0995, built 61 seconds before the file was written) — the buttons carry `text="LOGOUT"`/`"EXIT_GAME"`/`"MACROS"`/`"RETURN_TO_GAME"`/`"MAIN_MENU"` as the reference's own do; `ScriptLogFrame`'s five authored close-button lines, now `inherits="UIPanelCloseButton"` off the chain's `UIPanelTemplates.xml` seated 757 lines above it (1846); and the editbox's 22-line "gap" doc claiming only the self-acquire `autoFocus` path is built and its `false` default unverified — path 1 is 1686's `visibility_focus`, and the default is `true`, byte-read off `flags = 1` at `0x779a29`/`0x779a2e`, so the test named `autofocus_does_not_focus_on_show…` is renamed for what it actually pins (2044) - the `text=` divergence never existed: `resolve_text`'s doc had claimed since 0068 that falling back to the raw attribute on a GlobalStrings miss was "one deliberate divergence" from a reference that draws the empty string, and read at the byte it is the reference's own behaviour — `FrameScript_GetText 0x703bf0` does return a pre-seeded empty string (`0x882748`) when the global is not a string, but that return never reaches a label, because all three `text=` readers image-wide test it and substitute the raw attribute: `Button::LoadXML` at `0x778c07` (`0x778c31 mov eax,esi`), `CSimpleFontString::LoadXML` at `0x771006` byte-identically, and `0x7292a6`, which pushes `edi` on the empty arm; so the loader changes nothing, the two test comments that had called `PetLevelText`'s "Level level race class" placeholder and `CLOSE` our divergence now name the reference's arm (a real 1.12 client draws them too), and what IS ours is the extra warning on a key-shaped miss (0983 → 0991), a strict addition; beside it, `GetEffectiveScale`'s root factor is 1 not because "benilla has no `uiScale` CVar" — 1804 registered one, default 0.9 — but because the dial is applied at the raster seam, `768/uiScale` UI units of virtual-screen height rather than a scale on `UIParent`, so every coordinate the VM hands Lua is already in those units and the reference's `GetCursorPosition()/GetEffectiveScale()` transcriptions convert correctly with a root of 1 (2044) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |