docs: reconcile project status and navigation
Add a canonical documentation map, modernize the public README, and align milestone, roadmap, architecture, issue, divergence, and session guidance with the July 20 baseline. Correct the far-teleport residual to issue #153, close visually accepted indicator and terrain-tiling work, record the remaining detail-overlay and build-warning debt, and deprecate the duplicate legacy bug ledger. Co-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
parent
a755b764bf
commit
6c3bd4ce4b
11 changed files with 429 additions and 155 deletions
16
AGENTS.md
16
AGENTS.md
|
|
@ -90,8 +90,8 @@ where ImGui cannot reach the 3D scene. Plugin gameplay UI uses the BCL-only
|
||||||
`AcDream.Plugin.Abstractions.IUiRegistry.AddMarkupPanel` contract; plugins
|
`AcDream.Plugin.Abstractions.IUiRegistry.AddMarkupPanel` contract; plugins
|
||||||
never import App or ImGui namespaces. Full design:
|
never import App or ImGui namespaces. Full design:
|
||||||
[`docs/plans/2026-04-24-ui-framework.md`](docs/plans/2026-04-24-ui-framework.md).
|
[`docs/plans/2026-04-24-ui-framework.md`](docs/plans/2026-04-24-ui-framework.md).
|
||||||
Memory cribs: `memory/project_chat_pipeline.md` (chat pipeline as of
|
Memory cribs: `claude-memory/project_chat_pipeline.md` (chat pipeline as of
|
||||||
Phase I), `memory/project_input_pipeline.md` (input pipeline as of
|
Phase I), `claude-memory/project_input_pipeline.md` (input pipeline as of
|
||||||
Phase K).
|
Phase K).
|
||||||
|
|
||||||
**Input pipeline:** `src/AcDream.UI.Abstractions/Input/` (action enum,
|
**Input pipeline:** `src/AcDream.UI.Abstractions/Input/` (action enum,
|
||||||
|
|
@ -112,14 +112,18 @@ movement queries.
|
||||||
component/target gates, live enchantment wire, Magic-scoped input, spell bar, spellbook, component
|
component/target gates, live enchantment wire, Magic-scoped input, spell bar, spellbook, component
|
||||||
book, effect indicators, shared main-panel switching, and positive/negative effects UI are implemented over the Step-9 projectile/DAT-effect
|
book, effect indicators, shared main-panel switching, and positive/negative effects UI are implemented over the Step-9 projectile/DAT-effect
|
||||||
foundation. The 2026-07-20 R6 complete-root-Frame/object-workset cutover is automated-test complete;
|
foundation. The 2026-07-20 R6 complete-root-Frame/object-workset cutover is automated-test complete;
|
||||||
three independent conformance/architecture/adversarial re-reviews are clean, the Release build has
|
three independent conformance/architecture/adversarial re-reviews are clean, the Release build succeeds
|
||||||
zero warnings, and the full suite is 6,452 passed / 5 skipped. Its unattended seven-destination
|
(the clean documentation audit exposes 17 pre-existing test-project warnings, #228), and the full suite
|
||||||
|
is 6,452 passed / 5 skipped. Its unattended seven-destination
|
||||||
connected input/portal/performance rebaseline also passes without an interactive desktop. Remaining
|
connected input/portal/performance rebaseline also passes without an interactive desktop. Remaining
|
||||||
ownership cleanup and registered TS-50/TS-51 timing residuals stay carried. **Next:** connected R6
|
ownership cleanup and registered TS-50/TS-51 timing residuals stay carried. **Next:** connected R6
|
||||||
locomotion/collision/projectile/teleport visual gate, then the final two-client
|
locomotion/collision/projectile/teleport visual gate, then the final two-client
|
||||||
portal-out/materialization observer gate. **Carried:** #145-residual, #116, R6 residuals, Track MP0.
|
portal-out/materialization observer gate. **Carried:** #153, #116, R6 residuals, and the deferred
|
||||||
|
Modern Pipeline track (MP1b+).
|
||||||
Start magic work at `claude-memory/project_magic_ui_and_casting.md`; detailed state is below.
|
Start magic work at `claude-memory/project_magic_ui_and_casting.md`; detailed state is below.
|
||||||
|
|
||||||
|
Documentation entry point: [`docs/README.md`](docs/README.md).
|
||||||
|
|
||||||
For canonical state, read in this order:
|
For canonical state, read in this order:
|
||||||
- [`docs/plans/2026-05-12-milestones.md`](docs/plans/2026-05-12-milestones.md) — milestone targets + freeze list per milestone
|
- [`docs/plans/2026-05-12-milestones.md`](docs/plans/2026-05-12-milestones.md) — milestone targets + freeze list per milestone
|
||||||
- [`docs/plans/2026-04-11-roadmap.md`](docs/plans/2026-04-11-roadmap.md) — what's shipped, what's in flight, what's next
|
- [`docs/plans/2026-04-11-roadmap.md`](docs/plans/2026-04-11-roadmap.md) — what's shipped, what's in flight, what's next
|
||||||
|
|
@ -141,7 +145,7 @@ For engineering reference (read on demand, not at session start):
|
||||||
The memory dir also holds `feedback_*.md` lessons-learned (cross-cutting
|
The memory dir also holds `feedback_*.md` lessons-learned (cross-cutting
|
||||||
patterns the project has agreed on) and `project_*.md` per-subsystem
|
patterns the project has agreed on) and `project_*.md` per-subsystem
|
||||||
cribs (chat pipeline, input pipeline, interaction pipeline, etc.).
|
cribs (chat pipeline, input pipeline, interaction pipeline, etc.).
|
||||||
See `memory/MEMORY.md` for the index.
|
See `claude-memory/MEMORY.md` for the index.
|
||||||
|
|
||||||
## Code Structure Rules
|
## Code Structure Rules
|
||||||
|
|
||||||
|
|
|
||||||
16
CLAUDE.md
16
CLAUDE.md
|
|
@ -88,8 +88,8 @@ where ImGui cannot reach the 3D scene. Plugin gameplay UI uses the BCL-only
|
||||||
`AcDream.Plugin.Abstractions.IUiRegistry.AddMarkupPanel` contract; plugins
|
`AcDream.Plugin.Abstractions.IUiRegistry.AddMarkupPanel` contract; plugins
|
||||||
never import App or ImGui namespaces. Full design:
|
never import App or ImGui namespaces. Full design:
|
||||||
[`docs/plans/2026-04-24-ui-framework.md`](docs/plans/2026-04-24-ui-framework.md).
|
[`docs/plans/2026-04-24-ui-framework.md`](docs/plans/2026-04-24-ui-framework.md).
|
||||||
Memory cribs: `memory/project_chat_pipeline.md` (chat pipeline as of
|
Memory cribs: `claude-memory/project_chat_pipeline.md` (chat pipeline as of
|
||||||
Phase I), `memory/project_input_pipeline.md` (input pipeline as of
|
Phase I), `claude-memory/project_input_pipeline.md` (input pipeline as of
|
||||||
Phase K).
|
Phase K).
|
||||||
|
|
||||||
**Input pipeline:** `src/AcDream.UI.Abstractions/Input/` (action enum,
|
**Input pipeline:** `src/AcDream.UI.Abstractions/Input/` (action enum,
|
||||||
|
|
@ -110,14 +110,18 @@ movement queries.
|
||||||
component/target gates, live enchantment wire, Magic-scoped input, spell bar, spellbook, component
|
component/target gates, live enchantment wire, Magic-scoped input, spell bar, spellbook, component
|
||||||
book, effect indicators, shared main-panel switching, and positive/negative effects UI are implemented over the Step-9 projectile/DAT-effect
|
book, effect indicators, shared main-panel switching, and positive/negative effects UI are implemented over the Step-9 projectile/DAT-effect
|
||||||
foundation. The 2026-07-20 R6 complete-root-Frame/object-workset cutover is automated-test complete;
|
foundation. The 2026-07-20 R6 complete-root-Frame/object-workset cutover is automated-test complete;
|
||||||
three independent conformance/architecture/adversarial re-reviews are clean, the Release build has
|
three independent conformance/architecture/adversarial re-reviews are clean, the Release build succeeds
|
||||||
zero warnings, and the full suite is 6,452 passed / 5 skipped. Its unattended seven-destination
|
(the clean documentation audit exposes 17 pre-existing test-project warnings, #228), and the full suite
|
||||||
|
is 6,452 passed / 5 skipped. Its unattended seven-destination
|
||||||
connected input/portal/performance rebaseline also passes without an interactive desktop. Remaining
|
connected input/portal/performance rebaseline also passes without an interactive desktop. Remaining
|
||||||
ownership cleanup and registered TS-50/TS-51 timing residuals stay carried. **Next:** connected R6
|
ownership cleanup and registered TS-50/TS-51 timing residuals stay carried. **Next:** connected R6
|
||||||
locomotion/collision/projectile/teleport visual gate, then the final two-client
|
locomotion/collision/projectile/teleport visual gate, then the final two-client
|
||||||
portal-out/materialization observer gate. **Carried:** #145-residual, #116, R6 residuals, Track MP0.
|
portal-out/materialization observer gate. **Carried:** #153, #116, R6 residuals, and the deferred
|
||||||
|
Modern Pipeline track (MP1b+).
|
||||||
Start magic work at `claude-memory/project_magic_ui_and_casting.md`; detailed state is below.
|
Start magic work at `claude-memory/project_magic_ui_and_casting.md`; detailed state is below.
|
||||||
|
|
||||||
|
Documentation entry point: [`docs/README.md`](docs/README.md).
|
||||||
|
|
||||||
For canonical state, read in this order:
|
For canonical state, read in this order:
|
||||||
- [`docs/plans/2026-05-12-milestones.md`](docs/plans/2026-05-12-milestones.md) — milestone targets + freeze list per milestone
|
- [`docs/plans/2026-05-12-milestones.md`](docs/plans/2026-05-12-milestones.md) — milestone targets + freeze list per milestone
|
||||||
- [`docs/plans/2026-04-11-roadmap.md`](docs/plans/2026-04-11-roadmap.md) — what's shipped, what's in flight, what's next
|
- [`docs/plans/2026-04-11-roadmap.md`](docs/plans/2026-04-11-roadmap.md) — what's shipped, what's in flight, what's next
|
||||||
|
|
@ -139,7 +143,7 @@ For engineering reference (read on demand, not at session start):
|
||||||
The memory dir also holds `feedback_*.md` lessons-learned (cross-cutting
|
The memory dir also holds `feedback_*.md` lessons-learned (cross-cutting
|
||||||
patterns the project has agreed on) and `project_*.md` per-subsystem
|
patterns the project has agreed on) and `project_*.md` per-subsystem
|
||||||
cribs (chat pipeline, input pipeline, interaction pipeline, etc.).
|
cribs (chat pipeline, input pipeline, interaction pipeline, etc.).
|
||||||
See `memory/MEMORY.md` for the index.
|
See `claude-memory/MEMORY.md` for the index.
|
||||||
|
|
||||||
## Code Structure Rules
|
## Code Structure Rules
|
||||||
|
|
||||||
|
|
|
||||||
125
README.md
125
README.md
|
|
@ -5,54 +5,64 @@ A modern open-source C# / .NET 10 Asheron's Call client.
|
||||||
Faithful port of the retail client's behaviour to Silk.NET with a modern,
|
Faithful port of the retail client's behaviour to Silk.NET with a modern,
|
||||||
plugin-friendly architecture. The code is modern; the behaviour is retail.
|
plugin-friendly architecture. The code is modern; the behaviour is retail.
|
||||||
|
|
||||||
**Status:** playable pre-alpha. You can log in to an ACE server, walk and
|
**Status:** playable pre-alpha; M3 ("Cast a spell") is active. The connected
|
||||||
run through Dereth, see other players animate correctly, watch the
|
client supports the complete M2 combat/loot/inventory loop plus retained
|
||||||
day-night cycle, hear ambient audio, and take weapons out. Many systems
|
spellbook, component-book, favorite-spell, enchantment, portal-space, radar,
|
||||||
are still stubbed or in-progress — see roadmap.
|
chat, character, and inventory UI. Current work is verification and retail
|
||||||
|
conformance, not a first-playable bring-up.
|
||||||
|
|
||||||
|
Start at the [documentation map](docs/README.md) for the current milestone,
|
||||||
|
roadmap, tactical issues, architecture, retail-divergence register, research,
|
||||||
|
and durable memory.
|
||||||
|
|
||||||
## Stack
|
## Stack
|
||||||
|
|
||||||
- **Language:** C# .NET 10
|
- **Language:** C# .NET 10
|
||||||
- **Graphics:** [Silk.NET](https://github.com/dotnet/Silk.NET) (OpenGL 4.3)
|
- **Graphics:** [Silk.NET](https://github.com/dotnet/Silk.NET) (OpenGL 4.3
|
||||||
|
context; `GL_ARB_bindless_texture` and `GL_ARB_shader_draw_parameters` are
|
||||||
|
mandatory)
|
||||||
- **Audio:** OpenAL via Silk.NET
|
- **Audio:** OpenAL via Silk.NET
|
||||||
- **Dat parsing:** [Chorizite.DatReaderWriter](https://github.com/Chorizite/DatReaderWriter)
|
- **Dat parsing:** [Chorizite.DatReaderWriter](https://github.com/Chorizite/DatReaderWriter)
|
||||||
- **Networking:** Custom UDP + ISAAC cipher + game-message layer, wire-compatible
|
- **Networking:** Custom UDP + ISAAC cipher + game-message layer, wire-compatible
|
||||||
with ACEmulator server
|
with ACEmulator server
|
||||||
|
|
||||||
## What works
|
## What works today
|
||||||
|
|
||||||
- Connecting to a local ACEmulator (ACE) server on `127.0.0.1:9000`
|
- ACE login, character selection, world entry, chat, client commands, and
|
||||||
- Character selection and login
|
graceful logout.
|
||||||
- Rendering Dereth terrain with retail-correct texture blending,
|
- Outdoor, building, cellar, and dungeon streaming with portal-space travel,
|
||||||
per-vertex lighting, and road overlays
|
terrain/scenery/EnvCell rendering, collision, lighting, sky, fog, audio, and
|
||||||
- Static scenery (buildings, trees, scenery objects) via EnvCell walker
|
day/night presentation.
|
||||||
- Animated characters (own + remote) with walk / run / strafe / jump /
|
- Local and observed player/NPC/monster movement, animation, selection, radar,
|
||||||
turn / attack motions sourced from the retail motion tables
|
combat stances, melee and missile presentation, death, corpses, chests, and
|
||||||
- Network sync with remote players — you can watch other characters
|
looting.
|
||||||
animate correctly, including speeds and directional motion
|
- Inventory bags, stack splitting, paperdoll/equipment, weapon switching,
|
||||||
- Day-night cycle driven from the retail Region dat (0x13000000) —
|
quick bars, item use, giving items to NPCs, and server-authoritative item
|
||||||
correct DayGroup picking via the retail LCG, correct keyframe
|
movement.
|
||||||
interpolation, correct per-keyframe sky-object replace
|
- Retained retail-style gameplay UI for vitals, chat, toolbar, inventory,
|
||||||
- Weather (rain/snow particles synced from the server via the retail
|
character/skills, spellbook/components, helpful/harmful effects, combat and
|
||||||
DayGroup name)
|
spell bars, radar/compass, indicator pages, and confirmation dialogs.
|
||||||
- Sky dome, stars, moon, clouds, sun — each rendered from the retail
|
- Spell catalog, learned/favorite spells, component preflight, connected casts,
|
||||||
Region's SkyObjects with texture scrolling and alpha fade
|
enchantments, DAT-driven missiles/effects, recall, Hidden/UnHide, and portal
|
||||||
- Plugin host with live event replay-on-subscribe
|
materialization presentation.
|
||||||
|
- Plugin host, shared input/command abstractions, and permanent ImGui developer
|
||||||
|
tools behind `ACDREAM_DEVTOOLS=1`.
|
||||||
|
|
||||||
## What's stubbed or in-progress
|
## Active gaps
|
||||||
|
|
||||||
- Indoor transitions (building interiors) — disabled, Phase B.3 pending
|
- R6's complete object-frame update path still needs the next local visual
|
||||||
- Combat — animation works, damage math not wired
|
comparison; the final M3 gate is a two-client portal-out/materialization
|
||||||
- Lightning visual — the retail PhysicsScript-driven flash is researched
|
observer comparison.
|
||||||
but not wired (see `docs/research/2026-04-23-lightning-real.md`)
|
- Issue `#225` still needs the lifestone/particle alpha-order visual check,
|
||||||
- TimeSync drift — we only sync calendar on login, not periodically,
|
although its connected lifetime/performance gates pass.
|
||||||
so acdream's in-game clock gradually drifts from retail's
|
- Narrow behavior debt remains in issue `#153` (an unstreamed far-teleport
|
||||||
- Landscape draw distance — currently `ACDREAM_STREAM_RADIUS=2` (~400m)
|
edge case), issue `#116` (slide feel), and registered TS-50/TS-51 effect
|
||||||
vs retail's several kilometres
|
timing.
|
||||||
|
- Many later retail systems remain roadmap work: advanced social/vendor/trade/
|
||||||
|
crafting UI, full weather/lightning parity, deeper combat/stat systems,
|
||||||
|
graphical Linux, and a true headless multi-session bot host.
|
||||||
|
|
||||||
See `docs/plans/2026-04-11-roadmap.md` for the ordered phase list.
|
See [docs/README.md](docs/README.md) for document authority and current links.
|
||||||
See `docs/ISSUES.md` for the rolling list of known bugs + small deferred
|
|
||||||
features (tactical, bug-level; the roadmap is strategic, phase-level).
|
|
||||||
|
|
||||||
## Building + running
|
## Building + running
|
||||||
|
|
||||||
|
|
@ -74,7 +84,8 @@ $env:ACDREAM_TEST_HOST = "127.0.0.1"
|
||||||
$env:ACDREAM_TEST_PORT = "9000"
|
$env:ACDREAM_TEST_PORT = "9000"
|
||||||
$env:ACDREAM_TEST_USER = "testaccount"
|
$env:ACDREAM_TEST_USER = "testaccount"
|
||||||
$env:ACDREAM_TEST_PASS = "testpassword"
|
$env:ACDREAM_TEST_PASS = "testpassword"
|
||||||
dotnet run --project src\AcDream.App\AcDream.App.csproj -c Debug
|
$env:ACDREAM_RETAIL_UI = "1"
|
||||||
|
dotnet run --project src\AcDream.App\AcDream.App.csproj -c Release
|
||||||
```
|
```
|
||||||
|
|
||||||
Offline CLI dat inspector (no server needed):
|
Offline CLI dat inspector (no server needed):
|
||||||
|
|
@ -89,8 +100,11 @@ dotnet run --project src/AcDream.Cli -- "C:\path\to\Asheron's Call"
|
||||||
|---|---|
|
|---|---|
|
||||||
| `ACDREAM_DUMP_SKY=1` | Per-second dump of the interpolated `SkyKeyframe` values + per-SkyObject draw info + texture alpha histograms |
|
| `ACDREAM_DUMP_SKY=1` | Per-second dump of the interpolated `SkyKeyframe` values + per-SkyObject draw info + texture alpha histograms |
|
||||||
| `ACDREAM_DUMP_MOTION=1` | Dump every inbound `UpdateMotion` + resulting `SetCycle` |
|
| `ACDREAM_DUMP_MOTION=1` | Dump every inbound `UpdateMotion` + resulting `SetCycle` |
|
||||||
| `ACDREAM_STREAM_RADIUS=N` | Tune landblock visible-window radius (default 2 = 5×5) |
|
| `ACDREAM_STREAM_RADIUS=N` | Legacy override for the configured two-tier streaming radii |
|
||||||
| `ACDREAM_NO_AUDIO=1` | Suppress OpenAL init |
|
| `ACDREAM_NO_AUDIO=1` | Suppress OpenAL init |
|
||||||
|
| `ACDREAM_RETAIL_UI=1` | Enable retained retail gameplay UI |
|
||||||
|
| `ACDREAM_DEVTOOLS=1` | Enable ImGui developer tools |
|
||||||
|
| `ACDREAM_UNCAPPED_RENDER=1` | Disable normal presentation pacing for throughput measurement |
|
||||||
| `ACDREAM_DAY_GROUP=N` | Force a specific DayGroup index for A/B-testing weather presets |
|
| `ACDREAM_DAY_GROUP=N` | Force a specific DayGroup index for A/B-testing weather presets |
|
||||||
| `ACDREAM_RUN_SKILL=N` / `ACDREAM_JUMP_SKILL=N` | Client-side run/jump skill (default 200) |
|
| `ACDREAM_RUN_SKILL=N` / `ACDREAM_JUMP_SKILL=N` | Client-side run/jump skill (default 200) |
|
||||||
|
|
||||||
|
|
@ -98,16 +112,20 @@ dotnet run --project src/AcDream.Cli -- "C:\path\to\Asheron's Call"
|
||||||
|
|
||||||
```
|
```
|
||||||
src/
|
src/
|
||||||
AcDream.App/ rendering + audio + main loop (Silk.NET)
|
AcDream.App/ window, retained UI, rendering, audio, runtime wiring
|
||||||
AcDream.Core/ game state, meshing, physics, sky, weather, lighting
|
AcDream.Content/ GL-free DAT mesh/texture extraction
|
||||||
|
AcDream.Core/ game state, physics, movement, world, gameplay logic
|
||||||
AcDream.Core.Net/ UDP + ISAAC + game-message layer
|
AcDream.Core.Net/ UDP + ISAAC + game-message layer
|
||||||
|
AcDream.UI.Abstractions/ shared UI/input ViewModels, commands, contracts
|
||||||
|
AcDream.UI.ImGui/ permanent developer-tool renderer
|
||||||
AcDream.Cli/ offline dat-inspector console app
|
AcDream.Cli/ offline dat-inspector console app
|
||||||
|
AcDream.Bake/ offline content bake tooling
|
||||||
AcDream.Plugin.Abstractions/ plugin host interfaces
|
AcDream.Plugin.Abstractions/ plugin host interfaces
|
||||||
AcDream.Plugins.Smoke/ example plugin
|
AcDream.Plugins.Smoke/ example plugin
|
||||||
|
|
||||||
tests/
|
tests/
|
||||||
AcDream.Core.Tests/ xUnit tests (742 passing)
|
AcDream.*.Tests/ layer-matched xUnit projects (6,452 passing,
|
||||||
AcDream.Core.Net.Tests/ network-layer tests
|
5 intentional skips at the 2026-07-20 baseline)
|
||||||
|
|
||||||
tools/
|
tools/
|
||||||
RetailTimeProbe/ Win32 P/Invoke ReadProcessMemory probe of
|
RetailTimeProbe/ Win32 P/Invoke ReadProcessMemory probe of
|
||||||
|
|
@ -122,7 +140,8 @@ references/ vendored read-only reference code — ACE,
|
||||||
Gitignored.
|
Gitignored.
|
||||||
|
|
||||||
docs/
|
docs/
|
||||||
architecture/ single-source-of-truth architecture doc
|
README.md documentation map + authority order
|
||||||
|
architecture/ architecture, structure, divergence, WB inventory
|
||||||
plans/ phase roadmaps + per-phase specs
|
plans/ phase roadmaps + per-phase specs
|
||||||
research/ decompile-derived research, per-phase
|
research/ decompile-derived research, per-phase
|
||||||
findings, deep-dive agent reports
|
findings, deep-dive agent reports
|
||||||
|
|
@ -131,18 +150,20 @@ docs/
|
||||||
|
|
||||||
## Development workflow
|
## Development workflow
|
||||||
|
|
||||||
All AC-specific behaviour is ported from the decompiled retail client
|
All AC-specific behaviour is ported from the named retail client oracle
|
||||||
(`docs/research/decompiled/`). The workflow is:
|
(`docs/research/named-retail/`). The workflow is:
|
||||||
|
|
||||||
1. **Decompile first.** Find the matching function in the decompiled
|
1. **Grep named retail first.** Find the matching `class::method` in the
|
||||||
client.
|
Sept 2013 named pseudo-C and headers.
|
||||||
2. **Cross-reference.** Check against ACE's C# port and ACViewer /
|
2. **Decompile only as fallback.** Use the older Ghidra chunks when the named
|
||||||
|
oracle lacks the function.
|
||||||
|
3. **Cross-reference.** Check against ACE's C# port and ACViewer /
|
||||||
WorldBuilder.
|
WorldBuilder.
|
||||||
3. **Write pseudocode.** Translate C to readable pseudocode first.
|
4. **Write pseudocode.** Translate C to readable pseudocode first.
|
||||||
4. **Port faithfully.** Translate line-by-line, preserving variable
|
5. **Port faithfully.** Translate line-by-line, preserving variable
|
||||||
names and control flow.
|
names and control flow.
|
||||||
5. **Conformance test.** Add tests using golden values from retail.
|
6. **Conformance test.** Add tests using golden values from retail.
|
||||||
6. **Integrate surgically.** Minimise churn in the surrounding pipeline.
|
7. **Integrate surgically.** Minimise churn in the surrounding pipeline.
|
||||||
|
|
||||||
Guessing at AC-specific algorithms is explicitly forbidden — see
|
Guessing at AC-specific algorithms is explicitly forbidden — see
|
||||||
`CLAUDE.md` for the full workflow rationale and the list of failure
|
`CLAUDE.md` for the full workflow rationale and the list of failure
|
||||||
|
|
@ -150,7 +171,7 @@ modes we've paid for in the past.
|
||||||
|
|
||||||
## Reference repos
|
## Reference repos
|
||||||
|
|
||||||
We cross-reference five external projects for every retail behaviour:
|
We cross-reference six external projects for retail behavior:
|
||||||
|
|
||||||
- **ACE** (ACEmulator) — authoritative server-side protocol
|
- **ACE** (ACEmulator) — authoritative server-side protocol
|
||||||
- **ACViewer** — MonoGame dat viewer; good for character appearance
|
- **ACViewer** — MonoGame dat viewer; good for character appearance
|
||||||
|
|
|
||||||
195
docs/ISSUES.md
195
docs/ISSUES.md
|
|
@ -15,10 +15,33 @@ What does NOT go here:
|
||||||
## Conventions
|
## Conventions
|
||||||
|
|
||||||
- Sequential integer IDs (`#1`, `#2`, …). Commits that close an issue reference the ID in the message (e.g. `fix #3: periodic TimeSync parsing`).
|
- Sequential integer IDs (`#1`, `#2`, …). Commits that close an issue reference the ID in the message (e.g. `fix #3: periodic TimeSync parsing`).
|
||||||
- `Status` is `OPEN`, `IN-PROGRESS`, or `DONE`. DONE items move to the **Recently closed** section at the bottom with closed-date + commit SHA.
|
- `Status` is `OPEN`, `IN-PROGRESS`, or `DONE`. The status inside each issue is
|
||||||
|
authoritative. This long-lived file still has completed items interleaved
|
||||||
|
with open history; physical placement under an older heading is not status.
|
||||||
|
- New DONE items should move to **Recently closed** when practical. Do not do a
|
||||||
|
mechanical move of old blocks merely to tidy the file; preserve their
|
||||||
|
research context until a deliberate archive split.
|
||||||
- Every session: scan OPEN issues at start; promote/close anything we touched during the session before ending.
|
- Every session: scan OPEN issues at start; promote/close anything we touched during the session before ending.
|
||||||
- Promoting to a Phase: mark as `DONE (promoted to Phase X)` + commit SHA where the Phase entry landed.
|
- Promoting to a Phase: mark as `DONE (promoted to Phase X)` + commit SHA where the Phase entry landed.
|
||||||
|
|
||||||
|
## Current queue — 2026-07-20
|
||||||
|
|
||||||
|
- **Next visual gate:** R6 locomotion/collision/projectile/teleport comparison
|
||||||
|
after the complete-root-Frame/object-workset cutover.
|
||||||
|
- **M3 closing gate:** `#218`, final two-client portal-out/materialization and
|
||||||
|
indoor observer comparison.
|
||||||
|
- **Separate rendering gate:** `#225`, lifestone/particle alpha ordering. Its
|
||||||
|
connected performance, lifetime, and unattended portal routes pass.
|
||||||
|
- **Carried behavior debt:** `#153` far-teleport unstreamed-edge arrival and
|
||||||
|
`#116` slide response. TS-50/TS-51 are tracked in the divergence register.
|
||||||
|
- **Deferred visual fidelity:** `#226` retail landscape detail overlay.
|
||||||
|
- **Build hygiene:** `#228` records 17 clean-Release test-project warnings;
|
||||||
|
production compilation and all tests pass.
|
||||||
|
|
||||||
|
The [documentation map](README.md) defines how this tactical ledger relates to
|
||||||
|
the milestone, roadmap, architecture, divergence register, research, and
|
||||||
|
memory.
|
||||||
|
|
||||||
## Template
|
## Template
|
||||||
|
|
||||||
Copy this block when adding a new issue:
|
Copy this block when adding a new issue:
|
||||||
|
|
@ -44,6 +67,80 @@ Copy this block when adding a new issue:
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## #228 — Clean Release build emits 17 test-project warnings
|
||||||
|
|
||||||
|
**Status:** OPEN
|
||||||
|
**Severity:** LOW
|
||||||
|
**Filed:** 2026-07-20
|
||||||
|
**Component:** tests / build hygiene
|
||||||
|
|
||||||
|
**Description:** A fresh `dotnet build AcDream.slnx -c Release --no-restore`
|
||||||
|
succeeds with zero errors but emits 17 warnings from
|
||||||
|
`tests/AcDream.Core.Tests`. Earlier current-state prose claimed “zero warnings”
|
||||||
|
after an incremental gate in which those projects did not recompile.
|
||||||
|
|
||||||
|
**Root cause / status:** The warnings are existing nullable-flow (`CS8600`,
|
||||||
|
`CS8602`, `CS8625`), never-assigned test fixture fields (`CS0649`), and xUnit
|
||||||
|
analyzer findings (`xUnit1025`, `xUnit1031`, `xUnit2013`, `xUnit2017`). One
|
||||||
|
duplicate `InlineData` also causes xUnit to skip a duplicate test-case ID during
|
||||||
|
discovery; the intended unique cases still pass. This is test hygiene, not a
|
||||||
|
production runtime failure.
|
||||||
|
|
||||||
|
**Files:** `tests/AcDream.Core.Tests/Conformance/DatConcurrencyStressTests.cs`;
|
||||||
|
`tests/AcDream.Core.Tests/Physics/Motion/RemoteChaseEndToEndHarnessTests.cs`;
|
||||||
|
`tests/AcDream.Core.Tests/Physics/CellGraphMembershipTests.cs`;
|
||||||
|
`tests/AcDream.Core.Tests/Physics/DoorSetupGfxObjInspectionTests.cs`;
|
||||||
|
`tests/AcDream.Core.Tests/Physics/MotionInterpreterDoMotionFamilyTests.cs`;
|
||||||
|
`tests/AcDream.Core.Tests/Rendering/Wb/AcSurfaceMetadataTableTests.cs`;
|
||||||
|
`tests/AcDream.Core.Tests/Physics/MotionInterpreterTests.cs`;
|
||||||
|
`tests/AcDream.Core.Tests/Physics/CellArrayTests.cs`;
|
||||||
|
`tests/AcDream.Core.Tests/Streaming/StreamingControllerTwoTierTests.cs`.
|
||||||
|
|
||||||
|
**Acceptance:** A non-incremental Release solution build reports zero warnings
|
||||||
|
and zero errors without suppressing analyzers or weakening nullable checking;
|
||||||
|
the full 6,452-pass / 5-skip suite remains green.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## #226 — Retail landscape detail-texture overlay is not rendered
|
||||||
|
|
||||||
|
**Status:** OPEN — deferred visual fidelity; the user-visible tiling regression
|
||||||
|
in #155 is fixed
|
||||||
|
**Severity:** LOW
|
||||||
|
**Filed:** 2026-07-20
|
||||||
|
**Component:** rendering / terrain material
|
||||||
|
|
||||||
|
**Description:** Retail can overlay a high-frequency landscape detail texture,
|
||||||
|
faded by viewer distance and gated by the Environment Detail Textures setting.
|
||||||
|
acdream now repeats every base/overlay/road surface at its authored
|
||||||
|
`TerrainTex.TexTiling`, which fixed the stretched/blurry symptom in #155, but
|
||||||
|
does not yet render this separate optional detail layer.
|
||||||
|
|
||||||
|
**Root cause / status:** The earlier #155 investigation conflated two retail
|
||||||
|
mechanisms. `bb5acab9` ported the behavior that produced the observed mismatch:
|
||||||
|
`TexMerge::CopyAndTile`/`Merge` pass each source's authored base tiling into the
|
||||||
|
terrain composition. The still-missing detail pass is a distinct
|
||||||
|
`LScape::GenerateDetailSurfaces`/`ACRender::landPolyDraw` path. The first
|
||||||
|
experimental detail-array implementation sampled the wrong neutral/data
|
||||||
|
contract and was reverted rather than shipping a darkened ground. TS-52 records
|
||||||
|
the current divergence.
|
||||||
|
|
||||||
|
**Files:** `src/AcDream.App/Rendering/TerrainAtlas.cs`;
|
||||||
|
`src/AcDream.App/Rendering/TerrainModernRenderer.cs`;
|
||||||
|
`src/AcDream.App/Rendering/Shaders/terrain_modern.frag`.
|
||||||
|
|
||||||
|
**Research:** `docs/research/2026-07-13-retail-terrain-texture-tiling-pseudocode.md`
|
||||||
|
covers the now-shipped base contract. The detail symbols cited above must be
|
||||||
|
distilled into a dedicated pseudocode note as the first #226 implementation
|
||||||
|
step; the reverted experiment remains available in git history.
|
||||||
|
|
||||||
|
**Acceptance:** With retail Environment Detail Textures enabled, close ground
|
||||||
|
shows the same high-frequency detail and distance fade without changing base
|
||||||
|
color/brightness. Disabling it produces the already-accepted authored base
|
||||||
|
tiling.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## #225 — Scene particles overpaint translucent world objects
|
## #225 — Scene particles overpaint translucent world objects
|
||||||
|
|
||||||
**Status:** IN-PROGRESS — implementation/reviews and connected stress gate pass; final visual gate pending
|
**Status:** IN-PROGRESS — implementation/reviews and connected stress gate pass; final visual gate pending
|
||||||
|
|
@ -172,6 +269,16 @@ The run was performed over RDP, but software pacing was explicitly disabled and
|
||||||
`pace` remained zero, so these are engine-throughput measurements rather than
|
`pace` remained zero, so these are engine-throughput measurements rather than
|
||||||
remote-display refresh measurements. The lifestone/particle visual gate remains.
|
remote-display refresh measurements. The lifestone/particle visual gate remains.
|
||||||
|
|
||||||
|
The 2026-07-20 unattended R6 rebaseline repeated the seven-destination route
|
||||||
|
without an interactive desktop and exercised semantic turn, forward, charged
|
||||||
|
jump, and combat input through the production dispatcher. All seven portal
|
||||||
|
materializations, outbound movement gates, same-location memory/update checks,
|
||||||
|
fatal-log scan, and graceful WM_CLOSE teardown passed. Caul update p95 was
|
||||||
|
1.2 ms on the first visit and 1.1 ms on return; Sawato was 0.2/0.3 ms. This is
|
||||||
|
additional lifetime/correctness evidence, not a replacement for the translucent
|
||||||
|
lifestone visual check. See
|
||||||
|
`docs/research/2026-07-20-connected-r6-soak.md`.
|
||||||
|
|
||||||
**Files:** `src/AcDream.App/Rendering/RetailAlphaQueue.cs`;
|
**Files:** `src/AcDream.App/Rendering/RetailAlphaQueue.cs`;
|
||||||
`src/AcDream.App/Rendering/Wb/WbDrawDispatcher.cs`;
|
`src/AcDream.App/Rendering/Wb/WbDrawDispatcher.cs`;
|
||||||
`src/AcDream.App/Rendering/ParticleRenderer.cs`;
|
`src/AcDream.App/Rendering/ParticleRenderer.cs`;
|
||||||
|
|
@ -210,7 +317,7 @@ degrade FPS, and revisiting an expired region restores its objects.
|
||||||
|
|
||||||
## #224 — Gameplay indicator bar only implemented effect icons
|
## #224 — Gameplay indicator bar only implemented effect icons
|
||||||
|
|
||||||
**Status:** IN-PROGRESS
|
**Status:** DONE — 2026-07-17, user visually confirmed after detail-panel polish
|
||||||
**Severity:** MEDIUM
|
**Severity:** MEDIUM
|
||||||
**Filed:** 2026-07-17
|
**Filed:** 2026-07-17
|
||||||
**Component:** retained UI / gameplay indicators / session telemetry
|
**Component:** retained UI / gameplay indicators / session telemetry
|
||||||
|
|
@ -249,6 +356,13 @@ selected spell name/description now reflows to the authored width and its own
|
||||||
`0x10000127` scrollbar works independently of the upper effect-list scrollbar.
|
`0x10000127` scrollbar works independently of the upper effect-list scrollbar.
|
||||||
Vitae recovery XP also uses retail's grouped integer presentation.
|
Vitae recovery XP also uses retail's grouped integer presentation.
|
||||||
|
|
||||||
|
**Resolution:** `52c529be`, `a96767ba`, `d1d60310`, `16c21e29`, and
|
||||||
|
`82789eea` ported the strip, shared pages, retail Vitae/Character Information,
|
||||||
|
button state, description wrapping, independent lower scrolling, and grouped
|
||||||
|
XP. The user accepted the resulting pages. Transport packet-loss averaging and
|
||||||
|
Mini Game gameplay remain explicitly tracked by AP-110 rather than keeping this
|
||||||
|
visible UI issue open.
|
||||||
|
|
||||||
**Files:** `src/AcDream.App/UI/Layout/IndicatorBarController.cs`;
|
**Files:** `src/AcDream.App/UI/Layout/IndicatorBarController.cs`;
|
||||||
`src/AcDream.App/UI/Layout/DatWidgetFactory.cs`;
|
`src/AcDream.App/UI/Layout/DatWidgetFactory.cs`;
|
||||||
`src/AcDream.Core.Net/WorldSession.cs`; `src/AcDream.App/UI/RetailUiRuntime.cs`.
|
`src/AcDream.Core.Net/WorldSession.cs`; `src/AcDream.App/UI/RetailUiRuntime.cs`.
|
||||||
|
|
@ -2618,42 +2732,42 @@ BCL-only.
|
||||||
|
|
||||||
**2026-07-09 triage:** investigated, verdict STILL_OPEN — a fix for this exact bug (`9444a328`, normalizing the panel root to (0,0) for off-screen FBO captures) exists but only on unmerged branches (`codex/mockup-stage` / `claude/peaceful-visvesvaraya-e0a196`); `StudioWindow.cs` on this branch still has no position-normalization code and the mechanism is unfixed here.
|
**2026-07-09 triage:** investigated, verdict STILL_OPEN — a fix for this exact bug (`9444a328`, normalizing the panel root to (0,0) for off-screen FBO captures) exists but only on unmerged branches (`codex/mockup-stage` / `claude/peaceful-visvesvaraya-e0a196`); `StudioWindow.cs` on this branch still has no position-normalization code and the mechanism is unfixed here.
|
||||||
|
|
||||||
## #155 — Outdoor terrain textures look stretched + blurry vs retail (missing landscape DETAIL-texture overlay)
|
## #155 — Outdoor terrain textures looked stretched and blurry vs retail
|
||||||
|
|
||||||
**Status:** OPEN — **root cause VERIFIED (oracle-first); fix attempt implemented + REVERTED** (rendered the ground black). Ready for a focused fresh implementation pass.
|
**Status:** DONE — 2026-07-13, `bb5acab9`, user visually confirmed
|
||||||
**Severity:** MEDIUM (visible — outdoor ground reads soft/stretched everywhere vs retail's crisp ground; user side-by-side screenshots)
|
**Severity:** MEDIUM
|
||||||
**Filed:** 2026-06-25
|
**Filed:** 2026-06-25
|
||||||
**Component:** render — terrain texturing (WB-derived modern path: `TerrainAtlas` / `TerrainModernRenderer` / `terrain_modern.frag`)
|
**Component:** rendering / terrain texture composition
|
||||||
|
|
||||||
**Description (user-observed, 2026-06-25):** Outdoor terrain textures look stretched and less detailed than retail — a cobblestone road's stones look too big/blurry, grass is softer. Side-by-side: retail crisp, acdream smeared.
|
**Description:** Cobblestone, roads, and grass appeared enlarged and soft even
|
||||||
|
though the high-resolution source surfaces, mipmaps, and anisotropic filtering
|
||||||
|
were active.
|
||||||
|
|
||||||
**Root cause (VERIFIED — decomp + dat, not guessed):** acdream renders one base texture tiled **once per 24 m landcell** (`terrain_modern.frag:49` `const float TILE = 1.0;`, `vBaseUV` 0→1 per cell) and **ignores the dat's detail-texture fields entirely**. Retail overlays a high-frequency **landscape detail texture** on the base ground; that overlay is what keeps retail's ground crisp up close. Filtering is NOT the problem (the ground array already has mipmaps + `LinearMipmapLinear` + 16× anisotropy, `TerrainAtlas.cs:187-193`); resolution is NOT the problem (terrain is 512² in both Portal and HighRes).
|
**Corrected root cause / resolution:** The first investigation attributed the
|
||||||
|
whole symptom to retail's separate detail-texture overlay and incorrectly
|
||||||
|
claimed the base `TerrainTex.TexTiling` field did not exist. The later
|
||||||
|
named-retail/DAT audit disproved that claim. Retail
|
||||||
|
`TexMerge::CopyAndTile @ 0x00503580` and `TexMerge::Merge @ 0x005038C0` pass
|
||||||
|
each base, overlay, and road surface's authored `TexTiling` into composition.
|
||||||
|
acdream had hard-coded one repeat per 24-metre landcell. `bb5acab9` carries the
|
||||||
|
field through `TerrainAtlas`, uploads a layer-indexed table, and applies it in
|
||||||
|
the modern shader while leaving cell-scale alpha masks unchanged. The user
|
||||||
|
confirmed the outdoor textures now match the expected scale.
|
||||||
|
|
||||||
**Verified retail mechanism (decomp `docs/research/named-retail/acclient_2013_pseudo_c.txt`):**
|
The optional high-frequency Environment Detail Textures pass is a different
|
||||||
- Dat fields on `DatReaderWriter.Types.TerrainTex` (confirmed via reflection on Chorizite.DatReaderWriter 2.1.7): `DetailTextureId` (`QualifiedDataId<SurfaceTexture>`, `.DataId`) + `DetailTexTiling` (`uint`). acdream currently reads neither (only `TextureId`).
|
retail mechanism. It remains deferred under #226/TS-52 and does not keep this
|
||||||
- `ACRender::landPolyDraw` 0x006b6525 (lines 702299-702300): **detail UV = `curr_detail_tiling × baseUV`** (the detail texture tiles `detail_tiling×` relative to the base).
|
fixed user-visible regression open.
|
||||||
- `landPolyDraw` 0x006b6450-0x006b649c (lines 702263-702287): **distance fade** — detail alpha is FULL at camera depth `< 10`, lerps to 0 by depth `50`, gone beyond. (Detail only sharpens up close.)
|
|
||||||
- 0x0059cab4 / lines 425099-425112: blend = **`TEXOP_MODULATE`** (modern equivalent: MODULATE2X `base*detail*2`, neutral at gray 0.5).
|
|
||||||
- `TexMerge::GetDetailTiling` 0x00503a10 (line 263852); `LScape::GenerateDetailSurfaces`/`SetDetailTexturing` 0x00506b40 (line 268389). Gated by the `EnvironmentDetailTextures` graphics preference (`Render::m_RenderPrefs.EnvironmentDetailTextures`).
|
|
||||||
- **FAITHFULNESS NOTE:** retail uses a **single landscape detail-tiling SCALAR** — `GetDetailTiling(region, 0)` reads `TerrainDesc[0].DetailTexTiling` (category 0 = landscape; default **2.0** @0x0081eca8), stored in global `Render::curr_detail_tiling` and applied to ALL terrain UVs. It is **NOT per-terrain-type**. Prefer the single scalar.
|
|
||||||
|
|
||||||
**⚠ DO-NOT-RETRY:** the first investigation agent **FABRICATED a base `TexTiling` field** — it does **NOT** exist on `TerrainTex` (only `DetailTexTiling`). Do not re-introduce a "read `TexTiling`, multiply the base UV" fix; the base tiling is not a per-type dat field. (Verify the actual base landcell UV scale in the decomp before touching `TILE`.)
|
**Files:** `src/AcDream.App/Rendering/TerrainAtlas.cs`;
|
||||||
|
`src/AcDream.App/Rendering/TerrainModernRenderer.cs`;
|
||||||
|
`src/AcDream.App/Rendering/TerrainTextureTilingTable.cs`;
|
||||||
|
`src/AcDream.App/Rendering/Shaders/terrain_modern.frag`.
|
||||||
|
|
||||||
**Fix attempt (implemented + REVERTED, this session):** built a parallel detail `GL_TEXTURE_2D_ARRAY` (per type from `DetailTextureId`) + `uDetailTiling[]` + the shader block `rgb *= mix(vec3(1.0), detail*2.0, fade)` with the 10→50 depth fade. It **compiled, linked, ran with no GL error** — but the ground rendered **black/dark up close**: the detail array sampled near-zero, so MODULATE2X collapsed `rgb` to 0. **The bindless handles were verified NOT swapped** (renderer correctly binds `(terrain, alpha, detail)`). The bug is in the detail-texture **DATA**: the no-detail gray fill (`NoDetailGray=128`) didn't land as neutral, OR `DetailTextureId` decodes dark/black, OR AC's detail textures are not 0.5-centered (so MODULATE2X darkens). Reverted via `git checkout` — terrain back to the working (blurry) state.
|
**Research:** `docs/research/2026-07-13-retail-terrain-texture-tiling-pseudocode.md`.
|
||||||
|
|
||||||
**NEXT (debugging steps for the fresh pass):**
|
**Acceptance:** Authored grass, road, base, and overlay textures repeat at
|
||||||
1. **Dump the detail array content** — are the layers ~0.5 gray or ~0 black? (Throwaway: decode each `DetailTextureId` + print mean brightness.) This tells you gray-fill vs decode vs texture-content.
|
retail scale without reducing source resolution or changing blend masks —
|
||||||
2. If the textures decode dark, AC detail textures may not be gray-centered → use plain MODULATE or re-center, not MODULATE2X. Confirm the actual blend visually.
|
passed in the connected visual gate.
|
||||||
3. Confirm `DetailTextureId` → `SurfaceTexture` → `RenderSurface` resolves (do the detail textures even exist for these terrain types? many may be 0 → must fall to the gray no-op).
|
|
||||||
4. Use retail's **single landscape scalar** (`TerrainDesc[0].DetailTexTiling`, default 2.0), not per-type (faithfulness note above).
|
|
||||||
5. Gate behind an `EnvironmentDetailTextures` equivalent.
|
|
||||||
6. **Secondary (separate, unconfirmed):** is the base `TILE=1.0` (once per cell) correct vs retail? Verify the landcell base UV scale in the decomp during the fix — it may also contribute to "stretched."
|
|
||||||
|
|
||||||
**Files (the reverted attempt, for reference):** `TerrainAtlas.cs` (detail array build + gray fill + `DetailTiling`), `terrain_modern.frag` (uDetail sampler + MODULATE2X + fade), `TerrainModernRenderer.cs` (bind detail handle + upload `uDetailTiling[]`).
|
|
||||||
|
|
||||||
**Milestone note:** freeze-override render-polish (off the M1.5 critical path); resume when prioritized. Detail-overlay is a real retail feature acdream lacks — register an AP row when it ships (or note it as a known divergence until then).
|
|
||||||
|
|
||||||
**Acceptance:** outdoor ground (cobblestone road + grass) reads crisp up close matching retail, detail fades cleanly past ~50 m, no overall color/brightness shift (modulate neutral); user side-by-side vs retail.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -2699,9 +2813,18 @@ BCL-only.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## #153 — Portals only work once per session (can't run in, run out, re-enter)
|
## #153 — Far teleport onto an unstreamed landblock edge can run away
|
||||||
|
|
||||||
**Status:** 🟡 PARTIALLY FIXED — REOPENED 2026-06-21 (a NARROWER residual). The cell-relative carried-anchor (Option B, Slices 1–3+7, `438bb68`→`403a338`) **fixes the cascade for a STREAMED-terrain arrival** (live-verified: `+Je` ran through ~10 far-town landblocks across 2 sessions, zero march). BUT a third live session found the cascade **RECURS when a teleport arrives onto a NOT-YET-STREAMED landblock NEAR AN EDGE.** Evidence (`launch5.log`): arrival `[snap] claim=0xC98C0028 pos=(113.666,190.259,22.010) branch=NO-LANDBLOCK (lbs=0) -> verbatim` (local Y=190.3, **1.7 m from the 192 boundary**) → cell marches `0xC98C(lbY 0x8C) → 0xC9FE(lbY 0xFE)` +2/tick while Z free-falls 22→−19; the outbound wire then sends the marched cell `C9FE0031` with compensating garbage `localY=−21684` → ACE `MOVEMENT SPEED` / `failed transition` → player stuck. Contrast same session: hub `0x00070133` VALIDATED→fine; far town `0x977B000C` arrived unstreamed but **mid-block** (Y=73.8) → Z free-fall only, NO march. **ROOT (hypothesis, NOT yet apparatus-confirmed):** outdoor teleport places immediately but the destination streams a few ticks later (`streaming: dungeon EXIT-expand -> (201,140)` logs just after placement); during that gap the resolve runs against an empty world, and at an edge the player crosses into the unstreamed neighbour where the carried anchor (which computes to `(0,0,0)` at the recentered center) gives no protection. Same root as the Z free-fall (`#135`/`#138` placed-but-unstreamed gap). **DO NOT guess-patch** (original #145 burned 5 attempts) — needs a capture + an anchor/guard diagnostic at the crossing FIRST. Likely fix shape: a streaming-gap HOLD (freeze the per-tick resolve — no march, no fall — until the player's landblock loads; the async equivalent of retail's synchronous load), which would fix both symptoms. Suites still green; `TeleportFarTownRunawayTests` covers the STREAMED case only. [Prior "fixed" banner was premature — 2 clean sessions wasn't enough for a streaming-timing bug.]
|
**Status:** IN-PROGRESS — the original repeat-portal failure and streamed-arrival
|
||||||
|
cascade are fixed; a narrower unstreamed-arrival-near-edge residual remains.
|
||||||
|
The cell-relative carried anchor (Option B, Slices 1–3+7,
|
||||||
|
`438bb68`→`403a338`) passed roughly ten streamed far-town transitions. The
|
||||||
|
recorded residual arrives within about 2 metres of a 192-metre landblock edge
|
||||||
|
before the neighbour is resident, then advances membership through unstreamed
|
||||||
|
cells while producing an inconsistent outbound cell/local-position pair. Keep
|
||||||
|
the capture-first/DO-NOT-RETRY constraints and detailed verified mechanism
|
||||||
|
below; this is the issue formerly misreferenced in living docs as
|
||||||
|
“#145-residual.” Issue #145 is an unrelated completed UI Z-order bug.
|
||||||
|
|
||||||
**Status (historical):** REOPENED 2026-06-21 — RESIDUAL: a teleport to a FAR town triggers a per-frame **resolver runaway** (the 2026-06-20 source-drop fix holds for Holtburg↔dungeon, but far-town destinations regress). #138 (objects come back) is confirmed SEPARATE + fixed. Root cause under research (retail-decomp oracle workflow).
|
**Status (historical):** REOPENED 2026-06-21 — RESIDUAL: a teleport to a FAR town triggers a per-frame **resolver runaway** (the 2026-06-20 source-drop fix holds for Holtburg↔dungeon, but far-town destinations regress). #138 (objects come back) is confirmed SEPARATE + fixed. Root cause under research (retail-decomp oracle workflow).
|
||||||
**Severity:** HIGH (blocks far-town portal travel; breaks collision after the teleport — user, 2026-06-21)
|
**Severity:** HIGH (blocks far-town portal travel; breaks collision after the teleport — user, 2026-06-21)
|
||||||
|
|
@ -3060,7 +3183,7 @@ Both are the **entity-lifecycle/render path across a teleport**, NOT the streami
|
||||||
|
|
||||||
**Acceptance:** portal out of the 0x0007 dungeon → full outdoor world streams (trees/scenery present), **server objects (doors/NPCs/portals) render**, **own avatar renders across repeated round-trips**, collision works, position tracks (no avatar-vs-camera desync).
|
**Acceptance:** portal out of the 0x0007 dungeon → full outdoor world streams (trees/scenery present), **server objects (doors/NPCs/portals) render**, **own avatar renders across repeated round-trips**, collision works, position tracks (no avatar-vs-camera desync).
|
||||||
|
|
||||||
**2026-07-10 gate — PASSED, #138 CLOSED:** the user confirmed the full dungeon round-trip end-to-end — ENTER + NAVIGATE (dungeon streams, renders, collides, navigable, doors work) AND the EXIT (portal OUT to the outdoor world, world streams, collision holds, position tracks). This completes the #138 acceptance and lands M1.5. **Separate follow-up still open:** `#145-residual` (the far-town teleport-OUT arrival cascade) is a narrow far-teleport streaming edge case tracked on its own; it is NOT a #138 or M1.5 blocker and stays open for capture-harness-first work if it recurs.
|
**2026-07-10 gate — PASSED, #138 CLOSED:** the user confirmed the full dungeon round-trip end-to-end — ENTER + NAVIGATE (dungeon streams, renders, collides, navigable, doors work) AND the EXIT (portal OUT to the outdoor world, world streams, collision holds, position tracks). This completes the #138 acceptance and lands M1.5. **Separate follow-up still open:** #153 (the far-town teleport-OUT arrival cascade) is a narrow far-teleport streaming edge case tracked on its own; it is NOT a #138 or M1.5 blocker and stays open for capture-harness-first work if it recurs.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -7468,7 +7591,7 @@ App 741+2skip / UI 425 / Net 385 green.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## #170 — Remote creature chase+attack renders wrong vs retail (glide, run not sustained)
|
## Historical closing summary for #170 — Remote creature chase+attack
|
||||||
|
|
||||||
**Status:** DONE (2026-07-04, user visual gate passed — "as close to retail now as
|
**Status:** DONE (2026-07-04, user visual gate passed — "as close to retail now as
|
||||||
I can see"). Three-fix arc: `427332ac` deleted the per-frame
|
I can see"). Three-fix arc: `427332ac` deleted the per-frame
|
||||||
|
|
@ -8712,10 +8835,10 @@ The mechanism named as the suspect in #68 (`RemoteMoveToDriver`'s arrival handli
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## #87 — Drop WB fork patch by switching to PrepareEnvCellGeomMeshDataAsync
|
## #227 — [DONE] Drop WB fork patch by switching to PrepareEnvCellGeomMeshDataAsync
|
||||||
|
|
||||||
**Status:** DONE (2026-07-09, investigated this session).
|
**Status:** DONE (2026-07-09, investigated this session).
|
||||||
Superseded by Phase O (2026-05-21, dropped the `WorldBuilder.Shared`/`Chorizite.OpenGLSDLBackend` project references entirely — there's no more forked submodule to patch/revert) and Phase A8 (2026-05-28, shipped `EnvCellRenderer.cs` which already calls the narrow `PrepareEnvCellGeomMeshDataAsync(geomId, environmentId, cellStructure, surfaces)` entry point at `EnvCellRenderer.cs:355`, using the bit-32-tagged synthetic geom id the issue proposed). `ObjectMeshManager.cs`'s bounds/type dispatch now branches on resolution type before calling `TryGet<T>`, so the blind `TryGet<Setup>` bug is structurally gone. `EnvCellRenderer` remains the live production cell-rendering path under Phase U as of commit `6aabe0b5` (Jul 6 2026). Note: a second, unrelated, already-DONE issue also uses the heading `## #87` elsewhere in this file (a pre-existing numbering collision, left untouched).
|
Superseded by Phase O (2026-05-21, dropped the `WorldBuilder.Shared`/`Chorizite.OpenGLSDLBackend` project references entirely — there's no more forked submodule to patch/revert) and Phase A8 (2026-05-28, shipped `EnvCellRenderer.cs` which already calls the narrow `PrepareEnvCellGeomMeshDataAsync(geomId, environmentId, cellStructure, surfaces)` entry point at `EnvCellRenderer.cs:355`, using the bit-32-tagged synthetic geom id the issue proposed). `ObjectMeshManager.cs`'s bounds/type dispatch now branches on resolution type before calling `TryGet<T>`, so the blind `TryGet<Setup>` bug is structurally gone. `EnvCellRenderer` remains the live production cell-rendering path under Phase U as of commit `6aabe0b5` (Jul 6 2026). This historical item was renumbered from a duplicate `#87` heading to `#227` during the 2026-07-20 documentation audit; the original indoor-cell issue retains #87.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
98
docs/README.md
Normal file
98
docs/README.md
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
# acdream documentation map
|
||||||
|
|
||||||
|
This page is the entry point for project documentation. It distinguishes
|
||||||
|
current sources of truth from implementation history so an old plan or issue
|
||||||
|
banner cannot silently override the current program state.
|
||||||
|
|
||||||
|
## Current snapshot — 2026-07-20
|
||||||
|
|
||||||
|
- **Active milestone:** M3, “Cast a spell.” The automated implementation and
|
||||||
|
connected single-client magic/portal presentation gates are complete.
|
||||||
|
- **Next visual gates:** the R6 locomotion/collision/projectile/teleport retail
|
||||||
|
comparison, then the final two-client portal-out/materialization observer
|
||||||
|
comparison (`#218`).
|
||||||
|
- **Separate visual verification:** the shared-alpha lifestone/particle result
|
||||||
|
in `#225`; its connected resource-lifetime and performance routes pass.
|
||||||
|
- **Carried behavior debt:** `#153` (far teleport onto an unstreamed edge),
|
||||||
|
`#116` (two narrowed slide-response cases), and divergence rows TS-50/TS-51.
|
||||||
|
- **Deferred engineering tracks:** Modern Pipeline MP1b+ and Linux/headless
|
||||||
|
automation (Track LH). Neither is part of the active M3 gate.
|
||||||
|
- **Divergence audit:** 178 active rows — IA 17, AD 37, AP 85, TS 34,
|
||||||
|
and UN 5 — plus the retained retired TS-37 history note.
|
||||||
|
- **Latest automated baseline:** Release build succeeds with 17 known
|
||||||
|
test-project warnings (`#228`); 6,452 tests passed and 5 intentionally
|
||||||
|
skipped. The unattended connected R6 route
|
||||||
|
completed seven portal materializations, production input exercises, and a
|
||||||
|
graceful close. See
|
||||||
|
[`research/2026-07-20-connected-r6-soak.md`](research/2026-07-20-connected-r6-soak.md).
|
||||||
|
|
||||||
|
## Sources of truth
|
||||||
|
|
||||||
|
Read these in this order when deciding what to do next:
|
||||||
|
|
||||||
|
1. [`plans/2026-05-12-milestones.md`](plans/2026-05-12-milestones.md) — the
|
||||||
|
active playable outcome, freeze boundaries, and visual gates.
|
||||||
|
2. [`plans/2026-04-11-roadmap.md`](plans/2026-04-11-roadmap.md) — strategic
|
||||||
|
phase ledger: shipped, active, deferred, and future work.
|
||||||
|
3. [`ISSUES.md`](ISSUES.md) — tactical defects and small follow-ups. The status
|
||||||
|
inside an issue is authoritative; physical order is not.
|
||||||
|
4. [`architecture/retail-divergence-register.md`](architecture/retail-divergence-register.md)
|
||||||
|
— every known place runtime behavior can differ from retail.
|
||||||
|
5. [`architecture/acdream-architecture.md`](architecture/acdream-architecture.md)
|
||||||
|
and [`architecture/code-structure.md`](architecture/code-structure.md) —
|
||||||
|
ownership, dependency, update-thread, and extraction rules.
|
||||||
|
6. [`architecture/worldbuilder-inventory.md`](architecture/worldbuilder-inventory.md)
|
||||||
|
— rendering/DAT code already owned in-tree versus mechanisms still ours to
|
||||||
|
port.
|
||||||
|
|
||||||
|
If these disagree, milestones control the current outcome, the roadmap controls
|
||||||
|
work ordering, the issue status controls the individual defect, and the
|
||||||
|
architecture documents control implementation shape. Reconcile the stale
|
||||||
|
document in the same change; do not leave both claims standing.
|
||||||
|
|
||||||
|
## Research and implementation records
|
||||||
|
|
||||||
|
- [`research/named-retail/`](research/named-retail/) is the primary retail
|
||||||
|
oracle: named pseudo-C, headers, symbols, and types from the Sept 2013 build.
|
||||||
|
- [`research/decompiled/`](research/decompiled/) is the older Ghidra fallback.
|
||||||
|
- [`research/`](research/) contains focused pseudocode, traces, fixtures, and
|
||||||
|
gate reports. A dated research note records evidence; it does not become a
|
||||||
|
new roadmap.
|
||||||
|
- [`superpowers/specs/`](superpowers/specs/) and
|
||||||
|
[`superpowers/plans/`](superpowers/plans/) are per-slice design and execution
|
||||||
|
records. Completed plans remain historical.
|
||||||
|
- [`audit/`](audit/) contains completion and conformance audits.
|
||||||
|
|
||||||
|
## Durable memory
|
||||||
|
|
||||||
|
- [`../claude-memory/MEMORY.md`](../claude-memory/MEMORY.md) indexes the live
|
||||||
|
subsystem memories and the render/physics digests. Read a domain digest
|
||||||
|
before changing that subsystem, especially its DO-NOT-RETRY table.
|
||||||
|
- [`../memory/`](../memory/) contains stable engineering references such as the
|
||||||
|
modern rendering pipeline, two-tier streaming, and toolchain notes.
|
||||||
|
|
||||||
|
Memory accelerates recall; it does not outrank the canonical documents above.
|
||||||
|
When current truth changes, update the relevant canonical document and distill
|
||||||
|
only the durable lesson into memory.
|
||||||
|
|
||||||
|
## Historical and deprecated documents
|
||||||
|
|
||||||
|
- [`bugs.md`](bugs.md) is the April 2026 bug snapshot. It is preserved for
|
||||||
|
archaeology and is not an active ledger.
|
||||||
|
- Dated plans and specs describe the decision at that time. Their completion
|
||||||
|
wording is historical unless the current milestone/roadmap explicitly links
|
||||||
|
the item as active.
|
||||||
|
- Old `R1→R8` architecture sequencing is superseded. Current execution comes
|
||||||
|
from the milestones and strategic roadmap.
|
||||||
|
|
||||||
|
## Documentation maintenance rules
|
||||||
|
|
||||||
|
- Update milestone, roadmap, issue, divergence, architecture, and memory claims
|
||||||
|
in the same commit when a shipped change affects them.
|
||||||
|
- Keep one issue ID per defect. Narrow an issue in place; do not reuse another
|
||||||
|
issue's number as a shorthand.
|
||||||
|
- Mark automated, connected, and visual gates separately. An automated pass is
|
||||||
|
not a visual acceptance, and an RDP throughput sample is not a local-display
|
||||||
|
visual comparison.
|
||||||
|
- Preserve research history, but remove stale “current/next” claims from living
|
||||||
|
documents once the state advances.
|
||||||
|
|
@ -13,6 +13,11 @@ A modern C# .NET 10 Asheron's Call client that:
|
||||||
inheritance, interfaces, dependency injection) while matching retail
|
inheritance, interfaces, dependency injection) while matching retail
|
||||||
behavior exactly
|
behavior exactly
|
||||||
|
|
||||||
|
**Current program status is intentionally not duplicated in this architecture
|
||||||
|
document.** Start at [`../README.md`](../README.md), then use the milestone and
|
||||||
|
roadmap linked there. This file governs ownership and dependency shape even
|
||||||
|
when the active gameplay milestone changes.
|
||||||
|
|
||||||
## Guiding Principle
|
## Guiding Principle
|
||||||
|
|
||||||
**The code is modern. The behavior is retail.**
|
**The code is modern. The behavior is retail.**
|
||||||
|
|
@ -790,12 +795,15 @@ and `docs/superpowers/specs/`.
|
||||||
Current movement/collision ownership:
|
Current movement/collision ownership:
|
||||||
|
|
||||||
- **B.3** is shipped MVP history: first collision resolver foundation.
|
- **B.3** is shipped MVP history: first collision resolver foundation.
|
||||||
- **L.1** owns animation/motion parity, including root-motion coupling.
|
- **L.1/R6** own animation/motion parity and the complete retail object-frame
|
||||||
- **L.2** owns movement and collision conformance:
|
update order over canonical `LiveEntityRuntime` records.
|
||||||
|
- **L.2** owns the remaining movement and collision conformance:
|
||||||
`docs/plans/2026-04-29-movement-collision-conformance.md`.
|
`docs/plans/2026-04-29-movement-collision-conformance.md`.
|
||||||
- **G.3** owns dungeon streaming and portal-space delivery after L.2e lands
|
- **G.3 is shipped**: dungeon streaming, portal-space presentation, collision,
|
||||||
trustworthy `cell_bsp`, `CELLARRAY`, adjacent-cell checks, and building
|
lighting, doors, and the full round-trip gate landed. The separate far-
|
||||||
entry/exit boundaries.
|
teleport unstreamed-edge residual is issue #153, not unfinished G.3.
|
||||||
|
- **M3** owns current connected magic/portal acceptance; Track LH is the future
|
||||||
|
presentation-independent Linux/headless extraction.
|
||||||
|
|
||||||
The GameEntity / thin GameWindow refactor remains a valid target architecture,
|
The GameEntity / thin GameWindow refactor remains a valid target architecture,
|
||||||
but it is not a prerequisite for L.2. Do not resurrect old R1-R8 phase numbers
|
but it is not a prerequisite for L.2. Do not resurrect old R1-R8 phase numbers
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,8 @@
|
||||||
"Code Structure Rules" section in `CLAUDE.md`.
|
"Code Structure Rules" section in `CLAUDE.md`.
|
||||||
**Purpose:** Describe the desired structural state of the App layer,
|
**Purpose:** Describe the desired structural state of the App layer,
|
||||||
explain the rules we've adopted, and lay out the safe extraction
|
explain the rules we've adopted, and lay out the safe extraction
|
||||||
sequence from today's reality (one 15,288-line `GameWindow.cs`) to the
|
sequence from today's reality (one 14,557-line `GameWindow.cs` at the
|
||||||
|
2026-07-20 audit) to the
|
||||||
target (thin `GameWindow`, small focused collaborators).
|
target (thin `GameWindow`, small focused collaborators).
|
||||||
**Companion to:** [`acdream-architecture.md`](acdream-architecture.md)
|
**Companion to:** [`acdream-architecture.md`](acdream-architecture.md)
|
||||||
(the layered architecture) and
|
(the layered architecture) and
|
||||||
|
|
@ -20,7 +21,7 @@ layer is wire-compatible, the UI has a stable contract, plugins load.
|
||||||
The structural debt is concentrated in **one file**:
|
The structural debt is concentrated in **one file**:
|
||||||
|
|
||||||
```
|
```
|
||||||
src/AcDream.App/Rendering/GameWindow.cs 15,288 lines
|
src/AcDream.App/Rendering/GameWindow.cs 14,557 lines (2026-07-20)
|
||||||
```
|
```
|
||||||
|
|
||||||
`GameWindow` is the single object that:
|
`GameWindow` is the single object that:
|
||||||
|
|
@ -341,7 +342,7 @@ Each step is **one PR-sized refactor**. Each must build clean, all
|
||||||
tests pass, and visual verification at Holtburg looks identical to
|
tests pass, and visual verification at Holtburg looks identical to
|
||||||
the previous step. Don't bundle two steps.
|
the previous step. Don't bundle two steps.
|
||||||
|
|
||||||
### Step 1 — `RuntimeOptions` (this PR)
|
### Step 1 — `RuntimeOptions` — SHIPPED (`eda936dc`)
|
||||||
|
|
||||||
**Scope:** Replace startup-time env var reads with a typed options
|
**Scope:** Replace startup-time env var reads with a typed options
|
||||||
object built once in `Program.cs`.
|
object built once in `Program.cs`.
|
||||||
|
|
@ -357,7 +358,7 @@ new `tests/AcDream.App.Tests/` project).
|
||||||
**Verification:** `dotnet build` + `dotnet test` green. Visual launch
|
**Verification:** `dotnet build` + `dotnet test` green. Visual launch
|
||||||
verifies live mode + dat dir resolution still work.
|
verifies live mode + dat dir resolution still work.
|
||||||
|
|
||||||
### Step 2 — `LiveSessionController`
|
### Step 2 — `LiveSessionController` — SHIPPED (`0b25df53`)
|
||||||
|
|
||||||
**Scope:** Extract `TryStartLiveSession` + the WorldSession ownership +
|
**Scope:** Extract `TryStartLiveSession` + the WorldSession ownership +
|
||||||
the post-EnterWorld drain (`OnLiveStateUpdated`, `OnLiveEntityDeleted`,
|
the post-EnterWorld drain (`OnLiveStateUpdated`, `OnLiveEntityDeleted`,
|
||||||
|
|
|
||||||
|
|
@ -214,7 +214,7 @@ AP-94..AP-112 for the confirmed retail-UI completion gaps.
|
||||||
| AP-117 | Outdoor particle `CLandCell::IsInView` state is reconstructed with the modern landscape renderer's per-cell frustum plus active doorway clip-plane/scissor-AABB tests; retail `LScape::landcell_check` uses `Render::get_clip_height` + `Render::block_check` on terrain-cell corner intervals | `src/AcDream.App/Rendering/TerrainModernRenderer.cs` (`CollectVisibleCells`) | The mandatory modern renderer batches terrain by landblock and has no retail `ViewIntervalType` product. Publishing cell visibility from the exact landscape draw slices preserves ownership/order and removes the former object-survivor dependency without adding a second view pipeline | At a terrain cell grazing a frustum or doorway boundary, the conservative AABB test may freeze or resume particles on a slightly different frame than retail; whole regions outside the active doorway slice are rejected, and authored distance, login/portal fail-closed behavior, and indoor PView cells remain exact | `LScape::landcell_check @ 0x005050A0`; `CLandCell::IsInView @ 0x00532CB0`; `CPhysicsObj::ShouldDrawParticles @ 0x0050FE60` |
|
| AP-117 | Outdoor particle `CLandCell::IsInView` state is reconstructed with the modern landscape renderer's per-cell frustum plus active doorway clip-plane/scissor-AABB tests; retail `LScape::landcell_check` uses `Render::get_clip_height` + `Render::block_check` on terrain-cell corner intervals | `src/AcDream.App/Rendering/TerrainModernRenderer.cs` (`CollectVisibleCells`) | The mandatory modern renderer batches terrain by landblock and has no retail `ViewIntervalType` product. Publishing cell visibility from the exact landscape draw slices preserves ownership/order and removes the former object-survivor dependency without adding a second view pipeline | At a terrain cell grazing a frustum or doorway boundary, the conservative AABB test may freeze or resume particles on a slightly different frame than retail; whole regions outside the active doorway slice are rejected, and authored distance, login/portal fail-closed behavior, and indoor PView cells remain exact | `LScape::landcell_check @ 0x005050A0`; `CLandCell::IsInView @ 0x00532CB0`; `CPhysicsObj::ShouldDrawParticles @ 0x0050FE60` |
|
||||||
| AP-118 | An AutoWield transaction begun in active combat preserves the ready mode implied by the requested weapon. After authoritative `WieldObject`, a mode that settled without a blocker transition clears immediately; local ACE's observed pre-wield transition plus `ready -> NonCombat`, or post-wield `NonCombat -> ready -> NonCombat`, causes one normal `ChangeCombatMode` request from the trailing notice. Explicit user combat input cancels settlement. Retail's client does not need this extra request against the retail server. | `src/AcDream.App/UI/AutoWieldController.cs`; production binding in `GameWindow.cs` | Local ACE queues a trailing NonCombat callback during primary-weapon replacement and rejects an earlier request while the shuffle is busy; responding to the authoritative notice that completes that exact sequence orders the ordinary request after it without suppressing any server state | A non-ACE server that emits a different intermediate sequence can retain the settlement until a later explicit combat request, replacement, or logout clears it; peace-mode equips send none | `CPlayerSystem::AutoWield @ 0x00560A60`; `ACCWeenieObject::ServerSaysMoveItem @ 0x0058DBB0`; ACE `Player_Inventory.TryShuffleStance` / `TryDequipObjectWithNetworking` |
|
| AP-118 | An AutoWield transaction begun in active combat preserves the ready mode implied by the requested weapon. After authoritative `WieldObject`, a mode that settled without a blocker transition clears immediately; local ACE's observed pre-wield transition plus `ready -> NonCombat`, or post-wield `NonCombat -> ready -> NonCombat`, causes one normal `ChangeCombatMode` request from the trailing notice. Explicit user combat input cancels settlement. Retail's client does not need this extra request against the retail server. | `src/AcDream.App/UI/AutoWieldController.cs`; production binding in `GameWindow.cs` | Local ACE queues a trailing NonCombat callback during primary-weapon replacement and rejects an earlier request while the shuffle is busy; responding to the authoritative notice that completes that exact sequence orders the ordinary request after it without suppressing any server state | A non-ACE server that emits a different intermediate sequence can retain the settlement until a later explicit combat request, replacement, or logout clears it; peace-mode equips send none | `CPlayerSystem::AutoWield @ 0x00560A60`; `ACCWeenieObject::ServerSaysMoveItem @ 0x0058DBB0`; ACE `Player_Inventory.TryShuffleStance` / `TryDequipObjectWithNetworking` |
|
||||||
|
|
||||||
## 4. Temporary stopgap (TS) — 34 active rows (TS-20 retired 2026-07-16 — the later named-retail audit disproved the proposed DrawingBSP polygon filter; TS-37 is a retired-row historical note, not an active count; TS-39 retired R5-V3 — sticky seams bound to the ported PositionManager/StickyManager, radii threaded; TS-45 retired 2026-07-07 — hand-rolled `SphereCollision` replaced by the faithful CSphere family port, fixing the player-vs-monster crowd wedge; TS-3 retired 2026-07-07 — `frames_stationary_fall` accounting ported in the #182 verbatim UpdateObjectInternal rebuild, fixing the airborne falling-animation wedge; TS-41 retired 2026-07-07 — SERVERVEL synth-velocity remote body-drive replaced by the retail interp catch-up + unconditional MovementManager::UseTime, the remote-creature de-overlap #184; TS-42 retired 2026-07-19 — semantic animation completion now precedes the ordered Target/Movement/PartArray/Position tail; TS-44 narrowed again 2026-07-19 — complete orientation joined interpolation, only during-stick enqueue suppression remains)
|
## 4. Temporary stopgap (TS) — 34 active rows + TS-37 historical note (TS-20 retired 2026-07-16 — the later named-retail audit disproved the proposed DrawingBSP polygon filter; TS-37 is a retired-row historical note, not an active count; TS-39 retired R5-V3 — sticky seams bound to the ported PositionManager/StickyManager, radii threaded; TS-45 retired 2026-07-07 — hand-rolled `SphereCollision` replaced by the faithful CSphere family port, fixing the player-vs-monster crowd wedge; TS-3 retired 2026-07-07 — `frames_stationary_fall` accounting ported in the #182 verbatim UpdateObjectInternal rebuild, fixing the airborne falling-animation wedge; TS-41 retired 2026-07-07 — SERVERVEL synth-velocity remote body-drive replaced by the retail interp catch-up + unconditional MovementManager::UseTime, the remote-creature de-overlap #184; TS-42 retired 2026-07-19 — semantic animation completion now precedes the ordered Target/Movement/PartArray/Position tail; TS-44 narrowed again 2026-07-19 — complete orientation joined interpolation, only during-stick enqueue suppression remains)
|
||||||
|
|
||||||
| # | Divergence | Where (file:line) | Why it is safe / justified | Risk if assumption breaks | Retail oracle |
|
| # | Divergence | Where (file:line) | Why it is safe / justified | Risk if assumption breaks | Retail oracle |
|
||||||
|---|---|---|---|---|---|
|
|---|---|---|---|---|---|
|
||||||
|
|
@ -255,6 +255,7 @@ AP-94..AP-112 for the confirmed retail-UI completion gaps.
|
||||||
| TS-49 | Hidden-object availability is bridged through `TargetManager.NotifyVoyeurOfEventAndClear(ExitWorld)` because acdream has not ported retail's DetectionManager. Retail `CObjCell::hide_object` sends `LeftDetection` to detection voyeurs; acdream instead uses the existing non-Ok target update to tear down MoveTo/Sticky consumers and clear watched-role subscriptions while preserving the hidden object's own watcher role. | `src/AcDream.App/Rendering/EntityPhysicsHost.cs` (`NotifyHidden`); `src/AcDream.Core/Physics/Motion/TargetManager.cs` (`NotifyVoyeurOfEventAndClear`) | The current movement consumers already share TargetManager's status fan-out; the bridge prevents pursuit of an unavailable object without inventing a second partial detection database. | Plugins or future systems listening specifically for retail detection enter/leave events receive no `LeftDetection`; only movement/sticky target consumers observe the equivalent availability loss. | `CObjCell::hide_object @ 0x0052BE30`; retire by porting DetectionManager/CObjCell detection-voyeur delivery and routing Hidden through `LeftDetection` |
|
| TS-49 | Hidden-object availability is bridged through `TargetManager.NotifyVoyeurOfEventAndClear(ExitWorld)` because acdream has not ported retail's DetectionManager. Retail `CObjCell::hide_object` sends `LeftDetection` to detection voyeurs; acdream instead uses the existing non-Ok target update to tear down MoveTo/Sticky consumers and clear watched-role subscriptions while preserving the hidden object's own watcher role. | `src/AcDream.App/Rendering/EntityPhysicsHost.cs` (`NotifyHidden`); `src/AcDream.Core/Physics/Motion/TargetManager.cs` (`NotifyVoyeurOfEventAndClear`) | The current movement consumers already share TargetManager's status fan-out; the bridge prevents pursuit of an unavailable object without inventing a second partial detection database. | Plugins or future systems listening specifically for retail detection enter/leave events receive no `LeftDetection`; only movement/sticky target consumers observe the equivalent availability loss. | `CObjCell::hide_object @ 0x0052BE30`; retire by porting DetectionManager/CObjCell detection-voyeur delivery and routing Hidden through `LeftDetection` |
|
||||||
| TS-50 | `AnimationDone` executes semantically at each owner's retail `CPhysicsObj::process_hooks` boundary, but all other animation hooks are retained in `AnimationHookFrameQueue` until final root/part/equipped-child pose publication. Retail executes the complete hook stream before transition and the Target/Movement/PartArray/Position manager tail because its current CPartArray pose already exists in-place. Static owners correctly reach `process_hooks` only after their root, parts, and children are current. | `src/AcDream.App/Rendering/Vfx/AnimationHookFrameQueue.cs`; `src/AcDream.App/Rendering/RetailStaticAnimatingObjectScheduler.cs`; frame drain in `src/AcDream.App/Rendering/GameWindow.cs` | The modern renderer publishes immutable effect-pose snapshots after all root/child composition; deferred visual sinks avoid attaching particles/lights/audio to the previous pose. Semantic `AnimationDone` is split out and exact, so motion completion and manager behavior are not delayed. Pose-owner lifetime tokens prevent deferred hooks from crossing delete/local-ID reuse. | A non-AnimationDone hook with same-quantum semantic consequences (notably `CallPES`, default-script chaining, audio/particle creation relative to a transition) runs later than retail and can observe post-tail state or start one render frame late. | `CPhysicsObj::process_hooks @ 0x00511550`; `CPhysicsObj::UpdatePositionInternal @ 0x00512C30`; `CPhysicsObj::animate_static_object @ 0x00513DF0`; retire by publishing the current per-object/child pose before hook routing or splitting semantic and presentation sinks without changing authored hook order |
|
| TS-50 | `AnimationDone` executes semantically at each owner's retail `CPhysicsObj::process_hooks` boundary, but all other animation hooks are retained in `AnimationHookFrameQueue` until final root/part/equipped-child pose publication. Retail executes the complete hook stream before transition and the Target/Movement/PartArray/Position manager tail because its current CPartArray pose already exists in-place. Static owners correctly reach `process_hooks` only after their root, parts, and children are current. | `src/AcDream.App/Rendering/Vfx/AnimationHookFrameQueue.cs`; `src/AcDream.App/Rendering/RetailStaticAnimatingObjectScheduler.cs`; frame drain in `src/AcDream.App/Rendering/GameWindow.cs` | The modern renderer publishes immutable effect-pose snapshots after all root/child composition; deferred visual sinks avoid attaching particles/lights/audio to the previous pose. Semantic `AnimationDone` is split out and exact, so motion completion and manager behavior are not delayed. Pose-owner lifetime tokens prevent deferred hooks from crossing delete/local-ID reuse. | A non-AnimationDone hook with same-quantum semantic consequences (notably `CallPES`, default-script chaining, audio/particle creation relative to a transition) runs later than retail and can observe post-tail state or start one render frame late. | `CPhysicsObj::process_hooks @ 0x00511550`; `CPhysicsObj::UpdatePositionInternal @ 0x00512C30`; `CPhysicsObj::animate_static_object @ 0x00513DF0`; retire by publishing the current per-object/child pose before hook routing or splitting semantic and presentation sinks without changing authored hook order |
|
||||||
| TS-51 | Particle and PhysicsScript tails advance once per render frame after the complete ordinary/static object worksets. Retail advances each object's ParticleManager and ScriptManager inside every admitted `UpdateObjectInternal` quantum; `animate_static_object` also advances that static owner's managers using its whole admitted elapsed interval. | `src/AcDream.App/Rendering/GameWindow.cs` (`AdvanceLiveObjectRuntime` final `_particleSystem.Tick(dt)` / `_scriptRunner.Tick(...)`) | The current managers are shared presentation/runtime owners rather than per-object manager instances. R6 makes root motion, animation, object clocks, workset membership, and manager order faithful without pretending the shared tails have per-owner timing. Splitting ownership safely requires a later effect-lifetime slice. | A render fragment below retail's minimum object quantum can advance an effect while its owner waits; a catch-up frame advances an owner's root through several quanta but its effect tail only once; static default scripts/particles use render elapsed rather than `animate_static_object` elapsed/discard timing. | `CPhysicsObj::UpdateObjectInternal @ 0x005156B0`; `CPhysicsObj::animate_static_object @ 0x00513DF0`; retire by giving live/static owners incarnation-bound particle/script managers and ticking each manager in the owning object quantum |
|
| TS-51 | Particle and PhysicsScript tails advance once per render frame after the complete ordinary/static object worksets. Retail advances each object's ParticleManager and ScriptManager inside every admitted `UpdateObjectInternal` quantum; `animate_static_object` also advances that static owner's managers using its whole admitted elapsed interval. | `src/AcDream.App/Rendering/GameWindow.cs` (`AdvanceLiveObjectRuntime` final `_particleSystem.Tick(dt)` / `_scriptRunner.Tick(...)`) | The current managers are shared presentation/runtime owners rather than per-object manager instances. R6 makes root motion, animation, object clocks, workset membership, and manager order faithful without pretending the shared tails have per-owner timing. Splitting ownership safely requires a later effect-lifetime slice. | A render fragment below retail's minimum object quantum can advance an effect while its owner waits; a catch-up frame advances an owner's root through several quanta but its effect tail only once; static default scripts/particles use render elapsed rather than `animate_static_object` elapsed/discard timing. | `CPhysicsObj::UpdateObjectInternal @ 0x005156B0`; `CPhysicsObj::animate_static_object @ 0x00513DF0`; retire by giving live/static owners incarnation-bound particle/script managers and ticking each manager in the owning object quantum |
|
||||||
|
| TS-52 | The terrain shader applies retail-authored base/overlay/road `TerrainTex.TexTiling` but omits the separate Environment Detail Textures pass and its viewer-distance fade (**#226**). | `src/AcDream.App/Rendering/TerrainAtlas.cs`; `src/AcDream.App/Rendering/TerrainModernRenderer.cs`; `src/AcDream.App/Rendering/Shaders/terrain_modern.frag` | `bb5acab9` fixed the user-visible stretched/blurry regression by porting the distinct base-tiling contract. An earlier experimental detail array darkened the whole ground because its source/neutral blend contract was wrong, so it was correctly reverted rather than guessed into production. | With retail's Environment Detail Textures preference enabled, close terrain lacks the extra high-frequency modulation/fade even though authored base texture scale is correct. | `LScape::GenerateDetailSurfaces` / `SetDetailTexturing @ 0x00506B40`; `ACRender::landPolyDraw @ 0x006B6450..0x006B6525`; issue #226 |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
17
docs/bugs.md
17
docs/bugs.md
|
|
@ -1,11 +1,18 @@
|
||||||
# acdream — known bugs
|
# acdream — historical bug snapshot (deprecated)
|
||||||
|
|
||||||
Track visual, gameplay, and protocol bugs here. Close by moving to
|
> **Not an active issue tracker.** This file preserves the 2026-04-14 snapshot
|
||||||
the "Fixed" section with the commit hash that resolved it.
|
> for archaeology. Several “open” entries below were superseded, narrowed, or
|
||||||
|
> fixed by later collision/rendering work. Do not update status here and do not
|
||||||
|
> use these BUG numbers for new work. The canonical tactical ledger is
|
||||||
|
> [`ISSUES.md`](ISSUES.md); current program navigation is in
|
||||||
|
> [`README.md`](README.md).
|
||||||
|
|
||||||
|
The text below is intentionally retained as historical evidence of what was
|
||||||
|
believed at the time.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Open
|
## Historical open snapshot (not current)
|
||||||
|
|
||||||
### BUG-001: Wrong cloth textures on characters
|
### BUG-001: Wrong cloth textures on characters
|
||||||
- **Observed:** 2026-04-13
|
- **Observed:** 2026-04-13
|
||||||
|
|
@ -53,7 +60,7 @@ the "Fixed" section with the commit hash that resolved it.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Fixed
|
## Historical fixed snapshot
|
||||||
|
|
||||||
### BUG-002: Jump not visible from retail client
|
### BUG-002: Jump not visible from retail client
|
||||||
- **Fixed:** 5634e71 — Jump packet (opcode 0xF61B) now sent to server.
|
- **Fixed:** 5634e71 — Jump packet (opcode 0xF61B) now sent to server.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# acdream — strategic roadmap
|
# acdream — strategic roadmap
|
||||||
|
|
||||||
**Status:** Living document. Updated 2026-07-20. **M3 active; automated implementation complete, visual gates pending.** M2's connected demo loop is complete. M3 now has the retail cast-intent/component/target lifecycle, exact live enchantment wire state, scoped Magic input, retained spell bar, spellbook, component book, positive/negative effects panels with authored rows and selected-spell details, the complete seven-control gameplay indicator strip and its Character Information/Link/Vitae detail pages, and shared `gmPanelUI` geometry/switching over the Step 9 projectile/PhysicsScript/particle/portal foundation. The remaining M3 work is the connected single-client magic-UI/casting gate and final two-client portal-out/materialization observer gate.
|
**Status:** Living document. Updated 2026-07-20. **M3 active; automated implementation and connected single-client magic/portal gates complete.** M2's connected demo loop is complete. M3 now has the retail cast-intent/component/target lifecycle, exact live enchantment wire state, scoped Magic input, retained spell bar, spellbook, component book, positive/negative effects panels with authored rows and selected-spell details, the complete seven-control gameplay indicator strip and its Character Information/Link/Vitae detail pages, and shared `gmPanelUI` geometry/switching over the Step 9 projectile/PhysicsScript/particle/portal foundation. The next gate is a local visual rebaseline of the new R6 object-frame path; the final M3 requirement is the two-client portal-out/materialization observer gate. Issue #225's lifestone/particle alpha comparison is a separate rendering visual gate.
|
||||||
**Purpose:** One source of truth for where the project is and where it's going. Every observed defect or missing feature has a named phase that owns it; when something looks wrong in-game, look here to find the phase that'll address it. Implementation details live in per-phase specs under `docs/superpowers/specs/`, not in this file.
|
**Purpose:** One source of truth for where the project is and where it's going. Every observed defect or missing feature has a named phase that owns it; when something looks wrong in-game, look here to find the phase that'll address it. Implementation details live in per-phase specs under `docs/superpowers/specs/`, not in this file.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -30,9 +30,13 @@ active enchantment, then recall through the DAT-driven portal presentation.
|
||||||
Connected-gate
|
Connected-gate
|
||||||
correction now also pins type-12 spellbook tabs, retail zero text margins,
|
correction now also pins type-12 spellbook tabs, retail zero text margins,
|
||||||
and `PassToChildren` Closed/Open chrome through real-DAT fixtures.
|
and `PassToChildren` Closed/Open chrome through real-DAT fixtures.
|
||||||
3. **Pending user visual gate:** connected projectile/self-buff casts plus the
|
3. **Done (connected user gates):** projectile/self-buff casts, protection
|
||||||
complete retained magic UI interaction checklist.
|
effects, spellbook/component-book filtering and deletion, favorite spell
|
||||||
4. **Pending user visual gate:** two-client portal-out/materialization observer
|
bar interaction, recall, portal-space presentation, and retained indicator
|
||||||
|
pages.
|
||||||
|
4. **Pending local visual gate:** locomotion, collision, projectile, and
|
||||||
|
teleport comparison after the R6 complete-root-Frame/object-workset cutover.
|
||||||
|
5. **Pending two-client visual gate:** portal-out/materialization observer
|
||||||
presentation before M3 closes, including #218's finished Hidden silhouette,
|
presentation before M3 closes, including #218's finished Hidden silhouette,
|
||||||
fully rendered destination reveal, and no indoor stop-time position snap.
|
fully rendered destination reveal, and no indoor stop-time position snap.
|
||||||
|
|
||||||
|
|
@ -43,10 +47,10 @@ the active slice only when they block this demo or represent a severe regression
|
||||||
|
|
||||||
## Historical program: Phase W — Unified Cell Graph (UCG)
|
## Historical program: Phase W — Unified Cell Graph (UCG)
|
||||||
|
|
||||||
**[SUPERSEDED — G.3 dungeon work shipped; M1.5 next step = #138 round-trip
|
**[SUPERSEDED — G.3 shipped and M1.5 landed after the #138 round-trip gate.
|
||||||
gate + #145-residual. See the shipped table + `docs/plans/2026-05-12-milestones.md`
|
Issue #153 is a separate far-teleport edge residual. See the shipped table +
|
||||||
M1.5 section for current status. This section's W1/W2a history below is kept
|
`docs/plans/2026-05-12-milestones.md` M1.5 section for current status. This
|
||||||
for record.]**
|
section's W1/W2a history below is kept for record.]**
|
||||||
|
|
||||||
**Pivot (2026-06-02).** The render-pipeline reset stalled because the indoor "world from
|
**Pivot (2026-06-02).** The render-pipeline reset stalled because the indoor "world from
|
||||||
below" is a cell-**membership** disagreement between the render-side `CellVisibility` and
|
below" is a cell-**membership** disagreement between the render-side `CellVisibility` and
|
||||||
|
|
@ -606,7 +610,7 @@ Research: R9 + R12 + R13.
|
||||||
- **✓ SHIPPED — G.1 — Sky + weather + day-night.** Deterministic client-side from Portal Year time. Sky dome geometry + keyframe gradients + rain/snow particles. See `r12-weather-daynight.md`. Full data + visual stack shipped: Region dat loader, keyframe interp, WeatherSystem with 5-kind PDF + transitions + storm flashes, WorldSession→WorldTimeService sync via ConnectRequest+TimeSync, SkyRenderer with sky-object arcs + UV scroll, rain/snow billboard renderer, F7/F10 debug cycle keys.
|
- **✓ SHIPPED — G.1 — Sky + weather + day-night.** Deterministic client-side from Portal Year time. Sky dome geometry + keyframe gradients + rain/snow particles. See `r12-weather-daynight.md`. Full data + visual stack shipped: Region dat loader, keyframe interp, WeatherSystem with 5-kind PDF + transitions + storm flashes, WorldSession→WorldTimeService sync via ConnectRequest+TimeSync, SkyRenderer with sky-object arcs + UV scroll, rain/snow billboard renderer, F7/F10 debug cycle keys.
|
||||||
- **✓ SHIPPED — G.2 — Dynamic lighting.** 8-light D3D-style fixed pipeline. Hard-cutoff at Range, no attenuation inside. Cell ambient. Shader UBO per frame. See `r13-dynamic-lighting.md`. SceneLightingUbo std140 at binding=1 feeds terrain + mesh + mesh_instanced + sky shaders. LightingHookSink auto-registers Setup.Lights at entity stream-in, flips IsLit on SetLightHook, unregisters on landblock unload.
|
- **✓ SHIPPED — G.2 — Dynamic lighting.** 8-light D3D-style fixed pipeline. Hard-cutoff at Range, no attenuation inside. Cell ambient. Shader UBO per frame. See `r13-dynamic-lighting.md`. SceneLightingUbo std140 at binding=1 feeds terrain + mesh + mesh_instanced + sky shaders. LightingHookSink auto-registers Setup.Lights at entity stream-in, flips IsLit on SetLightHook, unregisters on landblock unload.
|
||||||
- **Indoor portal-based cell tracking (follow-up to Indoor walking Phase 1 / issue #87).** Replace `PhysicsDataCache.TryFindContainingCell` AABB containment with retail's `CObjMaint::HandleObjectEnterCell` portal traversal. When the player crosses a cell portal boundary, `CellId` propagates through the `CEnvCell` portal connectivity graph. Prerequisite for wall collision from outside (#85) and the remaining #84 threshold symptom. PDB symbols and `acclient.h` `CCellStructure` refs are in place (see #87). **Unblocks G.3.**
|
- **Indoor portal-based cell tracking (follow-up to Indoor walking Phase 1 / issue #87).** Replace `PhysicsDataCache.TryFindContainingCell` AABB containment with retail's `CObjMaint::HandleObjectEnterCell` portal traversal. When the player crosses a cell portal boundary, `CellId` propagates through the `CEnvCell` portal connectivity graph. Prerequisite for wall collision from outside (#85) and the remaining #84 threshold symptom. PDB symbols and `acclient.h` `CCellStructure` refs are in place (see #87). **Unblocks G.3.**
|
||||||
- **✓ SHIPPED — G.3 — Dungeon streaming + portal space.** `EnvCellStreamer`, portal-visibility BFS, `PlayerTeleport (0xF751)` handling with post-transition `LoginComplete`, and the retail DAT-authored portal-space CreatureMode viewport (Setup `0x02000306`, animation `0x030005AC`, exact camera/light/timing/view-plane transitions, forward-axis roll, direct portal→world viewport switch, projection warp, destination viewer reset, object/physics-before-network frame barrier, pre-network input movement/jump output, post-inbound AutonomousPosition, non-advancing spatial reconciliation, and retail `set_hidden` PartArray timeline teardown on both Hidden and UnHide; `/ls` and spell-recall corrective visual gates passed 2026-07-16, with non-blocking visual polish deferred). Dungeons render, stream, teleport-in, collide, light, and their doors work — see the shipped-table rows (G.3, G.3a, #137 collision, A7.L1 lighting) below and the M1.5 section of `docs/plans/2026-05-12-milestones.md` for current gate status (one recorded end-to-end dungeon round-trip user gate outstanding; live residual = far-town teleport-OUT arrival cascade, #145-residual REOPENED). See `r09-dungeon-portal-space.md` and `docs/research/2026-07-15-retail-portal-space-pseudocode.md`.
|
- **✓ SHIPPED — G.3 — Dungeon streaming + portal space.** `EnvCellStreamer`, portal-visibility BFS, `PlayerTeleport (0xF751)` handling with post-transition `LoginComplete`, and the retail DAT-authored portal-space CreatureMode viewport (Setup `0x02000306`, animation `0x030005AC`, exact camera/light/timing/view-plane transitions, forward-axis roll, direct portal→world viewport switch, projection warp, destination viewer reset, object/physics-before-network frame barrier, pre-network input movement/jump output, post-inbound AutonomousPosition, non-advancing spatial reconciliation, and retail `set_hidden` PartArray timeline teardown on both Hidden and UnHide; `/ls` and spell-recall corrective visual gates passed 2026-07-16, with non-blocking visual polish deferred). Dungeons render, stream, teleport, collide, light, and their doors work; the final end-to-end dungeon round-trip gate passed 2026-07-10. See the shipped-table rows (G.3, G.3a, #137 collision, A7.L1 lighting) and the M1.5 section of `docs/plans/2026-05-12-milestones.md`. The far-town unstreamed-edge arrival residual is tracked separately as #153. See `r09-dungeon-portal-space.md` and `docs/research/2026-07-15-retail-portal-space-pseudocode.md`.
|
||||||
|
|
||||||
**Acceptance:** walk outside at dusk, see the sky gradient + sun moving; enter a torch-lit dungeon via portal; leave back to daylight.
|
**Acceptance:** walk outside at dusk, see the sky gradient + sun moving; enter a torch-lit dungeon via portal; leave back to daylight.
|
||||||
|
|
||||||
|
|
@ -647,7 +651,7 @@ the way retail + holtburger expect.
|
||||||
- Attacking a creature produces "You hit Drudge for 12 slashing damage (87%)" lines in chat.
|
- Attacking a creature produces "You hit Drudge for 12 slashing damage (87%)" lines in chat.
|
||||||
- Accented character names round-trip through the wire correctly (CP1252).
|
- Accented character names round-trip through the wire correctly (CP1252).
|
||||||
|
|
||||||
**Memory crib:** `memory/project_chat_pipeline.md`.
|
**Memory crib:** `claude-memory/project_chat_pipeline.md`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -704,7 +708,7 @@ with retail's MMB-hold mouse-look.
|
||||||
dormant — light up in Phase L when `CombatState.CurrentMode` is
|
dormant — light up in Phase L when `CombatState.CurrentMode` is
|
||||||
wired (issue #L.3).
|
wired (issue #L.3).
|
||||||
|
|
||||||
**Memory crib:** `memory/project_input_pipeline.md`.
|
**Memory crib:** `claude-memory/project_input_pipeline.md`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -915,8 +919,9 @@ diagnostic scaffolding, not yet the final collision system.
|
||||||
InterpolationManager into the owned
|
InterpolationManager into the owned
|
||||||
PositionManager facade remains the final R6 ownership cleanup.
|
PositionManager facade remains the final R6 ownership cleanup.
|
||||||
Final 2026-07-20 gate: three independent retail/architecture/adversarial
|
Final 2026-07-20 gate: three independent retail/architecture/adversarial
|
||||||
re-reviews are clean; Release build is warning-free; the repository suite is
|
re-reviews are clean; Release builds successfully with 17 known test-project
|
||||||
6,452 passed / 5 skipped. The unattended connected Release rebaseline also
|
warnings tracked by #228; the repository suite is 6,452 passed / 5 skipped.
|
||||||
|
The unattended connected Release rebaseline also
|
||||||
passes: seven portal materializations across Caul, Sawato, Rynthid,
|
passes: seven portal materializations across Caul, Sawato, Rynthid,
|
||||||
Aerlinthe, Holtburg, and same-location revisits; production-dispatcher turn,
|
Aerlinthe, Holtburg, and same-location revisits; production-dispatcher turn,
|
||||||
forward, charged-jump, and combat inputs; outbound movement evidence;
|
forward, charged-jump, and combat inputs; outbound movement evidence;
|
||||||
|
|
@ -1441,8 +1446,8 @@ OpenGL ceiling; revisit macOS only if a supported graphics backend is chosen.
|
||||||
|
|
||||||
## Cross-cutting work tracked in parallel
|
## Cross-cutting work tracked in parallel
|
||||||
|
|
||||||
- **Test coverage.** Each phase lands with unit + integration tests in `tests/`. Current count: 98 Core + 96 Core.Net = 194. Keep the ratio as new phases land.
|
- **Test coverage.** Each phase lands with layer-matched unit and integration tests in `tests/`. Current Release baseline: 6,452 passed / 5 intentional skips (2026-07-20).
|
||||||
- **Memory files.** Project state under `memory/project_phase_*_state.md` is updated when a phase ships. `MEMORY.md` is the index.
|
- **Memory files.** Live subsystem state and digests are indexed by `claude-memory/MEMORY.md`; stable engineering references remain under `memory/`. Canonical program status stays in milestones/roadmap/issues.
|
||||||
- **`CLAUDE.md` discipline.** Check all four references (ACE, ACViewer, WorldBuilder, Chorizite) before committing to an approach. WorldBuilder is the closest stack match and should be checked first.
|
- **`CLAUDE.md` discipline.** Check all four references (ACE, ACViewer, WorldBuilder, Chorizite) before committing to an approach. WorldBuilder is the closest stack match and should be checked first.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -1470,8 +1475,8 @@ OpenGL ceiling; revisit macOS only if a supported graphics backend is chosen.
|
||||||
| Character clothing missing / wrong | **5 FIXED** ✓ |
|
| Character clothing missing / wrong | **5 FIXED** ✓ |
|
||||||
| Statue wrong color / wrong scale | **5 FIXED** ✓ |
|
| Statue wrong color / wrong scale | **5 FIXED** ✓ |
|
||||||
| Holtburg sign half-buried | **5 FIXED** ✓ |
|
| Holtburg sign half-buried | **5 FIXED** ✓ |
|
||||||
| Can't walk past the loaded 3×3 window | **A.1 FIXED** ✓ (5×5 default, `ACDREAM_STREAM_RADIUS` to tune) |
|
| Can't walk past the loaded 3×3 window | **A.1/A.5 FIXED** ✓ (two-tier streaming, near 4 / far 12 by default; legacy override remains) |
|
||||||
| Frame hitch crossing landblock boundary | **Phase A.3** (synchronous loader for now; async returns when DatCollection is thread-safe) |
|
| Frame hitch crossing landblock boundary | **A.3/A.5 async streaming SHIPPED**; residual content-load hitches are measured under Modern Pipeline MP1c |
|
||||||
| Walking around doesn't move me on the server | **Phase B.2/B.3 FIXED** ✓ for coarse server movement; fine retail collision parity is **Phase L.2** |
|
| Walking around doesn't move me on the server | **Phase B.2/B.3 FIXED** ✓ for coarse server movement; fine retail collision parity is **Phase L.2** |
|
||||||
| Packet loss / out-of-order UDP causes stale or missing world updates | **Phase M.3** |
|
| Packet loss / out-of-order UDP causes stale or missing world updates | **Phase M.3** |
|
||||||
| Server asks for retransmit and client doesn't resend cached packets | **Phase M.3** |
|
| Server asks for retransmit and client doesn't resend cached packets | **Phase M.3** |
|
||||||
|
|
@ -1482,22 +1487,22 @@ OpenGL ceiling; revisit macOS only if a supported graphics backend is chosen.
|
||||||
| Sliding along buildings / walls feels wrong | **Phase L.2c + L.2d** |
|
| Sliding along buildings / walls feels wrong | **Phase L.2c + L.2d** |
|
||||||
| Roof edge / cliff / precipice blocks or slides wrong | **Phase L.2c** |
|
| Roof edge / cliff / precipice blocks or slides wrong | **Phase L.2c** |
|
||||||
| Crossing outdoor cell seams reports the wrong cell | **Phase L.2e** |
|
| Crossing outdoor cell seams reports the wrong cell | **Phase L.2e** |
|
||||||
| Can't talk to NPCs | **Phase H.3** (emote scripts + dialogs) |
|
| Can't talk to NPCs | Basic select/use/give interaction works; full emote conversation/dialog systems remain **Phase H.3** |
|
||||||
| Can't open a door | **Phase F** (object-use action) |
|
| Can't open a door | **FIXED** ✓ — object-use, animation, fading hooks, and collision transitions shipped |
|
||||||
| Portals render as a rotating black disk | **Phase E.3** (particle system) |
|
| Portals render as a rotating black disk | **FIXED** ✓ — DAT particles/effects and portal-space presentation shipped |
|
||||||
| Chimneys have no smoke | **Phase E.3** |
|
| Chimneys have no smoke | **Phase E.3 SHIPPED** ✓ |
|
||||||
| Houses have no fireplace fire | **Phase E.3** |
|
| Houses have no fireplace fire | **Phase E.3/G.2 SHIPPED** ✓ |
|
||||||
| No fireplace / torch lighting | **Phase G.2** (shipped; Setup.Lights auto-register, 8-light cap with hard-cutoff) |
|
| No fireplace / torch lighting | **Phase G.2** (shipped; Setup.Lights auto-register, 8-light cap with hard-cutoff) |
|
||||||
| Skin/hair color slightly off | **Phase C.3** |
|
| Skin/hair color slightly off | **Phase C.3** |
|
||||||
| No chat window | **Phase H.1 / I.1-I.7 FIXED** ✓ |
|
| No chat window | **Phase H.1 / I.1-I.7 FIXED** ✓ |
|
||||||
| Chat? You can finally type and send messages | **I.4 FIXED** ✓ (shipped 2026-04-25) |
|
| Chat? You can finally type and send messages | **I.4 FIXED** ✓ (shipped 2026-04-25) |
|
||||||
| Combat doesn't show in the chat log | **I.7 FIXED** ✓ |
|
| Combat doesn't show in the chat log | **I.7 FIXED** ✓ |
|
||||||
| Accented character names show as `?` or garbled | **I.5 FIXED** ✓ (Windows-1252 codec) |
|
| Accented character names show as `?` or garbled | **I.5 FIXED** ✓ (Windows-1252 codec) |
|
||||||
| No sound | **Phase E.2** |
|
| No sound | **Phase E.2 SHIPPED** ✓ (remaining unsupported codecs are TS-9) |
|
||||||
| Dungeons / foundry interior missing | **Phase G.3 — SHIPPED** (render/stream/teleport-in/collide/light/doors all closed; M1.5 next step = #138 round-trip gate + #145-residual) |
|
| Dungeons / foundry interior missing | **Phase G.3 — SHIPPED + M1.5 gate passed 2026-07-10** (render/stream/teleport/collision/light/doors closed; separate far-teleport edge residual = #153) |
|
||||||
| Can't fight monsters | **Phase F.3** (combat math + damage) |
|
| Can't fight monsters | **M2 LANDED 2026-07-15** ✓ — melee/missile, death, loot, inventory loop user-gated |
|
||||||
| Can't cast spells | **Phase F.4** |
|
| Can't cast spells | **M3 connected single-client casting/effects gate passed** ✓; final two-client portal observer gate remains |
|
||||||
| No inventory panel | **Phase F.2 + F.5** |
|
| No inventory panel | **D.5 / M2 SHIPPED + user-gated** ✓ — bags, stacks, paperdoll, equipment, drag/drop, loot |
|
||||||
| No character creation — must use ACE admin | **Phase H.4** |
|
| No character creation — must use ACE admin | **Phase H.4** |
|
||||||
| Sky is a flat color | **Phase G.1** (shipped; F7 cycles time, F10 cycles weather) |
|
| Sky is a flat color | **Phase G.1** (shipped; F7 cycles time, F10 cycles weather) |
|
||||||
| Can't join allegiance | **Phase H.2** |
|
| Can't join allegiance | **Phase H.2** |
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,14 @@ new R6 object-update cutover has passed its unattended connected input/portal/
|
||||||
performance rebaseline; its locomotion/collision/projectile/teleport visual
|
performance rebaseline; its locomotion/collision/projectile/teleport visual
|
||||||
gate remains for the next local viewing session before that observer gate.
|
gate remains for the next local viewing session before that observer gate.
|
||||||
Carried:
|
Carried:
|
||||||
#145-residual, #116 slide-response, the remaining R6 ownership cleanup plus
|
#153 far-teleport residual, #116 slide-response, the remaining R6 ownership cleanup plus
|
||||||
registered TS-50/TS-51 timing residuals (the complete-root-Frame/object-workset
|
registered TS-50/TS-51 timing residuals (the complete-root-Frame/object-workset
|
||||||
cutover is automated-test complete 2026-07-20; three independent re-reviews are
|
cutover is automated-test complete 2026-07-20; three independent re-reviews are
|
||||||
clean, Release builds with zero warnings, and 6,452 tests pass / 5 skip), and
|
clean, Release builds with 17 known test-project warnings tracked by #228, and
|
||||||
Track MP0.
|
6,452 tests pass / 5 skip), and
|
||||||
|
the deferred Modern Pipeline track (MP1b+). The separate #225 shared-alpha
|
||||||
|
implementation has passed connected lifetime/performance gates and awaits only
|
||||||
|
its lifestone/particle visual comparison.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -219,7 +222,7 @@ lighting (#79/#93/#80). The indoor-physics workarounds (#90 stickiness +
|
||||||
`TryFindIndoorWalkablePlane` synthesis) were removed by A6.P4 — no duct-tape
|
`TryFindIndoorWalkablePlane` synthesis) were removed by A6.P4 — no duct-tape
|
||||||
left. **Explicit caveats carried forward (NOT M1.5 blockers — tracked as
|
left. **Explicit caveats carried forward (NOT M1.5 blockers — tracked as
|
||||||
their own follow-ups):** the far-town teleport-OUT arrival cascade
|
their own follow-ups):** the far-town teleport-OUT arrival cascade
|
||||||
(#145-residual, REOPENED — a narrow far-teleport streaming edge case,
|
(#153, REOPENED — a narrow far-teleport streaming edge case,
|
||||||
capture-harness-first) and #116 slide-response feel-debt. Next: **M2 —
|
capture-harness-first) and #116 slide-response feel-debt. Next: **M2 —
|
||||||
"Kill a drudge."**
|
"Kill a drudge."**
|
||||||
|
|
||||||
|
|
@ -238,10 +241,10 @@ multi-landblock dungeon LOD + `PlayerTeleport` handling), and it has since
|
||||||
blowup (RESOLVED), dungeon doors (#187/#188), and A7 dungeon lighting
|
blowup (RESOLVED), dungeon doors (#187/#188), and A7 dungeon lighting
|
||||||
(#79/#93/#80/#154, all CLOSED). M1.5's dungeon-demo scenario (enter via
|
(#79/#93/#80/#154, all CLOSED). M1.5's dungeon-demo scenario (enter via
|
||||||
portal, navigate 3-5 rooms, walls block, smooth transitions) is
|
portal, navigate 3-5 rooms, walls block, smooth transitions) is
|
||||||
functionally met; M1.5 now awaits ONE recorded end-to-end dungeon
|
functionally met. The final end-to-end dungeon round-trip gate passed on
|
||||||
round-trip user gate. The sole remaining live-code residual is the
|
2026-07-10 and landed M1.5. The separate live-code residual is the far-town
|
||||||
far-town teleport-OUT arrival cascade (**#145-residual, REOPENED** — see
|
teleport-OUT arrival cascade (**#153, REOPENED** — see below); it is not a
|
||||||
below).
|
dungeon-round-trip blocker.
|
||||||
|
|
||||||
**Building/cellar demo — DONE + user-gated.** The indoor world reads as
|
**Building/cellar demo — DONE + user-gated.** The indoor world reads as
|
||||||
solid. Across the
|
solid. Across the
|
||||||
|
|
@ -311,10 +314,9 @@ shipped: teleport-into-dungeon (G.3a hold-until-hydrate FSM,
|
||||||
#137 (`0efa7ed2`); the #95 portal-graph visibility blowup RESOLVED
|
#137 (`0efa7ed2`); the #95 portal-graph visibility blowup RESOLVED
|
||||||
(9.1M→~39k instances, `a40c38e8`); dungeon doors shipped (#187
|
(9.1M→~39k instances, `a40c38e8`); dungeon doors shipped (#187
|
||||||
`e2e285b8`, #188 `3284dd0a`); A7 dungeon lighting closed
|
`e2e285b8`, #188 `3284dd0a`); A7 dungeon lighting closed
|
||||||
(#79/#93/#80/#154, `44cced71`/`d275ed55`/`9ebb2060`). Remaining: one
|
(#79/#93/#80/#154, `44cced71`/`d275ed55`/`9ebb2060`). The recorded end-to-end
|
||||||
recorded end-to-end dungeon round-trip user gate, plus the far-town
|
dungeon round-trip passed on 2026-07-10. The far-town teleport-OUT arrival
|
||||||
teleport-OUT arrival cascade residual (**#145-residual, REOPENED** —
|
cascade residual remains separate (**#153, REOPENED** — capture-harness-first).
|
||||||
capture-harness-first).
|
|
||||||
|
|
||||||
**2026-07-15 portal presentation completion (single-client visual gate passed
|
**2026-07-15 portal presentation completion (single-client visual gate passed
|
||||||
2026-07-16; non-blocking polish deferred).** The
|
2026-07-16; non-blocking polish deferred).** The
|
||||||
|
|
@ -482,7 +484,7 @@ the A6 physics/membership family + A6.P4 per-cell shadow architecture, A7
|
||||||
indoor/dungeon lighting, and **full Phase G.3 dungeon support** (streaming
|
indoor/dungeon lighting, and **full Phase G.3 dungeon support** (streaming
|
||||||
collapse/expand, teleport in/out, dungeon collision/lighting/doors). No
|
collapse/expand, teleport in/out, dungeon collision/lighting/doors). No
|
||||||
rework until M7 polish. Exempt from the freeze as still-open bugs (rule 2's
|
rework until M7 polish. Exempt from the freeze as still-open bugs (rule 2's
|
||||||
"actively broken" clause): #145-residual (far-town teleport-OUT cascade) and
|
"actively broken" clause): #153 (far-town teleport-OUT cascade) and
|
||||||
#116 (slide-response) — these are tracked follow-ups, not frozen work.
|
#116 (slide-response) — these are tracked follow-ups, not frozen work.
|
||||||
|
|
||||||
**Estimated timeline:** 3–5 weeks calendar (17–26 days focused work). Bigger
|
**Estimated timeline:** 3–5 weeks calendar (17–26 days focused work). Bigger
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue