- picking a spell up off the bar no longer blacks out every empty slot: `UI-Quickslot` is a FILLED 60%-black plate, not a hollow ring (decoded off the shipped BLPs — Quickslot2's interior is RGBA 0,0,0,0, Quickslot's 0,0,0,153), and the reference dims it to half alpha in `ActionButton_ShowGrid`, so an empty well now ghosts at 30% black where it read as a hole; the wow-re cross-check then found the reference never UN-dims it (a 3-argument `SetVertexColor` preserves the current alpha at `0x79abd0`, and `SetNormalTexture` reuses the region), so in the real client the first drag leaves every button's border at half alpha for the rest of the session — benilla ends the dim on purpose and records it as the divergence it is (1782)
- the bag bar is the reference's own `MainMenuBarBagButtons.xml` (window 3 of the stock-first migration), and the swap found a real bug rather than a move: the reference's `ItemAnim_OnEvent` matches a push against the button's inventory-slot id (20..23) and benilla emitted its own container numbering (1..4), so all four bag-push cards would have silently never played against the stock body — `push_container` now emits the reference's selector (`bag + 1`), which is what an addon expects anyway; beside it, a readiness probe that asks the LOADER, not a grep, which of the 85 stock windows load off the player's chain today (58 do; the 27 that don't name their own blocker)
- a rooted, hovering, water-walking or walking creature reached benilla as an unhandled opcode: the twelve `SMSG_SPLINE_MOVE_*` (the observer twin of the ack'd force family — bare packed guid, no ack, any unit) now decode into one MOVEMENTFLAGS word per unit, which benilla kept for our mover and for a relayed player and not at all for a creature, the one body this family is ever addressed to; ROOT wipes the direction bits so the dead-reckon stops walking a rooted body on for its next heartbeat (`0x7c7340`), HOVER clears a yard off the floor without climbing a body already inside that yard (`0x636e81`), WATERWALK elects the liquid surface against the terrain, SAFE_FALL's terminal is 7.0 not 60.148 (`0x7c5d23`), and SET_RUN_MODE's bool is inverted against the bit, folded at the parse; the inspect card names a unit's granted modes in words (`granted rooted+hover`) so a creature resting a yard off the floor reads as intended rather than broken
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- corpses render: a corpse create spawned a real entity, latched its guid for the reclaim send, and drew nothing — one missing EntityKind variant folded it into the catch-all and four downstream lanes then failed by default, not even the debug cube fired; the reference forks once, on the bones flag: a fresh body builds a character composite from the corpse's OWN appearance bytes and 19 item slots through the same compositor a living player is dressed by (its own hide-helm/hide-cloak bits honoured, the ranged slot never dresses, and weapons never dress because the client looks a packed display word up as a guid — we reproduce the outcome, not the dead lookup), while a bone pile takes its race and sex's DeathSkeleton, sixteen of which ship; the pose is one settled arm — Dead, or Drowned when the body lies more than 0.66666669 yd under a liquid surface — and a corpse is not a unit, so clicking one no longer sends a selection for a guid no unit owns
- a lit particle takes its MODEL's committed light node, not the sky's: indoors the reference lights an object's particles from the object's own node — the footprint's baked floor colours on the fixed interior axis plus the room's placed lights — never the day/night sun; a particle quad carries exactly one normal, world up, one constant per draw, so the whole node collapses to three floats, published off the same fold the model's mesh renders from so a mesh and its own particles can never disagree about the room they stand in; in Onyxia's Lair the 78 lit falling-rock emitters on the 26 anchors that classify interior now take the room's light
- and that lit lane is FIXED FUNCTION, not the mesh's soft SH curve: the shipped client null-binds both shader slots for a particle batch and re-zeroes the shader mask at the head of every batch, so a model and its own particles share the same committed light words and legitimately differ in the curve applied to them — the mesh's wrapping lobe against the hardware's max(N·L, 0) is 0.900 vs 0.869 on the key axis, up to the three nearest room lights arrive diffuse-only under GL's own 1/(0.7d + 0.03d²) falloff (a light at or below the emitter cannot reach it at all), and the clamp sits on the product, never the multiplier, because it is GL that clamps the lit vertex colour
- the cinematic letterbox has no aspect test in it: CinematicFrame.lua's if guards a recompute, not whether there are bars — below 4:3 the reference's bar textures simply stand at their declared 1024x128 on the client's native 1024x768 sheet, which is height/6, the same formula evaluated at exactly 4:3 — so one expression covers every window shape, min((h − min(w/2, h))/2, h/6): a 2:1 picture when wide, bars at 4:3 too; and a shown keyboard frame swallows EVERY key, not the ten names the host used to feed it — you could walk around underneath your own intro; the proof is the reference's own handler, which has to RunBinding("SCREENSHOT") by hand to get one key back; ESC still skips, and a W already held when the shot starts keeps running, which is faithful too
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- "Unable to connect" now says which: an address that does not resolve reads the reference's "Invalid Login Server", a resolved address nothing answers on reads "Login Server Down", and each names the `host:port` actually dialed — resolution and connection are two operations now (a DNS failure surfaces as `Uncategorized` on macOS, so no error kind could tell them apart), and every address a name carries is tried, `localhost` → `::1` then `127.0.0.1` included
- a typed wrong password shows the login dialog instead of exiting the client, and the two auth-result enums — realmd's and the world server's — are split so a code is read against the family that sent it, with the world server's own refusal text shown for its codes
- the world cursor's fork is `CanInteract` and `CanAttack`, not a reaction-rank threshold: a Cenarion Circle NPC with no gossip showed the sword at neutral (and TAB acquired it, and right-click attacked it) because one predicate implemented twice read the standing where the binary reads the at-war bit in the player→unit direction; one byte-verified `CanAttack` is shared by the cursor, TAB, pet attack orders, `UnitCanAttack` and the action-button usable gate, the service ladder falls out to a plain pointer instead of the attack leg, and `/reaction` prints the at-war bit and the branch verdict
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>
- an animated doodad is culled by its authored box, not its bind pose — the one-yard bird flying a 64-yard circuit stops vanishing with the camera angle — and the fix survives the engine's own bound recompute
- the logon proof answers the server's version challenge instead of sending zeros, so a strict realmd stops rejecting benilla as a modified client
- two instruments land: a frame-by-frame visibility trace for one model, and a probe that classifies whether a realmd enforces the version check
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- every rebindable key runs through one chord-to-command engine, set in the era Key Bindings window, and buttons show their real keys
- a spell aimed at the ground sends its projectile to that spot, arcing to the point instead of a target
- a pet ordered onto something it can't attack refuses cleanly, and its frame shows the happiness face read from the client's own data
- a window's tabs clamp to the drawn edge and highlight exactly where they sit
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- the granted movement modes are one system now: slow fall slows, levitate hovers, water walking holds the surface, a root pins you even mid-air
- casting while moving refuses with the real error, and a jump cast plays its animation in the air
- Z cycles melee, ranged, stowed, every landed swing draws the weapon, and Alt-Z hides the UI
- login faces where you logged out, and the dev shortcuts moved to Ctrl+Shift off the Windows key
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- the spellbook draws the cooldown pie on a spell that's cooling down, and the active form's slot lights its checked ring
- shader variants warm at startup (with a tripwire if one ever compiles live), so a first cast no longer hitches on shader compile
- additive glow stacks clamp the way the original scene does, taming Frost Nova's blown-out mist, and shoulder cards split only at rigidly separable bones
- the login handshake now reads the same under both SRP encodings, and cooldown events no longer race the net step
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- terrain draws per chunk now, and one authority culls everything outside: buildings, billboard cards, particle emitters
- the fps and memory creep on long flights is fixed twice over: material animations only tick what something draws, and far-away art is released by distance (with a 30 s dwell floor so fast cameras don't thrash it)
- the second crash ever reported (a cast racing a despawning unit at flight speed) is fixed, with a regression test that reproduces the exact panic
- every build now prints which commit it is, so a bug report can say exactly what it ran
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- A creature that was already walking when it came into view stood frozen at
its spawn point, then teleported — up to a full wander leg, 30 yards in the
worst measured case — when its next movement packet arrived. The create
packet carries the live path (where the unit is along it, how much is left)
and we parsed all of it into the void. The unit now joins its walk exactly
where the server has it: measured before/after, 13% of movement starts were
over-a-yard teleports, now effectively zero.
- Walking into Zul'Gurub or Stratholme through the portal dropped you straight
through the world. The landing check asks "is there a floor under me?" — but
on the arrival frame the loaded world is still the map you just left, and an
instance entrance is a copy of its outdoor ground at the same coordinates,
0.23 yards under your feet. The old floor said yes, then despawned. The hold
now waits for the destination's own ground to arrive, and a world that never
arrives keeps the loading screen instead of dropping you into the void.
- Same fix covers a decoder hazard found on the way: a plain two-point path
announces two points but ships only the destination, and trusting the count
over-ran the packet — it never fires on our server's pathfinder, but now it
can't.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>