Commit graph

591 commits

Author SHA1 Message Date
Erik
8cbe45f0b2 docs(research): Campaign P P3/P4 decomp anchors - remote residuals + world specials
TS-46: init_sphere 0x0050c670 seeds the Setup's own sphere list; step
heights come from setup step_up/step_down x scale (0x005180d0/f0) and the
local player already ports this (PlayerModeController.ApplyStepHeights) -
remote/ordinary 0.4f pins are a plumbing gap. AD-25: handle_all_collisions
0x00514780 is one uniform CPhysicsObj function; the remote reflect block
should swap to the existing PhysicsObjUpdate.HandleAllCollisions port.
TS-23: parse/storage/exemption machinery exists; only moverFlags call
sites read a GUID heuristic. AP-71: check_entry_restrictions 0x0052b6d0
transcribed; restriction_obj write-site field collision flagged OPEN
(Ghidra MCP unreachable). AP-10: ValidateWalkable verbatim-correct; only
the dry-corner constant collapsed, plus WATER_CONTACT_TS declared but
never written.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-29 23:58:40 +02:00
Erik
6077ce4d23 docs: VTank requirements research - the plugin-automation milestone model
User-requested (2026-07-29): the plugin API must eventually support
VTank-class automation state machines written as acdream plugins. The
research decodes the full Virindi Tank surface from wiki archives and
primary source (the meta FSM''s complete condition/action vocabulary and
.met encodings, the expression language''s 67-function catalog, all ten
nav-point types with .nav wire payloads, VTClassic''s loot-rule type ids
and .utl format), derives the implied host API surface, and grounds it
against acdream: the K2 headless-bot triad is already the right
substrate, the VTank-like engine itself belongs in plugin-land, and the
milestone is a 5-step bridge/query/enchantment/transaction/nav sequence
where steps 2-4 ride on landed M3/M4 work. Filed in the post-Vulkan
intake as a C-bucket milestone candidate.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-29 16:29:49 +02:00
Erik
39c1737bda feat(core): adopt retail's SoundType catalog; retire AC2D
SoundId was not a subset of retail's table, the way its comment claimed.
It was an invention: 23 acdream-local names on acdream-local values, and
the values were wrong in the way that matters. FootstepDefault = 0x02 is
retail's Random. SwingSword = 0x10 is retail's Death2. Death = 0x60 is
retail's Explode. Anyone who reached for one of those names to compare
against a wire or dat value would have got a different sound.

Nothing referenced any of them by name -- grep for `SoundId.` across src
and tests returns nothing -- so this was a trap rather than a live defect,
the same shape the enum campaign found in DamageType. All 22 invented names
are deleted and retail's 205 replace them.

Three oracles agree exactly, on every name and every value: retail
acclient.h:4569 enum SoundType, ACE's Sound, and DatReaderWriter's Sound.
The third matters most. AudioHookSink already resolves SoundTable lookups
through DatReaderWriter.Enums.Sound, so that is the enum acdream actually
reads at runtime; our catalog now agrees with the values already flowing
through the dat path, and a conformance test pins the two so they cannot
drift apart.

On the "206 sounds" figure: retail's block holds 207 entries, being 205
sounds followed by NUM_SOUND_TYPES = 0xCD and FORCE_SoundType_32_BIT. The
first is a count and the second a width pin. Counting the former is where
206 came from. Neither is a member here, matching how the campaign treated
NUM_ATTACK_HEIGHTS and Num_HoldKeys -- a count is not a value the wire can
carry.

Behaviour is unchanged and could not be otherwise: the enum had no
consumers. IAudioEngine's three SoundId overloads are no-op stubs and the
live path takes wave ids and DatReaderWriter values.

The user's separate report that sound is "not working that good" is a
triggering, selection and attenuation question rather than a catalog one,
and is filed as its own Bucket B row in the post-Vulkan intake.

Also in this commit, by user decision: AC2D is retired as a reference. Its
clone and directory are gone and it must not be re-cloned. Everything we
took from it still stands and is written down -- the FSplitNESW terrain
split constants, the 0xF61C movement packet layout, the finding that a
client need not compute terrain Z itself -- so CLAUDE.md's reference list,
its hierarchy table, and the architecture doc's protocol row now point at
docs/research/2026-04-12-movement-deep-dive.md rather than erasing the
history. The reference count drops from six to five.

Core tests 3907 passed / 2 skipped.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-29 07:38:56 +02:00
Erik
f27ad9ee43 feat(core): adopt retail's full WeenieError code table
acdream carried 16 status codes, curated by hand out of the CMotionInterp
and MoveToManager decompilation passes. The other 362 were unnamed, which
made every one of them a cast site waiting to happen. This slice takes the
whole table: 372 values under 378 names.

The oracle set is finally complete. All six vendored reference repos were
empty when the 2026-07-29 enum campaign ran, which is why it deferred this
decision; they are re-cloned now, so ACE's WeenieError could be read
directly instead of leaning on the UtilityBelt catalog alone.

The two agree without a single conflict. ACE has 369 members, no internal
value collisions. The catalog has 372, shares all 369 ACE names, and
disagrees on none of their values. Its three extras -- IsNowOpenFellowship
(0x050B), IsNowClosedFellowship (0x050C), LockedFellowshipCannotRecruit
(0x0518) -- each turn up in ACE's separate WeenieErrorWithString enum with
a `_` marking the interpolated name, so the catalog is just the less-split
view of the same client enum. All three are adopted on agreement between
two oracles, not on one.

Retail cannot arbitrate any of this. acclient.h has no counterpart enum;
its charError (26) is character-creation only. Recorded, not guessed
around.

Six values keep two names. acdream's NotGrounded, CrouchInCombatStance,
SitInCombatStance, SleepInCombatStance, ChatEmoteOutsideNonCombat and
ActionDepthExceeded are each anchored to a retail decompilation site, where
ACE's names for those values are server-side coinages. Rather than pick,
both are declared, acdream's first so ToString() is untouched.

Behaviour is unchanged, and there is no way for it not to be: nothing in
the tree branches on a WeenieError member. MotionInterpreter's switch is on
a motion type and merely returns one of these; WeenieErrorText.For switches
on a raw uint; the chat translation table WeenieErrorMessages is keyed on
uint throughout, so naming a code does not make it render. The one site
that moved is RemoteTeleportHook, where the (WeenieError)0x3Cu cast becomes
the now-named WeenieError.ITeleported at the same value.

Register row AP-15 is narrowed rather than retired. Its code-catalog caveat
is superseded -- an unnamed code is no longer a way for it to bite -- but
the sentences are still ACE's doc comments rather than retail's
string_table.bin, and that part stands.

The enum moved out of MotionInterpreter.cs into its own file at the same
namespace. At 372 members it does not belong inside a physics class file.

Core tests 3903 passed / 2 skipped.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-29 07:33:27 +02:00
Erik
22ae7944b6 merge(net): the wire-stack audit, and one reconciled #255
Brings `github/overnight/wire-audit` (`41f74fcd`) forward onto the V11 tree.
Like the enum branch it was cut at `b70b9832`, and like the enum branch its
subject is disjoint from the deletion: the audit lives in `AcDream.Core.Net`
and its tests, V11 emptied `AcDream.App`. One conflict, in `docs/ISSUES.md`,
resolved below.

What it carries: three real parser fixes — ranged speech was carrying a range
float the parser ate, a chat type that is never sent was silently dropping every
transient string on it, and `xpSpent` is a dword on the wire where we were
writing eight bytes. Plus the transport flag word pinned against ACE across all
twenty-three bits, golden fixtures generated from ACE's own writer instead of
hand-typed hex, and the audit document covering all three hundred forty-nine
opcodes.

**The conflict, and how it was resolved.** Both this branch and V11's closeout
reopened #255 — the RetailDatLoader concurrency tests that measure the thread
pool rather than the loader — on the same day, from different trees, without
knowing about each other. Neither reopening is a duplicate of the other: the
V11 gate saw 2 failures in 5 complete-solution Release runs on the
post-deletion tree, the audit session saw 2 in 4 on the pre-deletion tree, and
both saw 124/124 in isolation every time. They independently reached the same
conclusion, that `TaskCreationOptions.LongRunning` is a hint rather than a
guarantee, and independently proposed the same fix, a rendezvous inside the read
stub.

So the two notes are merged into one issue with both evidence sets kept as
labelled subsections rather than one overwriting the other. Four failures across
nine runs on two trees is a materially stronger case than either half, and the
agreement between two blind observations is the part worth preserving. No
assertion was weakened and no retry was added; the fix itself remains open.

Verified on the merge result: Release build 0 errors, and
`AcDream.Core.Net.Tests` at 659 passed / 0 skipped, up exactly the 59 the branch
claimed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-29 03:31:25 +02:00
Erik
081c2009d1 docs(net): the wire-stack audit, all three hundred forty-nine opcodes
Bucket B item 2 of the post-Campaign-V intake, delivered as a ledger. Every
entry in ACE's three opcode enums gets a row grounded in acdream source read
during the audit, with a file:line citation, compared field by field against
ACE's serializer or handler. The prior status columns were deliberately not
used as input; they are compared against the result instead.

Two blockers lead the document because they outlast it. The vendored reference
repos are empty directories in the main checkout, not just in worktrees, so
CLAUDE.md's instruction to cross-reference at least two of them is currently
unexecutable as written; working copies were recovered elsewhere on disk and
Chorizite.ACProtocol was not found anywhere. And the 2026-06-04 wire catalog
this audit was meant to diff against was never committed and does not exist on
disk, though MEMORY.md still links to it. The row universe therefore comes from
ACE's enums, which is more complete than the missing catalog's 256, and drift
is measured against the in-repo Phase-M matrix instead.

The corpus could not support the frequency ranking the mission asked for.
ACDREAM_DUMP_OPCODES was not set for any recorded session, so there are zero
unhandled-opcode lines across every log. That is reported rather than papered
over, and it is why no new parsers were written for unobserved gaps: the bar
was observed plus two oracles, and the first half was unsatisfiable. One
instrumented re-run would fix this, and it leads the open questions.

The most useful thing the audit found is a pattern rather than a single bug.
Three confirmed wire divergences each had a passing test built on the same
wrong assumption as the parser it was defending. The Phase-M matrix had marked
all three rows complete, and for ranged speech it even recorded the mistake as
a design note, "same parser as 0x02BB". A status column can be wrong on the day
it is written.

Counts: 130 parsed or built-and-wired, 11 partial, 75 stub or dead-builder, 128
missing, 5 server-side, across 349 rows. The stub block is concentrated in
fellowship, housing, trade, allegiance, and vendor, which is exactly the surface
the intake's bucket-C items will need.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-29 02:05:12 +02:00
Erik
c19680fd69 docs(enums): the 2026-07-29 verification campaign, end to end
The ledger the campaign owed: which oracles were actually available, what each
family's end state is, what got fixed and why, and - the part that matters most
for whoever picks this up - the twelve things that could not be settled from an
oracle and are therefore recorded as open questions rather than guessed.

Two findings deserve to survive past the morning report.

The first is that five of the six vendored reference repos named in CLAUDE.md are
empty directories in this environment. ACE, Chorizite, holtburger, ACViewer, AC2D
and DatReaderWriter contain nothing, so the campaign re-anchored on the retail
header itself - which CLAUDE.md ranks above ACE anyway - with the UtilityBelt
enum catalog and the 38,985-file ACE weenie corpus as cross-checks. That turned
out to be the more rigorous arrangement rather than a compromise, because of the
second finding: the catalog is wrong about CraftFletchingBase, where retail and
acdream agree. Trusting any single source, including the one the brief nominated,
would have introduced a bug. Retail's header decided every disagreement and the
weenie corpus broke ties.

