acdream/README.md
Erik 6c3bd4ce4b 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>
2026-07-20 13:00:41 +02:00

196 lines
8.6 KiB
Markdown

# acdream
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,
plugin-friendly architecture. The code is modern; the behaviour is retail.
**Status:** playable pre-alpha; M3 ("Cast a spell") is active. The connected
client supports the complete M2 combat/loot/inventory loop plus retained
spellbook, component-book, favorite-spell, enchantment, portal-space, radar,
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
- **Language:** C# .NET 10
- **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
- **Dat parsing:** [Chorizite.DatReaderWriter](https://github.com/Chorizite/DatReaderWriter)
- **Networking:** Custom UDP + ISAAC cipher + game-message layer, wire-compatible
with ACEmulator server
## What works today
- ACE login, character selection, world entry, chat, client commands, and
graceful logout.
- Outdoor, building, cellar, and dungeon streaming with portal-space travel,
terrain/scenery/EnvCell rendering, collision, lighting, sky, fog, audio, and
day/night presentation.
- Local and observed player/NPC/monster movement, animation, selection, radar,
combat stances, melee and missile presentation, death, corpses, chests, and
looting.
- Inventory bags, stack splitting, paperdoll/equipment, weapon switching,
quick bars, item use, giving items to NPCs, and server-authoritative item
movement.
- Retained retail-style gameplay UI for vitals, chat, toolbar, inventory,
character/skills, spellbook/components, helpful/harmful effects, combat and
spell bars, radar/compass, indicator pages, and confirmation dialogs.
- Spell catalog, learned/favorite spells, component preflight, connected casts,
enchantments, DAT-driven missiles/effects, recall, Hidden/UnHide, and portal
materialization presentation.
- Plugin host, shared input/command abstractions, and permanent ImGui developer
tools behind `ACDREAM_DEVTOOLS=1`.
## Active gaps
- R6's complete object-frame update path still needs the next local visual
comparison; the final M3 gate is a two-client portal-out/materialization
observer comparison.
- Issue `#225` still needs the lifestone/particle alpha-order visual check,
although its connected lifetime/performance gates pass.
- Narrow behavior debt remains in issue `#153` (an unstreamed far-teleport
edge case), issue `#116` (slide feel), and registered TS-50/TS-51 effect
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/README.md](docs/README.md) for document authority and current links.
## Building + running
**Requires:**
- .NET 10 SDK
- A retail Asheron's Call dat directory (Turbine/Microsoft property —
supply your own). Contains `client_portal.dat`, `client_cell_1.dat`,
`client_highres.dat`, `client_local_English.dat`.
- A running ACE (ACEmulator) server on `127.0.0.1:9000` (or override
via env var)
**Launch (PowerShell on Windows — bash has trouble with the apostrophe
in "Asheron's Call"):**
```powershell
$env:ACDREAM_DAT_DIR = "$env:USERPROFILE\Documents\Asheron's Call"
$env:ACDREAM_LIVE = "1"
$env:ACDREAM_TEST_HOST = "127.0.0.1"
$env:ACDREAM_TEST_PORT = "9000"
$env:ACDREAM_TEST_USER = "testaccount"
$env:ACDREAM_TEST_PASS = "testpassword"
$env:ACDREAM_RETAIL_UI = "1"
dotnet run --project src\AcDream.App\AcDream.App.csproj -c Release
```
Offline CLI dat inspector (no server needed):
```
dotnet run --project src/AcDream.Cli -- "C:\path\to\Asheron's Call"
```
## Diagnostic env vars
| Variable | Effect |
|---|---|
| `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_STREAM_RADIUS=N` | Legacy override for the configured two-tier streaming radii |
| `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_RUN_SKILL=N` / `ACDREAM_JUMP_SKILL=N` | Client-side run/jump skill (default 200) |
## Layout
```
src/
AcDream.App/ window, retained UI, rendering, audio, runtime wiring
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.UI.Abstractions/ shared UI/input ViewModels, commands, contracts
AcDream.UI.ImGui/ permanent developer-tool renderer
AcDream.Cli/ offline dat-inspector console app
AcDream.Bake/ offline content bake tooling
AcDream.Plugin.Abstractions/ plugin host interfaces
AcDream.Plugins.Smoke/ example plugin
tests/
AcDream.*.Tests/ layer-matched xUnit projects (6,452 passing,
5 intentional skips at the 2026-07-20 baseline)
tools/
RetailTimeProbe/ Win32 P/Invoke ReadProcessMemory probe of
the live retail acclient.exe — dumps
TimeOfDay + sky-lighting globals so we
can compare against acdream's state
SkyObjectInspect/ dat-inspector for Region sky objects
references/ vendored read-only reference code — ACE,
ACViewer, WorldBuilder, holtburger,
AC2D, Chorizite, DatReaderWriter.
Gitignored.
docs/
README.md documentation map + authority order
architecture/ architecture, structure, divergence, WB inventory
plans/ phase roadmaps + per-phase specs
research/ decompile-derived research, per-phase
findings, deep-dive agent reports
audit/ phase-completion audits
```
## Development workflow
All AC-specific behaviour is ported from the named retail client oracle
(`docs/research/named-retail/`). The workflow is:
1. **Grep named retail first.** Find the matching `class::method` in the
Sept 2013 named pseudo-C and headers.
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.
4. **Write pseudocode.** Translate C to readable pseudocode first.
5. **Port faithfully.** Translate line-by-line, preserving variable
names and control flow.
6. **Conformance test.** Add tests using golden values from retail.
7. **Integrate surgically.** Minimise churn in the surrounding pipeline.
Guessing at AC-specific algorithms is explicitly forbidden — see
`CLAUDE.md` for the full workflow rationale and the list of failure
modes we've paid for in the past.
## Reference repos
We cross-reference six external projects for retail behavior:
- **ACE** (ACEmulator) — authoritative server-side protocol
- **ACViewer** — MonoGame dat viewer; good for character appearance
- **WorldBuilder** — Silk.NET dat editor; matches our stack
- **Chorizite.ACProtocol** — clean-room C# protocol library
- **holtburger** — most complete non-retail client; Rust TUI, full
client-side behaviour
- **AC2D** — C++ AC-client emulator; has the real terrain split
formula and 0xF61C movement packet format
See `CLAUDE.md` for which reference is authoritative for which domain.
## Licence
Not yet chosen. All external reference code is vendored under its own
licence; see `references/*/LICENSE`. The acdream source code itself is
unreleased — not yet distributed to the public. Once the licence
choice is made it will go in a top-level `LICENSE` file.
The AC dat files and the game's intellectual property remain the
property of Microsoft / Turbine. This project does not distribute any
of those files or assets — you must supply your own retail install.