Modern open-source C# .NET 10 Asheron's Call client. Faithful port of retail client behaviour to Silk.NET with a plugin API.
When the server broadcasts a mid-run UpdateMotion with a different ForwardSpeed (e.g. the player's RunRate changes due to stamina / skill update), acdream must NOT restart the cycle — that would reset the footstep cursor and look like a visible twitch. Retail handles this via Sequence.multiply_cyclic_animation_framerate (ACE references/ACE/Source/ACE.Server/Physics/Animation/Sequence.cs L277-L287), which walks the cyclic tail of the queue and scales each node's framerate by newSpeed / oldSpeed. MotionTable.change_cycle_speed (MotionTable.cs L372-L379) is the caller from the same-motion path in GetObjectSequence (L132-L139). This commit: 1. Adds AnimNode.MultiplyFramerate(factor) — scales a single node's framerate. Retail also swapped StartFrame↔EndFrame for negative factors; acdream keeps StartFrame ≤ EndFrame as an invariant and encodes direction via Framerate sign (see existing comment in LoadAnimNode), so we only scale. Valid because callers only ever pass positive factors from UpdateMotion ForwardSpeed. 2. Adds AnimationSequencer.MultiplyCyclicFramerate(factor) — walks _firstCyclic through the tail and calls node.MultiplyFramerate(factor). Also scales each node's Velocity and Omega by the same factor so CurrentVelocity / CurrentOmega stay aligned with playback — matches ACE's subtract_motion + combine_motion pair in change_cycle_speed. 3. Adds AnimationSequencer.CurrentSpeedMod public property — starts at 1.0, updated by SetCycle on both restart and mid-cycle rescale. 4. Adds a speed-change fast-path to SetCycle: when the (style, motion) pair matches the current cycle and signs agree, MultiplyCyclicFramerate(newSpeed/oldSpeed) is called instead of rebuilding the queue — the cursor stays where it is and the animation continues at the new rate. 5. Wires InterpretedMotionState.ForwardSpeed from UpdateMotion through to SetCycle in OnLiveMotionUpdated. ACE omits the ForwardSpeed flag when speed == 1.0 (InterpretedMotionState.cs:101-103), so we default missing/zero values to 1.0. Tests: 4 new sequencer tests covering MultiplyCyclicFramerate, cursor preservation across speed changes, the same-motion-different-speed fast-path, and the same-motion-same-speed no-op guard. 632 tests green (was 628). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| docs | ||
| memory | ||
| src | ||
| tests | ||
| tools | ||
| .gitignore | ||
| AcDream.slnx | ||
| CLAUDE.md | ||
| README.md | ||
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 directoryreferences/— 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.