Also recorded: the 2026-06-04 property-enum divergence note that this work was
supposed to build on does not exist - not in the tree, not under any ref, not in
the memory directory, which has no research/ subfolder at all. The MEMORY.md index
points at both it and a magic-number audit that is equally absent. The sweep was
regenerated from scratch instead, and landed on 864 property members against the
missing note's remembered 929. Someone should repoint those index entries.

The Bucket B intake row is marked done and points here.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-29 01:33:50 +02:00
Erik
97a095d628 docs(linux): park Slice L at L1 checkpoint 2026-07-27 12:35:47 +02:00
Erik
07bb1c5a74 docs(linux): close Slice L0 2026-07-27 12:00:10 +02:00
Erik
1628d9f587 docs(headless): close modern runtime slice K 2026-07-27 11:31:19 +02:00
Erik
b2ab0956f2 docs(headless): record K4 resource envelope 2026-07-27 11:21:44 +02:00
Erik
93c6c54220 docs(headless): record K4 telemetry checkpoint 2026-07-27 10:50:32 +02:00
Erik
827a039760 docs(headless): close K3 connected gates 2026-07-27 10:28:53 +02:00
Erik
fd9559a063 docs(headless): record K3 isolation checkpoint 2026-07-27 09:28:47 +02:00
Erik
fbdb58a962 docs(headless): close modern runtime slice K2 2026-07-27 08:26:23 +02:00
Erik
b299e3738e docs: close modern runtime slice K1 2026-07-27 07:39:56 +02:00
Erik
fbebb91848 docs(headless): close K0 and activate K1
Pin the tested Windows/Linux portability boundary, exact rollback, dependency audit, and synchronized architecture and roadmap state before starting the production single-session host.

Co-authored-by: Codex <noreply@openai.com>
2026-07-27 07:05:45 +02:00
Erik
953c469cac docs(runtime): close Slice J and activate Slice K
Record the shared graphical/no-window reset architecture, deterministic lifecycle evidence, exact rollback point, and synchronized project guidance before beginning the Linux headless host.

Co-authored-by: Codex <noreply@openai.com>
2026-07-27 01:01:41 +02:00
Erik
7818494116 docs(runtime): close the accepted J7 visual gate 2026-07-27 00:12:26 +02:00
Erik
5b3fb17775 fix(vfx): classify hardwareless particle emitters once 2026-07-27 00:03:44 +02:00
Erik
921712f412 fix(interaction): restore retail loot placement and world-drop projection 2026-07-27 00:03:15 +02:00
Erik
4d095be286 fix(physics): traverse prepared indoor portal topology 2026-07-27 00:02:44 +02:00
Erik
b8c90c1959 docs(runtime): record J7 root cutover gates
Capture the exact production rollback, complete automated evidence, connected route results, and the still-active physical-display acceptance without declaring J7 closed early.

Co-authored-by: OpenAI Codex <codex@openai.com>
2026-07-26 19:29:18 +02:00
Erik
75f9510e10 docs(runtime): close exact world host ownership 2026-07-26 18:41:24 +02:00
Erik
73d0b54e38 docs(runtime): record teleport correlation gate 2026-07-26 18:04:50 +02:00
Erik
6a063a27d4 refactor(runtime): own teleport destination correlation 2026-07-26 17:52:34 +02:00
Erik
38b3773cb9 docs(runtime): record reveal ownership gate 2026-07-26 17:27:15 +02:00
Erik
4ab98b080e docs(runtime): record world environment ownership 2026-07-26 16:52:54 +02:00
Erik
902076c0a4 refactor(runtime): own world environment state 2026-07-26 16:45:04 +02:00
Erik
4743f7c409 docs(runtime): close simulation ownership 2026-07-26 16:29:28 +02:00
Erik
c30a3efeb0 docs(runtime): close projectile ownership 2026-07-26 15:27:50 +02:00
Erik
fce8e7b18e docs(runtime): close per-session physics ownership
Record J5.5 production SHA, complete Release baseline, exact-binary lifecycle/reconnect and nine-stop collision/movement evidence, and rollback. Synchronize architecture, roadmap, milestones, AGENTS/CLAUDE, and advance the active program to J5.6 projectile runtime.

