feat(chess): preset-flexibility architecture — decouple HP, damage, piece-types, state, effects

Decouples five cross-cutting concerns from engine core so new presets
compose without special-casing:

- Piece attributes: CORE_PIECE_ATTRS + PresetDef.pieceAttributes;
  engine.effectivePieceAttrs unions them. HP is now preset-owned.
- Spawn pipeline: engine.spawnPiece() + onPieceSpawn hook replaces
  hand-rolled materialization. Queen-splits seeds HP via the hook,
  not via direct knowledge of piece-hp.
- Hook signatures: all hooks now take single context objects
  (LifecycleContext, MoveHookContext, CaptureHookContext, DamageHookContext,
  SelfCheckFilterContext, GameResultHookContext, PieceSpawnContext,
  BeforeMoveContext, TurnStartContext, DescribeMoveEffectContext).
- Piece-type registry: PIECE_TYPE_REGISTRY + core-piece-types.ts
  replaces hardcoded FIDE switch-tables in engine/check/checkmate/
  stalemate/Piece.tsx. Custom piece types plug in without engine edits.
- Preset-scoped state: engine.presetState<T>(id) backed by facts on
  PRESET_STATE_ENTITY. Auto-cleared on deactivate. capture-to-win
  migrated off GAME_ENTITY.Winner.
- Move log: engine.moveLog + MoveRecord + describeMoveEffect hook.
- Visual effects: engine.emitEffect/subscribeEffects + VisualEffect +
  VisualEffectLayer. Explosion, heal, poison renderers. No-op when
  no subscribers.
- Phase hooks: onBeforeMove (with cancel), onTurnStart. Scope-aware
  dispatch routes onDamage/onBeforeMove/onTurnStart by target/mover
  color.

All 5 production presets migrated. 4 prototype presets (Shield, Cannon,
Berserker, PawnStamina) in integration.test.ts exercise every hook.
Added test-utils.ts and PRESET-API.md for preset authors.

930 tests passing; bun run check clean.
This commit is contained in:
Joey Yakimowich-Payne 2026-04-18 16:26:17 -06:00
commit cc30545ced
No known key found for this signature in database
32 changed files with 3611 additions and 304 deletions

View file

@ -32,7 +32,10 @@
"ses_263703df9ffegmVplLbaxmQIes",
"ses_262de3483ffe5v8SD8eFNqtdo0",
"ses_262de1b3bffexz022qa8FnxRyV",
"ses_262ddfb93ffeMGkZK2rspryFfX"
"ses_262ddfb93ffeMGkZK2rspryFfX",
"ses_262998e6fffeRY6BJVTKB7Jtwb",
"ses_26299a749ffe3jnwQzrfJ9g1Wc",
"ses_261e4ca30ffexBShmvjEhVSHRy"
],
"plan_name": "rete-rules-engine",
"agent": "atlas"