Keep the persistent selection indicator above retail's waiting mesh, use the normal green accept circle for backpack-grid placement, and reserve the green drop-in arrow for bag-column containers as ItemList_DragOver does.
Co-Authored-By: Codex <codex@openai.com>
Keep retail's underlay-free m_pDragIcon separate from the full cell icon and reveal the authored ghost mesh on physical source cells for the complete drag lifecycle. This removes the backpack backing from the cursor and retires AP-47.
Co-Authored-By: Codex <codex@openai.com>
Clear retail AutoWield on the matching authoritative WieldObject instead of waiting for unrelated rollback bookkeeping to drain. This prevents a completed switch from consuming the next weapon activation locally, including crossbows.
Co-Authored-By: Codex <codex@openai.com>
Keep the retail inventory transaction busy until authoritative WieldObject confirms the requested weapon. This prevents rapid weapon changes from overlapping on ACE and rejecting otherwise valid items such as spears.
Co-Authored-By: Codex <codex@openai.com>
Preserve retail AmmoType from CreateObject and port BlocksUseOfShield so bow, caster, and two-handed switches remove incompatible shields, while mismatched missile ammo is also returned to the pack. Each blocker remains server-confirmed before AutoWield re-enters.
Co-Authored-By: Codex <codex@openai.com>
Sequence primary weapon replacement through the server-confirmed AutoWield transaction: return the occupied weapon to the player pack, wait for its move event, then wield the requested item. Route authoritative CombatMode property updates so peace stays peace and war adopts the new weapon stance without client-synthesized animation.
Co-Authored-By: Codex <codex@openai.com>
Treat combat-window visibility as gameplay-state owned so character layout restoration cannot replay a stale visible bit. Reset combat state to NonCombat at character-session entry, matching retail ClientCombatSystem::Begin.
Co-Authored-By: Codex <codex@openai.com>
Port retail's radius-aware placement ring so a relogging player is seated beside creatures occupying the saved location, and register the local body in the shared resolved-shadow pipeline. Route new forward movement and jump through AbortAutomaticAttack so repeat combat cancels immediately on movement.
Co-Authored-By: Codex <codex@openai.com>
Carry the consumed dark-range child's own retail edge policy into the procedural scrollbar, widening it to the authored post-reflow interval without covering the rendered labels. Restore the bright layer to live attack-charge feedback across the full bar from the left.
Co-Authored-By: Codex <codex@openai.com>
Derive the dark middle range from live post-anchor sibling geometry instead of freezing the inherited 800-pixel prototype during controller binding. Render the user-directed bright desired-power band independently from the absolute bar-left edge to the green thumb center.
Co-Authored-By: Codex <codex@openai.com>
Read the authored meter direction instead of inferring it from the combat element id, so the bright charge texture grows left-to-right from Speed. Keep the user-approved dark-red middle baseline visible independently and record its exact retail Recklessness visibility edge.
Co-Authored-By: Codex <codex@openai.com>
Preserve the authored gray track, trained-Recklessness range, live bright charge meter, and independent desired-power thumb while keeping Speed and Power over gray side regions. Correct retail text justification value 2 to left alignment and retain direct RenderSurface decoding in the texture inspection tool used to verify the assets.
Co-Authored-By: Codex <codex@openai.com>
Make the retained toolbar consume retail's payload-free selection notice from canonical live state so a reentrant Auto Target replacement cannot be erased by the outer clear. Restrict automatic acquisition to the requested hostile non-player monster policy and record the intentional PK edge divergence.
Co-Authored-By: Codex <codex@openai.com>
Replace the door-specific static-animation seed with one retail description-then-enter-world initializer shared by normal and reactive spawns. This preserves authoritative Dead and On/Off states, prevents replacement corpses from returning to Ready, and pins the lifecycle with Core and App tests.
Co-Authored-By: Codex <codex@openai.com>
Keep the velocity-only NPC adaptation inside the locomotion family so authoritative Dead motion remains persistent. Route selection clears through a dedicated combat target controller that reacquires the closest eligible creature when retail Auto Target conditions apply.
Co-Authored-By: Codex <codex@openai.com>
Keep AttackDone control statuses out of chat, preserve dead motion across zero-velocity position updates, render the authored power meter from right to left, and retain the rotatable viewer offset during target tracking.
Co-Authored-By: Codex <codex@openai.com>
Port ClientCombatSystem's Keep in View consumer through CameraSet's pivot-to-target boom heading, including the transformed half-metre target offset and melee/missile validity gates. Preserve the existing stateful chase damping and collision architecture, with conformance coverage and named-retail pseudocode.
Co-Authored-By: Codex <codex@openai.com>
Resolve authored StringInfo labels from local.dat, port gmCombatUI's runtime option captions and checkbox widgets, and bind horizontal scrollbar media by retail structural roles so the green power jewel is a thumb instead of a tiled track. Persist the three combat options and make Auto Target govern target acquisition.
Co-Authored-By: Codex <codex@openai.com>
Mount authored gmCombatUI, share one press/hold/release request state machine across DAT buttons and keybindings, and recover the exact 1.0s/0.8s power timing from matching retail x86. The same timer fixes jump charge, while ready-stance, response queueing, auto-repeat, layout binding, migration, and conformance coverage keep behavior architectural rather than panel-local.
Co-Authored-By: Codex <codex@openai.com>
Route accepted non-autonomous local UpdateMotion state through retail's wholesale interpreted-motion funnel, so ACE-selected melee and missile actions use the normal motion queue and action-stamp gate. Share nullable wire conversion with remotes and remove the local direct command replay.
Co-Authored-By: Codex <codex@openai.com>
Select the default combat mode from ordered equipped objects so bows request missile stance. Parse CreateObject parent metadata and ParentEvent, then render held objects as separate children composed from setup holding locations and placement frames each animation tick.
Resolve stacked thrown weapons versus separately equipped missile ammo exactly like gmToolbarUI, normalize a zero stack to one, and refresh the authored missile indicator from equipment and stack events. Keep the decision in pure Core with retained and real-DAT conformance coverage.
Co-Authored-By: Codex <codex@openai.com>
Discover all seven panel launchers from their DAT panel-id attributes, route mounted panels through event-driven retained window state, and ghost unavailable panels. Port Use and Examine selection/target behavior with exact Appraise dispatch and retail cursor modes.
Co-Authored-By: Codex <codex@openai.com>
Resolve and sample retail's authored nine-color paperdoll click map, preserve local click coordinates, and select the stable highest-priority worn item with the player fallback. Keep targeted-use body clicks routed to self and pin both synthetic and live-DAT conformance.
Co-Authored-By: Codex <codex@openai.com>
Replace the toolbar's PWD-bit approximation with retail ObjectIsAttackable composed with the exact player and pet short-circuits. Carry second-header PetOwner through CreateObject, session, and ClientObject state so self, pet, and Free-PK cases match retail while friendly NPCs and attackable non-creatures remain name-only.
Co-Authored-By: Codex <codex@openai.com>
Parse and route the complete 0x0264 guid/fraction/valid response, send exact 0x0263 item-mana queries, and reproduce retail meter visibility plus guid-zero cancellation for mana and health selection changes. Keep the behavior in Core state and the retained selected-object controller with wire/state/UI conformance coverage.
Co-Authored-By: Codex <codex@openai.com>
Preserve pixel scroll offsets across inventory rebuilds, crop partially visible rows with nested geometry/UV clips, and replace the obsolete 560px resize ceiling with available screen height. Keep retail's row-sized wheel step while allowing continuous scrollbar thumb positions.
Co-Authored-By: Codex <codex@openai.com>
Route the selected stack quantity through retail GetObjectSplitSize semantics, send exact split-to-container and split-to-ground actions, and keep the original object in place until the server publishes the newly guided stack. Cover selection scoping, wire bytes, container placement, and world drops with conformance tests.
Co-Authored-By: Codex <codex@openai.com>
Keep the horizontal thumb at its raw pointer position so both endpoints are reachable, honor the stack entry's authored right alignment, and preserve PublicWeenieDesc plural names from CreateObject through the object table. Port retail's singular s/es fallback when no plural was sent.
Co-Authored-By: Codex <codex@openai.com>
Bind the authored stack count entry and horizontal slider to one Core split-quantity owner, preserve retail count-first naming and exact 1000-step rounding, refresh on stack changes, and consume the selected amount during merges. Conformance covers the production DAT fixture and retained pointer/focus paths.
Co-Authored-By: Codex <codex@openai.com>
Give retained buttons a reusable item-drop seam, wire the toolbar backpack target, and port retail stack-merge legality, capacity clamping, wire dispatch, destination selection, and immediate shortcut rekey notice. Record the live ACE merge gate and keep split quantity under AP-101.
Co-Authored-By: Codex <codex@openai.com>
Plan retail shortcut drops from a complete post-lift snapshot so fresh inventory items use cyclic-right displacement while toolbar aliases restore to their vacated slot. Apply local mutations atomically, preserve raw shortcut fields, emit exact Remove/Add ordering, and retire AP-102 after the live ACE gate.
Co-Authored-By: Codex <codex@openai.com>
Carry signed index, object id, and raw spell word losslessly through PlayerDescription, session storage, drag mutation, and AddShortcut wire serialization while keeping gmToolbarUI object-only. Retire AP-103 and record the live ACE relog persistence gate.
Co-Authored-By: Codex <codex@openai.com>
Port global toolbar use/select/create actions, migrate the collapsed Ctrl-number bindings, and route them through a focused retained-UI controller. Preserve shortcut aliases as aliases across inventory and paperdoll drops with retail's neutral/accept/reject drag states, preventing physical item moves such as unwielding an equipped helmet.
Co-Authored-By: Codex <codex@openai.com>
Port every reachable ClientUISystem cursor branch through the production DAT enum map, preserve global-default versus widget-local event ordering, and surface the registered OS fallback. Route all four toolbar stance indicators through the same combat toggle command as the key binding, with golden DAT and transition conformance coverage.
Co-Authored-By: Codex <codex@openai.com>
Route ACE server commands through the existing chat path, bind the retail paperdoll hit mask instead of its obscured viewport, and prefer authoritative private health vitals. Record the user-confirmed live gate and pin the production DAT widget type in tests.
Root cause (measured, not guessed): the OOM was a MANAGED Large-Object-Heap leak
(~5 GB in 6 min of roaming; working set 1.6 GB -> 7.6 GB), dominated by ~3.8 GB of
live System.Single[]. A heap-retention analysis of a captured gcdump traced 241 of
242 giant float arrays to a single List<float>: WbDrawDispatcher.InstanceGroup.Opacities.
#188 (2026-07-09, fading doors) added Opacities as a 5th per-instance parallel list
alongside Matrices/Slots/LightSets/IndoorFlags, but left it out of the per-frame
clear loop (WbDrawDispatcher.cs:959). So Opacities.Add(1.0f) fired once per drawn
instance per frame and the list never reset — growing forever; List<float> capacity
doubling produced the observed ~128 MB / ~512 MB power-of-two arrays and OOM after
~50 min. Hit both UI builds because it's core render, and started only recently
because Opacities did not exist before #188.
Fix: extract the per-frame reset into InstanceGroup.ClearPerInstanceData() (promoted
InstanceGroup private->internal) that clears ALL FIVE parallel lists in one place, so
a future 6th list can't silently drift out of the frame lifecycle again. Line 959 now
calls it. TDD: InstanceGroupClearTests asserts every parallel list resets (RED with
the old 4-list clear, GREEN after adding Opacities.Clear()).
Static-audit note: this is exactly why we measured before fixing — the audit ranked
GlobalMeshBuffer (GPU) #1 and the entity-dict leak #3; both were wrong about the
dominant cause. The dotnet-counters (managed vs native) + gcdump retention graph
named the real one-line culprit.
Secondary (NOT this commit): _groups dictionary is never pruned (bounded by distinct
group keys, empty groups are cheap) — filed as a follow-up, not the multi-GB driver.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>