Co-authored-by: Codex <noreply@openai.com>
2026-07-26 13:59:06 +02:00
Erik
7e6033d0ad refactor(runtime): own per-session physics simulation
Move the sole PhysicsEngine, production cache, collision admissions, canonical bodies and hosts, remote components, ordinary/remote worksets, simulation, cell commits, and shadow synchronization under RuntimeEntityObjectLifetime. Keep App as the prepared-asset, animation-input, and render-projection adapter while preserving the named-retail update and collision order.

Add exact-incarnation, object-clock, callback-reentrancy, GUID-reuse, two-runtime isolation, source ownership, collision publication, and graphical projection coverage. Release build and the complete 8,588-test solution pass.

Co-authored-by: Codex <noreply@openai.com>
2026-07-26 13:39:57 +02:00
Erik
0dc3bfdeff docs(runtime): close local movement ownership
Record the exact J5.4 automated, lifecycle/reconnect, and nine-stop movement evidence; advance the Modern Runtime program to J5.5; and synchronize architecture, roadmap, milestones, AGENTS/CLAUDE, rollback, and durable research pointers.

Co-authored-by: Codex <noreply@openai.com>
2026-07-26 12:53:41 +02:00
Erik
aa3f4a60f8 refactor(runtime): own local movement and outbound cadence
Move the canonical local movement controller, body/motion managers, object clock, movement wire data, and MTS/jump/AP sender into AcDream.Runtime. Replace process skill defaults with typed Runtime character options, make graphical and direct commands borrow one autorun owner, retain the construction-time PartArray seam, and include movement in terminal ownership convergence.

Preserve the accepted pre-inbound movement/jump and post-inbound autonomous-position order while moving the exact packet/cadence fixtures into Runtime tests. Add graphical/direct parity, two-instance isolation, teardown, allocation, architecture, and divergence-path coverage.

Co-authored-by: Codex <noreply@openai.com>
2026-07-26 12:33:53 +02:00
Erik
75b761e658 docs(runtime): close combat and magic intent
Record the exact J5.3 owner boundary, retail ordering, Release and connected evidence, rollback, and J5.4 handoff across architecture, roadmap, milestones, agent instructions, and durable memory.

Co-authored-by: Codex <noreply@openai.com>
2026-07-26 12:09:19 +02:00
Erik
20df9d155d refactor(runtime): own combat and magic intent
Move attack build/repeat state, combat-mode policy, authoritative auto-target transitions, and spell-cast intent beneath RuntimeActionState. Keep App as the input, world-query, DAT-policy, transport, and presentation adapter while preserving retail request and busy ordering. Add direct/graphical parity, reset, failure, and instance-isolation coverage.

Co-authored-by: Codex <noreply@openai.com>
2026-07-26 11:56:40 +02:00
Erik
81b31857c6 docs(runtime): close interaction transaction ownership
Record the exact J5.2 owner boundary, retail ordering, Release and connected evidence, rollback, and J5.3 handoff across architecture, roadmap, milestones, agent instructions, and durable memory.

Co-authored-by: Codex <noreply@openai.com>
2026-07-26 11:22:07 +02:00
Erik
be73bccf5a docs(runtime): close canonical action ownership
Record J5.1's exact Runtime selection, combat, and target-mode owner, its automated and connected acceptance evidence, rollback, and the J5.2 interaction-transaction boundary. Synchronize architecture, roadmap, milestones, issues, and agent handoff state.

