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 40f120617d feat(physics): use sloped terrain plane in FindEnvCollisions
Our previous FindEnvCollisions built a FLAT contact plane (Normal = +Z)
at the sampled terrain Z, discarding the triangle's actual slope.
Retail uses the real terrain polygon's plane (ACE Landblock.cs:125-137
find_terrain_poly → walkable.Plane) which IS sloped.

Without a true slope normal, AdjustOffset's projection of horizontal
velocity onto the plane produces no slope-aligned Z component — fine
for step-subdivision on flat ground, visibly wrong whenever the contact
plane is carried across frames (via PhysicsBody.ContactPlane persistence
from commit 93cbabb): the projection is a no-op and movement is purely
kinematic. With the real slope normal, projected motion correctly
follows the slope.

Not a user-visible bug fix by itself (DIAG LocalZ shows delta≈0 for the
local player everywhere; the "looks too high in water" issue the user
reported is actually a missing water-rendering feature, not a physics
bug). Landing it anyway because it matches retail behavior and removes
the "flat-plane-is-fine" assumption that would bite on any future
contact-plane-dependent code.

Additions:
 - TerrainSurface.SampleSurface(localX, localY) → (Z, Normal), deriving
   the plane normal analytically from the triangle's height gradient.
   Matches the same triangle SampleZ already interpolates through.
 - PhysicsEngine.SampleTerrainPlane(worldX, worldY) → System.Numerics.Plane,
   the wrapper that bridges terrain space to transition space.
 - TransitionTypes.FindEnvCollisions uses SampleTerrainPlane instead of
   synthesizing a flat plane from SampleTerrainZ.

All 717 tests green. Flat-plane case is unchanged (Normal.Z = 1 when
the triangle is level, identical to the old plane).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 19:42:20 +02:00
docs docs: mark Phase G.1+G.2 full visual stack as shipped 2026-04-19 10:54:33 +02:00
memory docs(memory): session 2026-04-19 handoff — remote motion port complete 2026-04-19 21:33:12 +02:00
src feat(physics): use sloped terrain plane in FindEnvCollisions 2026-04-21 19:42:20 +02:00
tests fix(terrain): align per-cell triangle geometry with ACE's ConstructPolygons convention 2026-04-21 13:20:59 +02:00
tools feat(core): port decompiled AC client physics — CollisionPrimitives + PhysicsBody 2026-04-12 23:54:51 +02:00
.gitignore chore: gitignore launch.log 2026-04-18 23:11: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(claude.md): add 'Running the client against the live server' section 2026-04-19 14:58:13 +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.