Commit graph

339 commits

Author SHA1 Message Date
Erik
84b7d2d7cd fix(ui): port live experience quality updates (#217)
Parse retail PrivateUpdatePropertyInt64 and route authoritative Total/Available Experience through both local-player projections so Attributes, the level meter, and Skills refresh together. Preserve the existing retail XP curve and right-align the Total XP value.

Close the user-confirmed item-give gate for #216 and record the named-retail/ACE/holtburger conformance evidence.

Co-Authored-By: Codex <noreply@openai.com>
2026-07-13 20:43:48 +02:00
Erik
30d294506c feat(inventory): port retail item giving (#216)
Preserve SmartBox drag-release coordinates, route the picked 3-D target through the retail AttemptPlaceIn3D policy, and send authoritative GiveObject requests with the selected stack quantity. Honor PlayerDescription's player secure-trade option and document the remaining trade-system boundary.

Co-Authored-By: Codex <noreply@openai.com>
2026-07-13 20:28:48 +02:00
Erik
a944e49b9c docs: close dungeon publication and respawn issues
Record the passed visual gates for #214 and #215 and move both completed entries into the recently closed ledger.

Co-Authored-By: Codex <noreply@openai.com>
2026-07-13 20:14:46 +02:00
Erik
0ad6700a07 fix(teleport): preserve dungeon cell identity on respawn (#215)
Classify teleport landblock transitions from the source and destination Position cell IDs instead of render-space coordinates. This keeps same-dungeon death respawns on their resident floor physics while preserving the existing true cross-landblock streaming path.

Co-Authored-By: Codex <noreply@openai.com>
2026-07-13 20:08:21 +02:00
Erik
b0c175afc0 fix(streaming): commit EnvCell landblocks atomically (#214)
Carry one complete cell payload with each streaming completion and publish visibility, physics, and render state on the render thread. Remove the obsolete post-readiness login reload that triggered a duplicate dungeon build.

Co-Authored-By: Codex <noreply@openai.com>
2026-07-13 18:45:24 +02:00
Erik
66bdae7a83 feat(ui): port retail dialog factory lifecycle
Replace the single mutable confirmation service with retail's property-backed DialogFactory model: fresh DAT roots, context ids, queue groups, priority preemption, callback/close-notice ordering, and context cancellation. Route /die, server confirmation aborts, and guarded item use through focused semantic owners.

Co-Authored-By: Codex <codex@openai.com>
2026-07-13 16:30:05 +02:00
Erik
43f7c7807c fix #213: complete suicide and framerate presentation
Translate suicide response 0x004A as retail's successful self-kill notice. Port /framerate onto the authored SmartBox FPS element with live two-decimal FPS and DEG values, keep diagnostic window chrome independent, and synchronize command-driven settings without discarding panel drafts.

Co-Authored-By: Codex <codex@openai.com>
2026-07-13 15:50:47 +02:00
Erik
9ea579bdd0 feat(chat): port retail client command families
Expand the typed client-command boundary across travel, character queries, local UI and layout controls, AFK and consent, emotes, friends, squelch and filters, and fill-components. Preserve retail packet layouts and queue ownership, import the confirmation dialog, and keep authoritative social state in Core.

Co-Authored-By: Codex <codex@openai.com>
2026-07-13 14:50:15 +02:00
Erik
5a45a7ac7f feat(chat): route retail lifestone commands
Separate retail client actions, ACE server commands, and ordinary chat at the shared router. Port lifestone/lif/ls from the named retail registry through a typed App controller to game action 0x0063, keep unknown verbs on ACE Talk, and cover both UI backends plus exact outbound bytes.

Co-Authored-By: Codex <codex@openai.com>
2026-07-13 11:43:19 +02:00
Erik
5090aa7217 fix #212: preserve shortcut tint in physical combat
Port the retail m_bShortcutGhosted meaning instead of treating SetShortcutNum's boolean as peace versus war. Keep occupied shortcut numbers on the gold sheet in NonCombat, Melee, and Missile, reserve the gray sheet for Magic, and lock the four-mode matrix with conformance tests and corrected research.

Co-Authored-By: Codex <codex@openai.com>
2026-07-13 11:21:12 +02:00
Erik
ab98cda26b fix #211: index login-equipped items under player
Project PlayerDescription equipment through the same contained-by-wielder ownership and ordered contents index as live WieldObject updates. Preserve equip masks and priorities so retail GetObjectAtLocation selects Missile for an already-equipped crossbow instead of sending a server-rejected Melee request.

Co-Authored-By: Codex <codex@openai.com>
2026-07-13 10:40:29 +02:00
Erik
e74efc5c06 fix #210: stabilize mouse-up capture ownership
Pin each mouse-up to its original captured target before callbacks can hide a window or transfer capture. Classify double-clicks before dispatch, preserve replacement capture owners, and cover both re-entrant paths so jump/combat visibility changes cannot crash the UI root.

Co-Authored-By: Codex <codex@openai.com>
2026-07-13 10:27:27 +02:00
Erik
db03b4bda8 feat(ui): port retail jump power bar
Import gmFloatyPowerBarUI LayoutDesc 0x21000072, teach the meter factory its stateful single-image shape, and project the movement-owned retail jump charge through a focused retained controller. Preserve authored resize constraints and state-managed visibility, with named-decomp pseudocode plus controller, movement, and production-DAT conformance coverage.

Co-Authored-By: Codex <codex@openai.com>
2026-07-13 10:22:12 +02:00
Erik
27619b2328 docs(ui): record Aetheria slot visual gate
Record the connected 2026-07-13 confirmation that ACE Aetheria states 0/1/3/7 progressively reveal none, blue, blue+yellow, and all slots with the authored backgrounds and no relog.

Co-Authored-By: Codex <codex@openai.com>
2026-07-13 10:00:46 +02:00
Erik
edc9be3008 fix(paperdoll): port quest-gated Aetheria slots
Add the three authored blue, yellow, and red sigil backgrounds and drive their visibility from player PropertyInt.AetheriaBitfield bits 1/2/4 at login and on live updates, matching gmPaperDollUI::UpdateAetheria. Include the sigil equip masks in the shared slot table and narrow AP-108.

Co-Authored-By: Codex <codex@openai.com>
2026-07-13 09:55:20 +02:00
Erik
1be18cc4db fix(paperdoll): restore authored slot backgrounds
Port the retail UIItem catalog path so every supported equipment location resolves its exact empty-state silhouette from live DAT. Share one definition table between equip behavior and presentation, wire runtime plus UI Studio, pin all 21 prototypes and surfaces, and retire AP-66.

Co-Authored-By: Codex <codex@openai.com>
2026-07-13 09:43:21 +02:00
Erik
8e9c538519 fix #208: keep combat bar hidden in peace mode
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>
2026-07-12 22:30:55 +02:00
Erik
00fe993f6f fix(combat): escape occupied login positions
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>
2026-07-12 22:20:17 +02:00
Erik
0f2d98c501 fix(combat): synchronize auto-target presentation
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>
2026-07-12 20:26:00 +02:00
Erik
8be933fc94 fix(animation): preserve wire motion on every spawn path
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>
2026-07-12 14:27:44 +02:00
Erik
ab6d96d113 feat(combat): port retail held weapon parenting
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.
2026-07-11 13:02:26 +02:00
Erik
d3d1c895a0 feat(ui): finish retail toolbar controls
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>
2026-07-11 12:11:53 +02:00
Erik
21fefce0e0 docs(ui): close selected-object live gate
Record the exact paperdoll body-selection confirmation, mark Wave 4.4c shipped, and close issue #141 now that every selected-object branch has passed live.

Co-Authored-By: Codex <codex@openai.com>
2026-07-11 11:58:37 +02:00
Erik
0b74d19475 fix(ui): port exact paperdoll body selection
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>
2026-07-11 11:56:26 +02:00
Erik
2644d1d527 fix(ui): port exact selected health policy
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>
2026-07-11 11:42:04 +02:00
Erik
52a80dc531 docs(ui): record selected-item mana live gate
Record the live Mana Stone source-destruction, armor transfer, and authoritative selected-meter update confirmation. Mark Wave 4.4b shipped while retaining the exact health-target policy as the remaining D.5.3 gap.

Co-Authored-By: Codex <codex@openai.com>
2026-07-11 11:32:01 +02:00
Erik
fa1da02783 feat(ui): port retail selected-item mana
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>
2026-07-11 11:16:21 +02:00
Erik
df460f94c3 docs(ui): record inventory scroll visual gate
Mark issue #147 done after live confirmation of vertical resize, clipped partial-row scrolling, and scroll-offset preservation across inventory mutations.

Co-Authored-By: Codex <codex@openai.com>
2026-07-11 10:59:42 +02:00
Erik
15aa3b9aff fix(ui): complete retail inventory scroll polish
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>
2026-07-11 10:56:33 +02:00
Erik
ea72c395c9 fix(ui): port retail partial stack transfers
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>
2026-07-11 10:34:13 +02:00
Erik
6005c51c4d fix(ui): finish retail stack selector polish
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>
2026-07-11 10:22:11 +02:00
Erik
a20e5c68c7 feat(ui): port retail selected-stack quantity
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>
2026-07-11 10:07:25 +02:00
Erik
eb6229394a fix(ui): unify target-mode primary clicks 2026-07-11 01:36:43 +02:00
Erik
c7607f019c fix #203: preserve animation on appearance updates 2026-07-11 00:25:29 +02:00
Erik
44f9ec13d9 docs(ui): pin retained widget retail oracles 2026-07-10 17:55:28 +02:00
Erik
5931a820ea docs(ui): repair retail fidelity ledger 2026-07-10 17:05:12 +02:00
Erik
f98050854d docs(ui): align architecture with retained runtime 2026-07-10 16:57:44 +02:00
Erik
9bd3a98363 docs: close #193 (OOM — Opacities leak, measurement-verified) + file #194
#193 FIXED (119a2326), verified by before/after dotnet-counters on the same
6-min churny roam: LOH 1.1→6.1 GB climbing (leaked) vs 0.24→0.64 GB then FLAT
(fixed); no crash. #194 filed: WbDrawDispatcher._groups never pruned (LOW,
bounded, not a crash risk) — surfaced during the #193 heap analysis.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 14:24:30 +02:00
Erik
02487da0ce docs: file #193 — client OOMs after ~50 min of play (two crashes 2026-07-10)
Two reproducible Out-of-memory crashes in one evening (Release build): one after
an extended dev-UI session, one after ~50 min of retail-UI play. Cause
uncharacterized. Filed post-M2 (stability, not M2 critical path).

Explicitly warns against the retracted "entity leak" reading: the smoke plugin's
"saw N entities total" is a cumulative spawn-EVENT counter, not residency.
Investigation must measure actual managed + unmanaged/GPU memory growth over
time, capture-first. May have contributed to tonight's phantom door-regression
(memory pressure -> GC thrash -> dropped inbound motion).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 10:03:08 +02:00
Erik
9a772d2b2a docs: M1.5 "Indoor world feels right" LANDED 2026-07-10 — advance to M2
User-gated the full dungeon round-trip (enter via portal -> navigate rooms ->
exit to the outdoor world), completing the #138 acceptance. Both M1.5 demo
halves are now confirmed: building/cellar (prior sessions) + full dungeon
round-trip (2026-07-10). Milestone-crossing artifacts per the milestones-doc
discipline:

- Pinned M1.5 landing writeup + flipped header to  LANDED; caveats explicit
  (#145-residual far-town teleport-OUT + #116 slide-response carried as
  post-M1.5 follow-ups, NOT blockers).
- Freeze list applied: all M1.5 phases (indoor render Option A, A6/A6.P4
  physics, A7 lighting, full Phase G.3 dungeon support) now frozen per rule 2.
- M2 "Kill a drudge" flipped to ACTIVE; first ports = CombatMath.ComputeDamage
  (F.3) + inventory panel (F.2) + combat anim (L.1c).
- CLAUDE.md "currently working toward" advanced to M2.
- #138 closed (user gate).

No demo video (per the user's standing preference).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 09:58:48 +02:00
Erik
113569b482 docs(#138): record 2026-07-10 partial gate — enter+navigate confirmed, exit gate pending
User re-confirmed the ENTER + NAVIGATE half of the dungeon round-trip works
(retail-UI session). The EXIT half (portal-out to outdoor, esp. far-town where
#145-residual lurks) wasn't exercised, so #138 stays open and M1.5 does not land
until the exit gate passes. Marks exactly where next session resumes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 09:49:19 +02:00
Erik
5e271dd719 docs: reconcile M1.5 tracking with git reality — G.3 dungeons SHIPPED, not "broken"
The milestones doc, roadmap, CLAUDE.md banner, and #138's ISSUES cross-ref had
drifted ~4 weeks behind shipped work — they still claimed "dungeons don't work
AT ALL / terrain-less landblocks unsupported (#133)", which sent this session
chasing a phantom door "regression" for an hour. Git reality (and tonight's live
dungeon session) refute it:

- #133 teleport-into-dungeon DONE (G.3a hold-until-hydrate FSM 7947d7a/2ce5e5c8/47ae237e);
  the terrain-less premise was refuted at design time (90786c19: dungeon LandBlock
  is flat-terrain, streams via the existing pipeline).
- #95 portal-graph visibility blowup RESOLVED (9.1M→~39k instances, a40c38e8).
- #137 dungeon collision CLOSED (0efa7ed2); doors #187/#188; A7 lighting #79/#93/#80/#154 CLOSED.
- #138 teleport-OUT ESSENTIALLY RESOLVED in code — the remaining M1.5 gap is one
  RECORDED end-to-end round-trip user gate, not broken code.

Also fixes a numbering trap: #138's body cited "#146/#147" for its collision
residuals, but those numbers are D.2b inventory-polish issues in this worktree;
the real residuals are #152 (portal-in walls, DONE 49d743f) + #151 (far-town
walls, FIXED 9743537). Sole live residual now surfaced: far-town teleport-OUT
arrival cascade (#145-residual, REOPENED — capture-harness-first).

Historical working-notes annotated [SUPERSEDED] rather than deleted.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 09:45:05 +02:00
Erik
217a4bad69 Merge branch 'main' into claude/peaceful-visvesvaraya-e0a196
# Conflicts:
#	docs/ISSUES.md
#	docs/architecture/retail-divergence-register.md
2026-07-09 23:18:52 +02:00
Erik
0ecb729527 docs: close #192 (login streaming race) — user visual gate passed
"Looks good." Filed directly to Recently closed since the fix already
shipped and gated this session (fa9aedca).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-09 16:12:31 +02:00
Erik
3dcd53cab7 docs: bulk issues triage — close 27, note 10 investigated-open
User-driven triage pass over ~60 open issues: 19 closed from the
user's own recollection, 8 more closed after this session's parallel
investigation confirmed the underlying bug/task no longer applies
(#96 accepted-divergence reclassification, #60/#68/#126/#4/#81/#33
fixed by commits that never cross-referenced their issue number, #87
superseded by Phase O + Phase A8). 9 issues investigated and confirmed
still genuinely open got a dated triage note appended in place
(#116/#104/#178/#29/#146/#147/#148/#156/#72); #41 got a user-note only.

Two investigated issues (#148, #156) turned up real completed fixes
sitting on an unmerged branch (claude/peaceful-visvesvaraya-e0a196,
11 commits, diverged from main 168 commits ago) — flagged in their
triage notes and separately to the user, not acted on here.

Verified before committing: header count unchanged (200 before/after,
no blocks lost or duplicated), spot-checked 6+ closures across every
category (user-closed, investigation-closed, stayed-open-with-note,
the #87 duplicate-heading edge case) for accuracy against the
underlying investigation evidence.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-09 13:52:41 +02:00
Erik
44cced715c docs: close #93 and #80 (indoor lighting) — user re-verified 2nd-floor fix
"Number 80 is closed, I verified again." Moved #93 (the lighting
umbrella) and #80 (2nd-floor darkness) to Recently closed. #94
(held-item spotlight) is NOT folded into this closure and stays open —
user confirmed acdream doesn't support equipping hand-held items yet,
so it's currently untestable; marked BLOCKED rather than an active A7
target so it doesn't keep resurfacing as unfinished lighting work.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-09 13:17:25 +02:00
Erik
754b299f7a docs: close #189 (fountain water spray) — user visual gate passed
"Fountain is back! We can close it." Root cause was #190 (entity-id
overflow), not the light-carrier hydration fix directly. Moved to
Recently closed with the mechanism summary; the candle-flame
identification sub-thread is noted as an unraised residual rather than
a new open issue, since the user didn't re-flag it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-09 12:44:13 +02:00
Erik
6e034ac610 docs: A7.L1 session bookkeeping — close #190, update #93/#189, file #191
- #190 (interior entity id overflow) moved to Recently closed with full
  evidence trail — found + fixed same session as #189's investigation.
- #189 (missing particles) updated: root cause was #190's id aliasing,
  not the light-carrier hydration fix itself; fix shipped but the
  fountain's water spray hasn't been re-confirmed visually yet (session
  moved to an FPS question, then a movement bug, before circling back).
  The "candle" identification sub-thread stays open regardless.
- #93 (indoor lighting umbrella) updated earlier this session with the
  two A7.L1 root causes + fixes; #80/#94 still need re-verification
  before it can close.
- #191 filed: tapping W briefly glides forward without playing the step
  animation (retail: single visible step). Different subsystem
  (movement/animation, not rendering) — not investigated this session,
  filed to keep it from interrupting A7 lighting/particle work.
- Roadmap Phase A7 progress note added earlier this session.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-09 12:40:42 +02:00
Erik
5d013dcb10 docs: close #188 (fading-wall doors fade + hold; door flip-back fix, 3284dd0a)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 09:20:51 +02:00
Erik
e2e285b855 fix(#187): drop the "Name == Door" special-case — register any entity with a resolvable MotionTableId
The door-swing animation rescue (GameWindow.cs:3897, for entities whose rest pose
is a static single frame but which still carry a reactive MotionTable) was gated on
an exact display-name string match. Sliding doors, gates, portcullises, and disguised
secret-passage props ("Magic Wall") all fail that check because their in-game Name
isn't literally "Door" -- so ACE's UpdateMotion for them was silently dropped forever
by the _animatedEntities.TryGetValue bail-out in OnLiveUpdateMotion.

Retail's own dispatch chain (ACCObjectMaint::CreateObject -> CPhysicsObj::
set_description -> SetMotionTableID -> CPartArray::SetMotionTableID 0x005186e0 ->
MotionTableManager::PerformMovement) is unconditionally data-driven: the only gate
for creating a motion dispatcher anywhere in that chain is "motion table id != 0" --
no CDoor class, no WeenieType switch, no name check. Production weenie data confirms
Sliding Door / Portcullis / Gate / Magic Wall all carry the identical WeenieType=Door
+ non-zero-MotionTableId shape as a plain "Door", differing only in display name.

Fix: the branch's existing `mtableId != 0` check (already computed one line later)
is now the entire gate, matching retail exactly. IsDoorSpawn deleted (dead code);
IsDoorName kept only for an unrelated diagnostic log-label filter.

Live-verified: sliding doors now animate open/closed correctly. Full regression
green (App 741 / Core 2631).

docs(#188): file the fading-wall render gap surfaced during #187's live gate

A "Pedestal Weak Spot" secret-passage door dispatches correctly (proving #187's fix
reaches it) but never visibly changes. Decoded its actual dat MotionTable directly
(0x090000F9): its open cycle carries EtherealHook + TransparentPartHook +
SoundTableHook -- a translucency-fade effect, not part-transform motion. acdream's
IAnimationHookSink documents these hook types as intended for "GfxObjMesh / renderer
state mutations" but no sink anywhere consumes them (only Particle/Lighting/Audio are
wired) -- confirmed via full-repo grep. Collision already works correctly via a
separate server-authoritative SetState wire message, independent of the animation
hook. This is feature-shaped rendering work (a per-part runtime alpha under the
mandatory N.5 bindless pipeline), not a quick fix -- filed for its own design pass.

Kept Issue188FadingDoorMotionTableInspectionTests.cs as a reusable MotionTable/hook
decoder for future "why doesn't this animate" questions.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-08 20:10:45 +02:00