Co-authored-by: Codex <codex@openai.com>
2026-07-26 10:54:12 +02:00
Erik
bb45afef33 docs(runtime): plan simulation ownership
Inventory the present selection, interaction, combat, movement, physics, and projectile owners; pin named-retail ordering; and define independently reversible J5.1-J5.7 gates without moving presentation into Runtime.

Co-authored-by: Codex <noreply@openai.com>
2026-07-26 10:25:46 +02:00
Erik
2c67a2c3ba docs(runtime): close gameplay-state ownership
Record J4.5 canonical shortcut and spellbook command ownership, combined failure and graphical/headless parity evidence, the 8,544-test Release gate, exact-binary lifecycle and nine-stop acceptance, rollback instructions, and the J5 boundary.

Co-authored-by: Codex <noreply@openai.com>
2026-07-26 10:17:39 +02:00
Erik
89e6b207f8 refactor(runtime): close canonical gameplay ownership
Unify the toolbar shortcut manager with Runtime inventory state, route retail-ordered shortcut and spellbook command effects through the canonical owners, and make retained controllers borrow those exact instances. Remove the item-interaction transaction fallback and add graphical/no-window parity plus failure-safe terminal ownership-ledger coverage.

Co-authored-by: Codex <codex@openai.com>
2026-07-26 09:48:51 +02:00
Erik
ce6fae7b38 docs(runtime): close character projections
Record J4.4's canonical character settings, borrowed gameplay views, typed state-command seam, complete Release evidence, exact-binary lifecycle/reconnect acceptance, rollback, and the J4.5 combined closeout boundary. Synchronize architecture, roadmap, milestones, agent guidance, and durable memory.

Co-authored-by: Codex <codex@openai.com>
2026-07-26 09:21:26 +02:00
Erik
9d0d9b07e0 docs(runtime): close magic and player ownership
Record J4.3's coupled Runtime character graph, desired-component single ownership, complete Release evidence, exact-binary lifecycle/reconnect acceptance, rollback, and the J4.4 projection boundary. Synchronize architecture, roadmap, milestones, agent guidance, and durable memory.

Co-authored-by: Codex <codex@openai.com>
2026-07-26 08:46:12 +02:00
Erik
d362172620 docs(runtime): close inventory state ownership
Record J4.2's single Runtime inventory transaction graph, complete Release evidence, exact-binary lifecycle/reconnect acceptance, rollback, and the J4.3 magic/player-sheet boundary. Synchronize architecture, roadmap, milestones, agent guidance, and durable memory.

Co-authored-by: Codex <codex@openai.com>
2026-07-26 08:29:06 +02:00
Erik
595d5e6b01 docs(runtime): close communication ownership
Record J4.1's single Runtime communication/social graph, failure-safe ordered chat stream, complete Release evidence, exact-binary lifecycle/reconnect acceptance, rollback, and the J4.2 inventory transaction boundary. Synchronize architecture, roadmap, milestones, agent guidance, and durable memory.

Co-authored-by: Codex <codex@openai.com>
2026-07-26 07:59:02 +02:00
Erik
77c013998b docs(runtime): close canonical entity object lifetime 2026-07-26 07:35:42 +02:00
Erik
84954c8b77 docs(runtime): close J3.5 and plan J3.6
Record the canonical entity/object delta cutover, full Release and exact-binary connected evidence, rollback, and the adversarial zero-owner J3.6 execution contract. Synchronize architecture, roadmap, milestones, and agent guidance.

Co-authored-by: Codex <codex@openai.com>
2026-07-26 06:54:47 +02:00
Erik
d3e96ff912 docs(runtime): close J3.4 and plan J3.5 2026-07-26 06:09:28 +02:00
Erik
d9bf4c4960 docs(runtime): close J3.3 and hand off J3.4
Record exact projection-store ownership, automated and connected evidence, rollback chain, and the executor-ready canonical object-table plan. Reconcile milestones, roadmap, architecture, divergence pointers, AGENTS/CLAUDE, and durable handoff state.

Co-authored-by: Codex <codex@openai.com>
2026-07-25 22:29:34 +02:00