Modern open-source C# .NET 10 Asheron's Call client. Faithful port of retail client behaviour to Silk.NET with a plugin API.
Find a file
Erik e16f3315d2 feat(net): AppraiseInfoParser — full PropertyBundle deserializer
Closes the single biggest P0 gap from r08: the AppraiseInfo blob
carried by both IdentifyObjectResponse (0x00C9) and the initial
PlayerDescription (0x0013) is now parsed end-to-end for the six core
property tables.

Wire layer:
- AppraiseInfoParser.TryParse returns a Parsed record:
  (Guid, Flags, Success, PropertyBundle, SpellBook[]).
- IdentifyResponseFlags enum mirrors ACE's bitfield exactly.
- Header reader: u16 count + u16 numBuckets (ACE
  PackableHashTable.WriteHeader format).
- Per-table readers: IntStatsTable, Int64StatsTable, BoolStatsTable
  (u32 → bool), FloatStatsTable (f64 values), StringStatsTable
  (string16L values with 4-byte pad), DidStatsTable.
- SpellBook reader: u32 count followed by count u32 spell ids, with
  sanity cap at 4096 entries.

What's NOT yet parsed (deferred, noted in XML doc):
- ArmorProfile / CreatureProfile / WeaponProfile / HookProfile blobs
  require porting their respective Structure classes.
- Enchantment bitfields (u16 highlight + u16 color triplets).
- ArmorLevels block.

The parser is defensive: malformed / truncated tables raise
FormatException which is caught internally; the caller gets
whatever properties parsed successfully before the error.

Tests (7 new):
- Header-only (no tables).
- IntStatsTable round-trip with mixed sign values.
- BoolStatsTable (u32 ↔ bool conversion).
- StringStatsTable with padded-length strings.
- SpellBook parsing.
- Combined flags across multiple tables.
- Truncated payload → null.

Build green, 628 tests pass (up from 621).

This unlocks the Attributes / Skills / Paperdoll UI panels once their
renderers land — every property key the server sends now gets stored
on the target ItemInstance (or — for PlayerDescription — the player's
own property bag once wired).

Ref: ACE AppraiseInfo.Write (AppraiseInfo.cs:735), PackableHashTable.
Ref: r08 §4 payload for 0x00C9.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 17:22:00 +02:00
docs docs: session 2026-04-18 memory + roadmap update 2026-04-18 17:15:32 +02:00
memory docs: session 2026-04-18 memory + roadmap update 2026-04-18 17:15:32 +02:00
src feat(net): AppraiseInfoParser — full PropertyBundle deserializer 2026-04-18 17:22:00 +02:00
tests feat(net): AppraiseInfoParser — full PropertyBundle deserializer 2026-04-18 17:22:00 +02:00
tools feat(core): port decompiled AC client physics — CollisionPrimitives + PhysicsBody 2026-04-12 23:54:51 +02:00
.gitignore chore: phase 0 — skeleton + dat asset inventory 2026-04-10 09:02:56 +02:00
AcDream.slnx feat(net): AcDream.Core.Net scaffold + ISAAC keystream (Phase 4.1) 2026-04-11 14:14:28 +02:00
CLAUDE.md docs: comprehensive architecture plan for acdream 2026-04-13 14:23:50 +02:00
README.md chore: phase 0 — skeleton + dat asset inventory 2026-04-10 09:02:56 +02:00

acdream

Experimental modern open-source Asheron's Call client in C# / .NET 10.

Status: pre-alpha, not playable. Phase 0 only — dat file asset inventory.

Stack: .NET 10, Chorizite.DatReaderWriter for dat parsing. Silk.NET + Avalonia planned for rendering/UI (not yet wired up).

Requires: A retail Asheron's Call install (Turbine/Microsoft property — supply your own). Set ACDREAM_DAT_DIR environment variable to the directory containing client_portal.dat, client_cell_1.dat, client_highres.dat, and client_local_English.dat, or pass it as the first CLI argument.

Layout

  • src/AcDream.Cli/ — console app that dumps asset counts from a dat directory
  • references/ — local read-only reference material (ACE, ACViewer, WorldBuilder, DatReaderWriter, holtburger, retail AC install). Gitignored.

Run

dotnet run --project src/AcDream.Cli -- "C:\path\to\Asheron's Call"

Or set ACDREAM_DAT_DIR and run without args.