Commit graph

5 commits

Author SHA1 Message Date
Erik
c8782c9365 phase(N.0): wire up WorldBuilder fork as submodule + project refs
Phase N.0 setup for the WorldBuilder migration. Replaces the local
read-only clone of Chorizite/WorldBuilder at references/WorldBuilder/
with a git submodule pointing at our fork
(github.com/eriknihlen/WorldBuilder.git, branch acdream).

Changes:
- .gitignore: exempt references/WorldBuilder from the references/
  ignore rule so the submodule can be tracked.
- .gitmodules (new): submodule entry tracking acdream branch on fork.
- src/AcDream.Core/AcDream.Core.csproj: add ProjectReference to
  WorldBuilder.Shared and Chorizite.OpenGLSDLBackend so we can call
  TerrainUtils, SceneryHelpers, etc. from our Core code.

Build green, all 93 scenery/terrain tests pass. The 8 pre-existing
DispatcherToMovement test failures are unrelated and exist on main.

Notes for users picking up this branch on main:
- After merge, the existing local clone at references/WorldBuilder
  may need to be removed before `git submodule update --init` will
  populate the submodule.
- Working on the fork happens via `cd references/WorldBuilder && git
  checkout acdream && <changes> && git push`. To pull upstream
  Chorizite/WorldBuilder fixes: `git remote add upstream
  https://github.com/Chorizite/WorldBuilder.git && git fetch upstream
  && git merge upstream/master`.

Next: Phase N.1 — replace SceneryGenerator algorithm calls with
WB's SceneryHelpers + TerrainUtils.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 08:51:49 +02:00
Erik
927636ec77 fix(physics): InterpolationManager review findings (L.3.1 Task 1 polish)
Addresses code-quality review findings on commit f43f168:

C-1: Stall detection re-implemented to match retail (acclient lines
353071-353275). Tracks _progressQuantum (sum of step values per window)
+ _distanceAtWindowStart (set at window start). Primary check:
cumulative_progress < MIN_DISTANCE_TO_REACH_POSITION (0.20m absolute).
Secondary check: cumulative_progress / _progressQuantum < 0.30.
Either failing increments fail counter; blip-to-tail at >3 consecutive
fails (already correct).

C-2: Renamed StallFailCountForBlip -> StallFailCountThreshold with
clearer XML doc explaining the > vs >= semantics (blip fires when fail
count EXCEEDS the threshold, i.e. on the 4th consecutive failed window).

I-1: _haveBaselineDistance sentinel prevents first-window false
positive that was triggering spurious fails on every new motion sequence
(old code defaulted _distanceAtWindowStart to 0, making cumulative
progress always negative on frame 5).

I-3: dt <= 0 || NaN guard at AdjustOffset entry prevents NaN
propagation into PhysicsBody.Position.

I-4: Internal field renames for clarity:
  _failFrameCounter        -> _framesSinceLastStallCheck
  _failDistanceLastCheck   -> merged into _distanceAtWindowStart

I-5: Added internal Count property + InternalsVisibleTo (via
AssemblyAttribute in .csproj) so Enqueue_DropsOldestWhenAtCap20
actually verifies cap enforcement. Added assertion that head is the
second-enqueued position after overflow.

3 new tests (AdjustOffset_FirstWindow_DoesNotFalseFail,
AdjustOffset_DtZeroOrNegative_ReturnsZero,
Enqueue_AtCap20_HeadIsSecondOriginal), 16 total. All green.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-02 19:10:23 +02:00
Erik
d3165f99d7 feat(vfx): Phase E.3 particle system + hook wiring + registry
Full runtime particle pipeline consuming Phase E.1's animation hooks.
13 motion integrators, per-emitter particle pools with overwrite-oldest
eviction, colour / scale / alpha interpolation over life, and a
ParticleHookSink routing CreateParticle / DestroyParticle / StopParticle /
CreateBlockingParticle hooks from the animation-hook router.

Core layer:
- ParticleSystem: handle-based emitter pool, per-tick emission
  accumulator (retail Birthrate = time-between-spawns → our emit rate
  via 1/B), 13 integrators covering the full ParticleType enum:
  Still, LocalVelocity, GlobalVelocity, 7 Parabolic variants (all
  apply Gravity * dt to velocity), Swarm (orbital drift),
  Explode (outward from anchor), Implode (inward to anchor, dies at
  convergence).
- EmitterDescRegistry: id-keyed EmitterDesc cache with fallback-to-
  default for unknown ids. Replaces the dat-loaded path until
  Chorizite.DatReaderWriter exposes ParticleEmitterInfo (v2.1.7 does
  not; upgraded from 2.1.4 anyway for future types).
- ParticleHookSink: wires the full hook family:
  - CreateParticleHook → SpawnEmitterById at entity pose + hook offset
  - CreateBlockingParticleHook → marker only (blocking semantics live
    in the sequencer not here)
  - DestroyParticleHook → StopEmitter(handle, fadeOut=false)
  - StopParticleHook   → StopEmitter(handle, fadeOut=true)
  - (Default/CallPES deferred until PhysicsScript dat is loadable)

GameWindow integration:
- ParticleSystem created eagerly (no driver dep), sink registered with
  hook router, Tick advanced per OnRender frame after animation tick so
  hooks fired this frame get integrated.

Tests (11 new): spawn-handle, emit-over-time steady state, lifetime
death curve, LocalVelocity movement, Parabolic gravity arc, Explode
outward trajectory, StopEmitter instant kill vs fadeOut, MaxParticles
cap enforcement, registry default fallback, registry custom
registration.

Upgraded Chorizite.DatReaderWriter 2.1.4 → 2.1.7 across Core + Cli.

Build green, 508 tests pass (up from 497).

Ref: r04 §2 (CParticleManager), §3 (13 integrators), §6 (PhysicsScript).
Renderer (instanced billboarded quads in translucent pass) ships next
commit; this one covers the data / logic / wiring layer in full.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 16:48:17 +02:00
Erik
01745d30ab chore(core): scaffold World/Meshing/Textures + add BCnEncoder.Net 2026-04-10 17:49:14 +02:00
Erik
caf57cca3e chore: phase 1 — add Core, Abstractions, App, Tests projects 2026-04-10 09:22:33 +02:00