acdream/tests/AcDream.Core.Tests
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
..
Audio feat(audio): Phase E.2 OpenAL engine + SoundTable cookbook + hook wiring 2026-04-18 16:38:26 +02:00
Input feat(movement): spacebar charged jump with skill-based height 2026-04-13 23:20:52 +02:00
Meshing feat(net): Phase 6.6 — parse UpdateMotion (0xF74C) into MotionUpdated event 2026-04-11 20:33:26 +02:00
Physics feat(anim): Phase E.1 hook router + GameWindow wiring 2026-04-18 16:30:23 +02:00
Plugins feat(core): add IGameState, IEvents, WorldEvents with replay-on-subscribe 2026-04-10 20:29:29 +02:00
Rendering feat(app): Phase B.2 — ChaseCamera (third-person follow camera) 2026-04-12 14:26:20 +02:00
Streaming fix(app): Phase A.1 — pending-spawn list in GpuWorldState (proper fix) 2026-04-11 23:19:40 +02:00
Terrain test: port ACME ClientReference + conformance tests 2026-04-12 22:45:20 +02:00
Textures feat(core): SurfaceDecoder — add PFID_P8, PFID_R8G8B8, and PFID_X8R8G8B8 2026-04-11 19:23:57 +02:00
Vfx feat(vfx): Phase E.3 particle system + hook wiring + registry 2026-04-18 16:48:17 +02:00
World fix(app+core): Phase B.3 — Setup.StepUpHeight + scenery road exclusion 2026-04-12 18:27:36 +02:00
AcDream.Core.Tests.csproj feat(app): Phase A.1 — StreamingRegion (window set + diff with hysteresis) 2026-04-11 22:01:45 +02:00
SmokeTest.cs chore: phase 1 — add Core, Abstractions, App, Tests projects 2026-04-10 09:22:33 +02:00