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 a28a69af71 feat(lighting): Phase G.2 LightSource + LightManager (data + selection)
Retail-faithful 8-light cap selection (r13 §12) — the fixed-function
D3D pipeline's "hardware lights" constraint carried over to modern GL
via UBO-per-draw.

Core layer (AcDream.Core/Lighting):
- LightSource: Kind (Directional/Point/Spot), WorldPosition,
  WorldForward, ColorLinear, Intensity, Range (hard cutoff),
  ConeAngle (spot), OwnerId (entity attachment), IsLit latch.
- CellAmbientState: (AmbientColor, SunColor, SunDirection) sourced from
  R12 sky state for outdoor cells or EnvCell dat for indoor cells.
- LightManager: Register/Unregister/UnregisterByOwner/Clear + Tick
  per frame. Selection matches r13 §12.2 exactly:
  1) Skip unlit + directional.
  2) Compute DistSq for every registered point/spot.
  3) Drop lights outside Range² * 1.1 (10% slack prevents pop).
  4) Sort by DistSq ascending; take up to 7 (slot 0 reserved for Sun).
  5) Slot 0 = Sun (Directional); slots 1..7 = nearest in-range.

Tests (9 new):
- Register/Unregister/Idempotent register.
- Tick picks top 8 by distance when 12 registered.
- Range filter drops far lights (5.0 range, 20m away).
- Range slack includes lights at exactly the boundary.
- Sun reserved at slot 0 across ticks.
- Unlit lights excluded; toggling IsLit brings them back.
- UnregisterByOwner removes all owner's lights.
- DistSq updated each tick for viewer movement.

Build green, 596 tests pass (up from 587).

Next: wire LightManager into the shader UBO pass (G.2 second commit)
and feed Sun from WorldTimeService.CurrentSunDirection per frame.

Ref: r13 §10.2 (D3D attenuation = none inside Range + hard cutoff),
§12 (full port plan).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 17:09:51 +02:00
docs docs+feat: 13 retail-AC deep-dives (R1-R13) + C# port scaffolds + roadmap E-H 2026-04-18 10:32:44 +02:00
memory memory: extend 2026-04-17 session handoff with evening bug-bash work 2026-04-18 15:55:31 +02:00
src feat(lighting): Phase G.2 LightSource + LightManager (data + selection) 2026-04-18 17:09:51 +02:00
tests feat(lighting): Phase G.2 LightSource + LightManager (data + selection) 2026-04-18 17:09:51 +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.