- the combat log's last eight wire bodies decode — PARTYKILLLOG, SPELLINSTAKILLLOG, PROCRESIST, SPELLORDAMAGE_IMMUNE, SPELLDISPELLOG, DISPEL_FAILED, ENCHANTMENTLOG, SPELLLOGEXECUTE — each layout read off vmangos's own writer and pinned by a byte-exact golden (DISPEL_FAILED carries no count, the list runs to the end of the body; SPELLLOGEXECUTE's POWER_DRAIN row is (amount, power, multiplier), verified at the client's bytes as well as the server's); with the eleven chat types that were waiting on them, 44 chat types become 55 — 29 sentence families, the death pair and the aura rows riding descriptor diffs because 1.12 has no "unit died" opcode, plus the six trailers ((glancing), (30 blocked), (12 absorbed) and kin) that had been missing from every family; also corrected: the durability-death line was going to the red error frame with hard-coded English, and SMSG_SPELLNONMELEEDAMAGELOG lacked its split-damage branch and its blocked wording
- PlayerModel is its own frame kind: SetUnit, RefreshUnit and SetRotation were published on Model, but they belong to the <PlayerModel> method table (0x84f1fc), and the client's lookup chains derived → base only, so a plain <Model> can never reach them — they got there from a strings scan read as ownership, and a strings hit answers whether a name EXISTS, not who owns it (SetUnit's one pooled string is referenced by the PlayerModel and GameTooltip tables and by no Model entry); the new PlayerModel → Model → Frame → Region chain unblocks CreateFrame("PlayerModel"), which is how pfUI builds every unit-frame portrait — and through pfUI, pfQuest and ShaguDPS
- a nil where a number goes is four shapes, not one law: a census of all 408 widget-registrar entries found 62 numeric positions that validate-or-raise, 43 that gate then stage an alternate, 64 that silently coerce to 0.0 and 5 that gate then store nothing — so SetMaxLetters(nil) completes and stores 0, "no limit" (the argument COUNT is checked exactly, the type is not), and the backdrop colour setters are asymmetric on purpose: a nil r/g/b channel is 0.0 but a nil alpha is OPAQUE, and reading every nil as 0.0 would have turned those borders transparent; both setters now also quantize ×255 into the packed 0xAARRGGBB byte quad the client actually stores, so 0.09 reads back as 23/255
- two more addon-killers: LIGHTYELLOW_FONT_COLOR_CODE was the one missing line of Fonts.xml's seven-line colour block (aux-addon concatenates it at file scope and died on its own first line), and the guard now enumerates the whole block l.4-20 instead of the names an earlier round had noticed absent; and the unit frames publish the reference's names — 1.12 has no *PowerBar anywhere, every bar is ManaBar and the colour table is ManaBarColor (8 of the top-20 addons read it by name), so ManaBarColor is the published table our own bars index into, with 22 more regions renamed to the reference's own
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- knockback is a jump whose seed came off the wire, not a server spline: SMSG_MOVE_KNOCK_BACK's four floats are exactly the MovementInfo jump tail in a different order (speedZ down-positive — a rising launch carries a negative value, the sign vmangos's own source marvels at), flown at the same take-off site as the keyboard jump and acked with the post-launch pose, which the server matches float-for-float within 0.01 before relaying to anyone; it is the one take-off that seeds BOTH axes, absolute in world XY, so it skips the arm that would hand the momentum back to a held key and reduce the whole knockback to a hop; root refuses it silently, a seated player stands up first, no MSG_MOVE_JUMP goes out — that packet is the keyboard's, and vmangos logs a jump at knockback speed as an overspeed cheat — and MSG_MOVE_KNOCK_BACK turns out not to be dead: an observed knockback replays as the arc it is
- your guild crest reaches your tabard: the three GuildEmblems layers — background, border, emblem, on both torso tiles — belong to no equipment slot, so the body composite never wrote those cells and every guild wore the Guild Tabard's own default art; the install is gated on a display flag only seven of 29,604 rows set, of which exactly one is worn by any item — which is why every battleground and Argent Dawn tabard keeps its own art; the five wire indices are signed, because an undesigned guild carries −1 in all five and the client refuses to paint on the first −1 (unguarded, the commonest guild state on a young realm would have worn a blank tabard); the emblem keys the skin cache, so two guilds in the same tabard display cannot lend each other crests; and a guild tabard's background hides the bra where a plain tabard does not — it is a cutout, 79.5% opaque off the shipped art, and what shows at the sides is bare skin
- a fly-by is framed by the world camera, not the M2 camera record's fov: a census of every reader shows the record's fov and clip planes reach only the portrait and Model-frame paths — nothing on the cinematic path reads any of the three — so fifteen of the sixteen shipped shots were rendering at HALF their intended vertical FOV, visibly over-zoomed on every race intro but the Undead; the fix is a deletion, and it dissolves a standing puzzle: the authored 0.22 and 27.8-yard "clips", which would render the dwarf intro's mountains as empty sky, are not clips at all on this path — two floats nobody consumes look exactly like that
- 104 of Onyxia's lava traps stood on an interior floor classified as outdoors, taking the day/night sun inside a windowless lair: a GameObject's light node anchors at its model's AUTHORED bounding-box centre, and the trap's box reaches 98.42 yd past its bind pose — the anchor sits ~40 yd under the chamber floor, where a downward ray finds nothing above it to claim; the reference recovers with a 1000-yd upward retry at the claim itself, which benilla had only at the colour sample, so the verdict was decided before any colour was read; all 104 now classify interior, beside the 26 rocks and 119 eggs that always did — and the drowned-corpse pose came back from its cross-check confirmed at the bytes (a strict liquid-depth test at exactly two-thirds of a yard, Dead or Drowned), with the two reference-side notes it contradicted corrected over there
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- founding a guild: fourteen opcodes, eight goldens (four mutation-checked), twelve engine globals, `GuildRegistrarFrame` and `PetitionFrame` — `CMSG_PETITION_BUY` is a 72-byte frame the server reads two fields of and drops in silence if short, `allowedGender` is the family's one u16, a signature is a 12-byte stride not 8, and `MSG_PETITION_DECLINE` writes the charter guid and reads the decliner's — same width, opposite meaning
- two sessions, not one: the registrar is an NPC session (closed by walking away — its show event is one of the fourteen callers of the interact latch, so the registrar turns to face you) and the charter is bound to an item guid you carry across the city; right-clicking a charter in your bags opens it, keyed on template flag `0x2000` (item 5863 has no on-use spell and no quest, so every existing item-use arm declined it)
- the byte carve came back and rescored six named guesses — three confirmed, two corrected, one refuted: `PETITION_SHOW` is deferred until every signer name has resolved (the window never paints blank rows), `ClosePetition` on somebody else's charter sends `MSG_PETITION_DECLINE` ("sends nothing" had been chosen on principle and was wrong half the time), and founding a guild is silent — no `ERR_GUILD_FOUNDER_S`, the reference emits no text at all; the four success ids go to chat and the five refusals to the red error frame, three paraphrased strings are now the shipped ones (a sweep asserts all fifteen), and the `npc` unit token had never been fed — the registrar's name banner was blank; `WOW_PROBE_CHARTER=1` drives gossip → buy → open → rename → destroy live, 10/10
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- the stable master: `MSG_LIST_STABLED_PETS` both ways, the four mutations answered by one result byte, two slots priced from `StableSlotPrices.dbc` (500 and 50000 copper — the cap falls out of the data, corroborated by vmangos's `MAX_PET_STABLES` and the reference's `NUM_PET_STABLE_SLOTS`), rows seated by slot never by position (a petless hunter's list starts at a stabled row), slot 0 read from the wire because a dismissed pet has a row and no live unit, a re-list after every success because no result carries one, and `GetPetIcon` reading `CreatureFamily.dbc`'s icon column — which ships `Ability_Druid_CatForm` for both warlock families, asserted as shipped
- master loot: `CMSG_LOOT_MASTER_GIVE` (the slot is a byte here where the roll family's is a u32) and `SMSG_LOOT_MASTER_LIST`; the click gate is the wire's slot-type byte and nothing else — the reference never asks who the master looter is — so a MASTER row fires `OPEN_MASTER_LOOT_LIST` instead of a take and auto-loot skips every non-ALLOW row; the candidate array is bucketed by raid subgroup into blocks of five (a dense list would have filed every candidate under the wrong "Group N"), an unresolved name is nil so `UPDATE_MASTER_LOOT_LIST` has something to repaint, and a give re-checks the row is still MASTER before sending; found on the way: a master looter in another raid subgroup lit the crown on your own portrait
- `SetLootMethod` takes its third (threshold) argument; the reference's silent reset to Uncommon when it is absent is flagged and not adopted; the stable's model pane draws nothing yet — a stabled pet is a database row with no world entity, and a booth that renders from a bare display id is the next arc
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- the world camera's pick regression: its off-screen render target carried `scale_factor: 1.0`, so on a Retina display the camera reported physical pixels as logical and a centred cursor cast its pick ray into the upper-left quadrant — unit and GameObject picks, the occlusion ray, chat bubbles and `world_to_viewport` all broke at once; the target now carries the window's real scale factor, re-stamped when dragging between displays changes it mid-session — and the perf pill's overlap dodge had the same disease in miniature (`GetBottom()` answers in WoW UI units, the pill lays out in window px), so it now answers a fraction of the screen and works at any window height
- `boothHalfRate` defaults back to half-rate: a body pane's off-screen booth pass rendered every frame reads +7.6 ms of GPU at 4K (~1.6 ms at 1600×900), on exactly the weak GPUs that felt the last snapshot — the doll's item effects keep full speed, since they key on the pacing regime rather than the camera's active bit, so only the 30 fps animation cadence returns, and full-rate stays one `SetCVar` away
- a spell cast by a GameObject arrives with caster guid 0 — vmangos writes the caster slot from a `Unit*` its GameObject constructor never sets — and the whole visual body was dropped at the guid lookup; the decode now reads an empty caster slot as the packet's first guid, which with no cast item IS the caster, so the Lightwell's click plays its impact kit (sound 3155 and the head flash) instead of only the aura glow that hid the miss, and the object stops being mislabelled a cast item
- the world map's black hairlines: a `SetTexCoord` crop is not a texture, and a POI icon magnified to 2.08 px per texel sampled half a texel past its crop into the neighbouring atlas cell — an opaque black row bleeding over a cell that is fully transparent (the empty cell is the reference's own zone-level substitution); `UiQuad::uv_clamp` now insets the sampling window half a texel per axis, so a crop renders as if its sub-rect were its own clamped texture, and `WOW_UI_PICK=x,y` names every quad under a pixel — it found this one in a single run
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- the client synthesises its combat-log chat lines: 44 chat types over 34 GlobalString families from 7 packets, the reference's own four hops (classify both endpoints → chat type → string key → format), text resolved out of the player's own GlobalStrings — so damage meters and Quiver's TranqAnnouncer have something to parse; wow-re's byte round corrected six gates (owner is charmed-by then created-by, "party" is your subgroup, friend-or-foe is CanAttack, the range gate, the miss defaults, the damage-shield chat type)
- the collision prism follows the NATIVE display, not the rendered one: a druid in bear form keeps the druid's swim, splash and wade lines and a morph keeps the human's — worst divergence on shipped data 0.72 yd (tauren moonkin), the sign flipping by form
- the creature swim gate is on both legs: a unit that loses its flag mid-water is driven out of swim at any depth, as the reference drops a charmed creature to the seabed on the next tick
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- the social window's fourth tab, Raid: the eight-subgroup grid over the roster, drag a member between subgroups, Convert To Raid, promote / demote assistant, uninvite, Ready Check with its popup, and the Raid Info flyout on the new `CMSG_REQUEST_RAID_INFO` / `SMSG_RAID_INSTANCE_INFO` wire (byte-golden against vmangos, an empty answer decoding as an empty list); `raid1`..`raid40` unit tokens, and `/partytest raid` stages a roster for a solo look
- an imbue pressed with an empty weapon hand says "Your weapon hand is empty" instead of raising a cursor — the attribute bit has two readers in the reference and the second is the error (corrects the day's first cut)
- sounds route onto the reference's own voice buses with its per-bus caps (the 0x87ce60 table, pinned as bytes): weapon impacts and clangs share four voices, footsteps six, the attacker's grunt one, the victim's injury two — so a pack swinging together makes about a dozen voices where it made dozens
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- the auction house end to end: right-clicking an auctioneer opens Browse/Bids/Auctions on the server's reply — search, the category tree from your own DBCs, the reference's 50-a-page pager, multi-key sorting (directions corrected at the bytes), bid/buyout, the sell slot with deposit and duration, cancel with its fee popup; prices sit on the reference's own money-frame kit in lined-up columns, the twenty auction messages split refusals-red / outcomes-to-chat, and a won or sold auction reads as a proper mail receipt — the window's Lua re-worded in our own terms after the overlap ratchet caught the first cut leaning on the reference's text
- the PvP honor system whole: the Honor tab and the inspect page over a real wire model, with current rank and highest-ever rank correctly two different fields
- a day of reported fixes: WASD survives a /logout re-entry, addon settings save on a window close and Cmd+Q (exactly once — a mac close could fire the tail twice), clams open again, random-enchant items name themselves on every surface, the loot window's rows hold their seats with legible counts, idle players stop sinking through building floors, the shooter re-pulls between Auto Shots, portraits loosen ~19% to the client's own aspect-1.0 matrix, and big creatures thump the camera off the CameraShakes table
- character select clicks like 1.12 — captions whiten on hover, buttons fire on release, Humans face straight ahead off the stage bone's real yaw, the facing is per-character, and hunter/warlock pets stand beside you at their family-ramp size with their own emitters (the imp's flames), the Voidwalker's sequence-hidden shackles culled
- the smaller player-facing set: nameplate on/off rows in Options with the CanAttack category gate (emissaries stop plating), the bonus bar slides up with igBonusBarOpen, the camera's framing height glides on a shapeshift, the open letter evicts the centre seat, the far-band fog hull stops printing a pale horizon stripe at low view distance, the guide arrow is gold with per-source rim art, error text fades through its shadow too, and /convertraid converts the party
- README: the auction house and PvP honor move out of "not built yet"
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- druids get the shift cloud back in both directions, by the reference's own mechanism: every shapeshift aura add *or* remove arms a one-slot pending-morph latch that the model-swap rebuild drains and replays — which is why shifting out (a client-side cancel the server sends no visual for) puffs at all, and why a GM morph or a revive correctly shows nothing; the first fix that merely let one-shot effects survive the swap's teardown produced the right pixels for the wrong reason and is superseded
- the honor system lands whole: the Honor tab on the character window, the honor page on inspect, and thirteen missing Lua bindings over a real wire model — session/yesterday/this-week/last-week kills, lifetime HKs and DKs, rank progress and badge art
- the load-bearing find: your current rank and your highest-ever rank are two separately-streamed fields, and the one we already had was the wrong one for anyone who ever de-ranked; a binary cross-check corrected five display details after the build, down to the rank title never being gendered
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- the Terrain Distance slider is back on Options → Graphics, in its 1.12 seat and range (177–777, live, no Apply) — and it now drives how much world is resident, not just how far you see: the streamer derives its resident and prefetch windows from farclip in the reference's own chunk units, pulling the ring in as you drag left and streaming it back one tile per frame as you drag right; the `WOW_TILE_RADIUS` env var, the debug panel's farclip slider and a dressed-up fog constant all retire into it
- ask a city guard for directions and the destination lands on your maps: `SMSG_GOSSIP_POI` becomes a red flag drawn through the same landmark path as towns and inns — an icon in place when near, competing for a rim arrow when off the edge — and the world map's landmark enumeration answers now, so the flag renders there too and names itself on hover
- the flag is one slot (new directions replace the last), drops itself within 10 yards of the destination, expires after the reference's own 480 seconds, and clears on any world entry; the rim-arrow rank rides the packet's own field, not a guessed constant
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- the four extra action bars become per-character options, off by default, on a new Action Bars options page — the toggles ride the server's own byte (`CMSG_SET_ACTIONBAR_TOGGLES` into `PLAYER_FIELD_BYTES`), so a fresh character's zero is the default for free; turning the bottom-left bar off gives the stance bar its previously unbuilt unraised look, end-caps and 64×64 rings
- bag windows stop drawing straight through a raised bottom bar: the bottom band has ONE owner — the manage pass — the bag stack joins it through a listener seam, and a guard test walks all eight raisable-bar combinations across 24 bar/tenant pairs and refuses overlap
- the item-push card takes the reference's real geometry, closing the gap 0887 measured
- resizable addon windows stop at their bounds instead of pinning and walking across the screen: four per-frame f32s with 0.0 the disable sentinel, the clamp on the interactive drag only with the residual rebated out of the drag delta, `<ResizeBounds>` in XML honoured — and `SetFontString`'s three raises land exactly as the bytes have them
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- the camera auto-follow returns, as a setting: Camera Following Style on the Controls options page — Smart (the default), Always, Never — so after an orbit drag the camera swings back behind you while you run; far sight still forces the chase off
- broken addons announce themselves: world entry prints "3 addon load failures — type /errors to see them", and the `/errors` window lists every script error this session with its traceback — 256 deduplicated rows, repeats collapsing onto a count — while the five load-failure classes that only ever hit the terminal (missing .toc, unparseable FrameXML, dependency cycles…) finally get a channel
- B opens the backpack alone, SHIFT-B opens all bags, F8–F11 toggle the individual slots — the reference's six bag commands instead of one command wearing every chord; and the Skills page gets its CLOSE button, with the ALL fold in the row font
- cmangos-classic logons work: `CMSG_AUTH_SESSION` now carries the real client's twelve secure-addon records (342 bytes, compressing to 130) — an empty addon block is a shape no client can send, and cmangos kicks for it where vmangos shrugs; Warden-enabled anticheat remains a separate wall
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- the social window's third tab is live — the roster in both its views, the member card with its promote/demote/remove verbs, the rank editor's thirteen permissions, the guild information board, and the invite, leave, kick and note dialogs behind them
- setting your hearthstone at an innkeeper now asks before it takes and says so afterwards, and the innkeeper's gossip lines get their own icons back
- unavailable talents grey out, and every greyed icon in the client now goes through the same luminance fold the original used
- the buff tooltip's remaining-time line reads gold with the client's own hour/minute ladder, the macro editor takes a shift-click to paste a spell, trainer rows repaint after a purchase, and a long book page stops flickering its ellipsis
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- dialogs carry the reference's toplevel bit, so the stack-split window opens above Bagnon instead of behind it
- the failure line fills its blank — "Requires Blacksmith Hammer", not "Requires" — and Opening casts stop printing a label the spell itself marks "no text"
- the pet bar's Attack/Follow/Stay tooltips name their keybinding, and typed text reaches the focused frame through the client's own delivery walk
- AtlasLoot parses again: our Lua keeps 5.0's compatibility semicolon
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- a channel line renders in the channel family's color, not the grey notice row the client consults and throws away
- a text emote composes its sentence — gender and target picked from the game's own tables — so a /wave is a line in chat, not just an animation
- a FontString's `font=` resolves a font object by name and gates the whole block, `<Gradient>` tints the art it sits on, and buttons' state fonts read `font=` too — Bagnon's white boxes and bare stack counts are fixed
- the money frame sizes its coins from the digits themselves, so Bagnon's gold stops opening cramped
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- the server picks the view and the mover independently — far sight moves the eye, client control moves the reins, and Mind Control sets both, which is why its camera works for free
- while you hold another body's reins your own stands still, so the server never smears your pose onto the creature you drive
- the Ornate Spyglass is a local 6x zoom, not a camera move — there was never a wire half to be missing
- the scene election fails closed: three classes of creature that escaped it are back under its verdict
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>
- the Character window's third tab is in: faction rows under their headers, standing bars, the detail popup and the watch bar, at the reference's own anchors
- all four reputation opcodes parse byte-exact, the flag byte reads the way the client reads it, and a standing gain reveals the faction unless it is hidden
- an end-to-end golden drives live wire bytes through the game data to the exact visible row list
- the reference-code overlap is measured by an instrument instead of asserted — the start of a debt paid in full later in the day
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- SendAddonMessage sends on the real 1.12 lane — an ordinary chat message wearing the addon-language sentinel — across the party, raid, guild and battleground channels, byte-verified in the client binary
- the receive half fires CHAT_MSG_ADDON with the client's own four-argument shape, and the two halves are round-tripped against each other so they cannot drift apart silently
- the `|`-escape scan is carved from the binary: colour escapes inside a message survive exactly as the real client allows them
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- timed quests get their countdown — a Quest Timers box under the minimap and a Time Remaining line in the quest log, kept against the server's own clock
- interiors go honest: footsteps stop crunching the terrain's snow through a building's floor, and tavern voices are authored dry, so the fake cave echo is gone
- snow is the reference's again — point-sprite flakes at the era's pixel size, and a spawn slab that leans into your run so a runner no longer outruns the field
- Stormwind stops drawing Elwynn through its walls, a looted quest crate's lid settles, cold zones puff visible breath, and the collect-quest toast fires only on a real advance
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- ctrl-click an item to try it on: the dressing room dresses your double, and shift-click posts the item link to chat
- the pet tab lands in the character window: paper doll stats, family and diet, the right-click menu, and dropping food on the pet feeds it
- water-only spells refuse on dry land: aquatic form gates to swimming, client-side like the real one
- the macro icon picker's white squares get their art back, and option rows explain themselves on hover
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- feign death plays dead for real: the body collapses and stays down, both bars read 0 and DEAD, the nameplate drops, the combat hum goes quiet
- melee and Auto Shot are exclusive now: starting one stops the other, even mid-swing
- another client's addon chatter no longer prints as party chat
- right-click presses look pressed, rage and happiness read on their real scale, and the login boxes blink their caret
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- a building's transition corridors carry the reference's bright-doorway fade: the black tunnel between sunlit outside and a lit interior is gone
- the Options window gets its first real pages: seven 1.12 sound rows on Audio and the two 1.12 Video Options sliders on Graphics, all live CVars
- terrain culls like the real client: the ground is one-sided, so from underneath you see through it exactly as 1.12.1 does
- the beam system's data plane lands: 48 live chain, drain and funnel beams read off the real patch chain, with a byte-exact wire golden — the renderer follows
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- the loading screen now compiles every shader the world can reach: sky, water, spell shards and model variants stop hitching the first time they appear
- a locked chest's cursor carries the LOCKED word like the real client, and the lock verdict never leaks into the sent packet
- enchanting asks before it acts: a bind-on-enchant item gets its confirm popup, and so does replacing an enchant that's already there
- a long gossip menu scrolls like the reference with rows grown to their wrapped text, and music already playing is not restarted when the server re-sends it
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- clicking your mount item while mounted dismounts you, and the mount icon no longer wears a stack "1"
- the horse appears and you're simply in the seat pose with the mount's cloud puff, no spellcast finishing over the saddle — and dismounting cuts clean to standing, no phantom jump-landing
- a mounted rider counter-turns head only, item-targeted spells show the targeting cursor, and the wrong thing in a quiver says "Only Arrows can be placed in that."
- liquid lookups ride a spatial index, and the camera's waterline comes from the client's own corner probe
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- the mount transition re-seats the rider instead of rebuilding them: shield glows, weapon enchants and worn visuals stay lit through mount and dismount
- an enchanted item's tooltip carries its enchant line, coloured per slot, with a temporary enchant's countdown
- a server refusal with nothing to say now says nothing: the raw "Inventory error" debug line is gone, real refusals still print
- the mail icon clears when you close the mailbox, and translucent models classify against the water plane
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- /target and /assist find units by name like the original, and /follow walks you behind your target
- right click opens clams and lockboxes, and the tooltip promises it
- the freeze thaws clean, poses release instead of sticking, and you drop to neutral standing before it grips
- unit frame art layers over the bars like the original
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>
- crossing into a new zone lands the whole discovery moment: the "Discovered" toast, the experience line in chat, and the race-keyed jingle
- crossing a tile boundary no longer recycles a whole row of terrain: a keep-band holds what you just left, unloading is budgeted, and fresh requests stagger instead of bursting
- a sheath swap moves the weapon (and its sparkles) to the new slot instead of rebuilding it, and a fading model now dims its own effects with it
- pressing the cast button again cancels the cast, and a form that can't cast a spell refuses it locally instead of round-tripping the server
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- ground-targeted spells work end to end: press the button, get the targeting cursor, click the ground, and the cast ships on the wire the way the real client sends it
- a reticle sized to the spell's real radius rides the cursor, and on the click the storm model, falling shards and area sound all land at the point
- character screens: a newly created character comes back selected on the list, and the authored layout scales to small windows instead of clipping the bottom controls off
- blob shadows ride their receiver's clip transform and the raster bias that kept them faint is measured and fixed
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- The keyring is built. Your first key makes the keyring button appear by
the bags, opening the window the original keeps its dungeon keys in — the
server had been sending the keys all along; nothing had ever shown them.
- Keys open their doors now. The client used to cast the open as a bare
spell, which the server rightly refuses; it now sends the item-use the
original sends, carrying which key from which slot. The tooltip plays
along: "Locked" turns the soft green when something you carry opens it,
and a key stops inventing a "Use: Opening" line it never had.
- A building can own the sky: a WMO can name its own painted skybox, and
Stratholme's burning city now draws its near-black-to-red dome instead of
the zone's khaki gradient. The exact rule for when it applies settles in
the next snapshot.
- Signpost tooltips follow the cursor again — the tooltip anchor forks per
object class, corner for doors, cursor for signs — and the Blasted Lands
lightning stops striking the same spot for ever: a placed doodad re-rolls
its animation variation every play-window, like the original.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- The second half of the open-door fix: the system that applies a door's
state to its collider had never run once. The state arrives with the
spawn, the collider is baked from the model hull frames later, and the
reconcile demanded both in the same frame — so every door kept the solid
collider it was born with. Open gates and forcefields are walkable now,
and the inspector prints solid-or-passable out loud.
- The mouseover follows the original's law: an object you cannot use — in
use, waiting on a quest, or hostile-faction scenery like the enemy's own
doors — shows nothing at all on hover. No tooltip, no highlight, no
cursor. Each object type answers for itself, the way the real client
dispatches it.
- Dun Morogh's snow trees lose their white plates and hard creases: model
textures authored clamp-to-edge were all sampled repeat-wrapped, so a
canopy's deliberate out-of-range margin wrapped back into opaque texels.
The sampler honours the authored address mode now, on this tree, a bad
bush, and hundreds of models like them.
- Odds and ends: the Blasted Lands lightning can actually strike (its
emitters sampled an animation slot that is silent for that model),
donation turn-in quests show their real Continue panel, boss emotes expand
their $name macros, and a rare one-in-256 login failure — a session key
the client hashed differently than the server does — is gone.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Why fences glowed noon-warm at midnight: our sun lane multiplied the
day/night colour by the client's documented 2.5 for doodads on lit ground,
which pushes past white and clips to a daylit face. Two days of binary
archaeology confirmed that multiply is real — on a render path the
reference machine turns out not to run.
- The settle was an API trace of the actual 1.12.1 client standing at the
same fences: on its Direct3D path the sun arrives at the day/night colour
clamped to at most full strength — one for lit ground, half in baked
shadow, never brighter than the palette. Our lane now commits exactly
that. Midnight is moonlit blue, and adjacent lit/shaded fences blend the
way the original does.
- Along the way: a capture-window override for era-resolution A/Bs, and a
calibration dial that lived exactly one day — the by-eye level it found
matched the traced law to a few parts in 255, then retired.
- Separately, the $-macro text expander now runs everywhere the original
runs it: chat lines, mail bodies and item text, not just the UI strings.
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>
- The social window: friends, ignore and `/who`, in the reference's own two-level
arrangement with its inner tabs and per-row right-click menus. The lists ride the
real wire — guid-keyed with no names, resolved through the name cache, and capped
at 50 friends / 25 ignores because those are the client's own caps — and the
ignore list does its actual job: an ignored speaker's chat is dropped silently, a
whisper additionally tells the sender, and a duel challenge is auto-declined.
Guild ships as a disabled tab, which is what a guildless character sees.
- The escape menu: ESC's last rung finally opens something. The game menu lands at
the reference's own size and ladder, and leaving works — logout and quit with the
server owning the clock (instant at an inn, refused in combat, or the 20-second
countdown), narrated by the real camp/quit dialogs. While the menu holds the
center nothing else opens, and the bag bar greys out under it.
- Items on the action bar act like items. An equipped trinket was a dead button;
the reference's use law is two stages — not equippable means use, equippable and
already worn means use in place — over its exact search order (equipment first,
then the bags, then the backpack, then the keyring; never the bank). What can go
on the bar is now the reference's own two filters, byte-read: an item with an
on-use spell or one you can equip, and no passive spells — and dropping a passive
there speaks the real client's own line, "You can't put a passive ability in the
action bar."
- A quest-starter item opens its quest instead of "The item was not found." The
question goes to the item's own guid, never through item-use — which the server
refuses for every one of the 215 quest-starter items — and refusing the quest
says what the client says, then closes the window.
- For the toolbox: a pixel pick that reports everything under the cursor all the
way back, a lens that says which render phase a draw landed in, and switches that
separate "discarded" from "lost depth" from "never drawn" — built while cornering
a flickering tent, whose fix ships in the next snapshot.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Duels. Challenge another player from their right-click menu, or with `/duel`, and
`/forfeit` to give it up. Both popups are there — the challenge you accept or decline, and
the warning when you leave the field — with the flag countdown between them, and the outcome
printed in chat when someone is knocked out or flees. Read off the reference client's own
duel packets and the three globals it keeps client-side, which is why the challenger reads
"You have requested a duel." even though the server never echoes that back.
- Inspect. Right-click a player and open their paper doll: their nineteen publicly visible
equipment slots with icon, name, quality and a linkable item, and their body standing in
the pane, which follows along if you retarget while the window is open. No stack counts and
no durability — those are not fields another player publishes, which is exactly why the
reference client's inspect doll has never shown them either.
- Water knows where it stops. Swimming used to trigger in the dry tunnel thirty yards under
Stormwind's canal, and in mid-air over Blackrock's lava. A liquid is now the grid the map
file actually stores — one wet flag per cell, and the surface height a bilinear over the
four corners of the cell you are standing in, the same sample the reference client takes —
so the water starts at the bank and its surface sits where your eye puts it. Lava is a
liquid you swim in, an indoor liquid asks the building you are inside, and `/liquid` prints
every surface claiming your feet and where each one came from.
- Creature parts authored to appear only on death — the voidwalker, the banshee, the ooze,
the stone elemental, the infernal — were drawing the whole time: material alpha now bakes
per animation sequence and the unit lane actually evaluates it. The character and inspect
model panes are lit by the reference widget's own single light instead of blowing out white,
the rotate arrows spin while you hold them, and the transparent sort ladder had its sign
backwards, so overhead names draw over water again instead of being painted out by a canal
behind them. Underneath, the protocol writer's 95-verb drawer and its thousand-line spell
module split into per-family files — no behaviour change, just a tree you can find things in.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- Other players walk the world. A watched player's motion between server updates now runs through
the same grounded movement resolve as your own character — same capsule, same colliders, same
step-up and ground election — so they follow terrain every frame instead of every packet, and
stop at a wall instead of walking into it and being snapped back. Their jumps are swept against
the world too, and a standstill jump steered mid-air reports that steer, the one mid-air press
the reference client broadcasts rather than defers.
- The move relay rebuilt: relayed moves ride a per-unit chain on real time, a due move never jumps
ahead of its unit's queue, and SMSG_COMPRESSED_MOVES — the batched carrier the server sends under
load — is decoded rather than skipped. Our own send path now matches the reference client's:
facing streams while moving, Nagle is off so each packet is one write, and the strafe axis nets so
left and right can never ride the same packet.
- NPC and quest text speaks the whole $-macro grammar, carved from the reference bytes — your name,
class and race, the gendered forms, and the server's live world states — and the same
substitution feeds gossip, quest text, the quest log and unit frames. Greetings are a weighted
draw, rolled per NPC per open, and a quest giver with no quest to give is no longer clickable,
where it used to open a dialog holding nothing but a placeholder greeting.
- Spell tooltips finish the reference's line law: cast time and cooldown behind the real passive
gate, the required tool or form, the reagents block, the chance-to-X line, a multi-bit
equipped-item requirement named properly instead of by raw bits, and a buff's dispel class.
- The UI layout engine got a dense, reusable anchor solver, and a change gate that skips the resolve
entirely on frames where no layout input moved — in practice, almost every idle frame. Pets are
named by their pet number rather than a creature-template entry, so the client asks the query the
server can actually answer. And the asset extractor grew a stray-geometry census for tracking
down geometry that renders where it should not.
This snapshot replaces the six dated `sync` commits that stood here before it, whose subjects said
nothing but the date. If you cloned before now: `git fetch && git reset --hard origin/main`.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>