No description
Wave 1 (W1.0–W1.6) of the thressgame-100 epic — push ThressGame coverage from
27 % toward 85 %+ via resolver expressiveness. Foundation for Layer-1 rules
(self-targeting destroys, mass-mover, adjacent splash). Recipes (W1.7–W1.12)
land in subsequent commits.
Resolver V3 (param-resolver.ts) — 6 new shapes:
- {ctx-self-id: null} → ctx.pieceId
- {ctx-self-marker-id: null} → ctx.markerId (throws when undefined)
- {add: [<resolver>, <int>]} → recursive arithmetic, MAX_SAFE_INTEGER overflow throws
- {sub: [...]}, {mul: [...]}, {mod: [...]} — same pattern; mod uses positive-modulo
formula ((l % r) + r) % r so column-wrap recipes work for any sign of l
V3 union order locked (param-resolver-schema.ts):
[literal, $var, ctx-attr, ctx-build, ctx-self-id, ctx-self-marker-id, add, sub, mul, mod]
PrimitiveApplyContext (types.ts): added optional readonly markerId? field.
runPrimitives (triggers.ts): populates markerId in ctx for piece-entered-marker
and marker-expire events from event.markerId (single source of truth).
W1.6 — add-to-attribute.target:
- Schema gains optional target?: numberOrResolver({ min: 0 }) field
- apply() resolves target then defaults to ctx.pieceId when undefined
- Closes the long-documented adjacent-splash sharp edge — splash damage now
expressible via target redirection instead of forcing set-piece-attr
Test surface:
- param-resolver.test.ts: +22 tests (39 total) — overflow boundary, recursive
nesting, mixed shapes, replay determinism, ctx.markerId failure modes
- param-resolver-schema.test.ts: +19 tests (38 total) — V3 union for each helper,
arithmetic shape parsing, ctx-self-id payload validation
- add-to-attribute.test.ts: +6 tests (10 total) — target literal, target $var,
target omitted (backward-compat), reject string target, apply with/without target
- ParamField snapshot regenerated for add-to-attribute.target rendering
bun run check: 2983 tests pass (was 2941, +42).
Plan: .sisyphus/plans/thressgame-100.md (5 waves + cross-ref + final verification,
~73 atomic tasks locked end-to-end).
Notepads: .sisyphus/notepads/thressgame-100/
Locked architectural decisions (irrevocable across all 6 waves):
A. Arithmetic resolver shapes — arity 2, no comparisons, no booleans
B. Self-targeting via ctx-self-id / ctx-self-marker-id (NOT 'self' literal)
C. add-to-attribute.target optional, defaults to ctx.pieceId
D. Multi-turn countdowns via on-attr-expire trigger (Wave 2)
E. Piece-pair lifecycle via PieceLink + on-piece-pair-link-broken (Wave 4)
F. Resource accumulation on GAME_ENTITY (Wave 5)
G. Board topology via BoardTopology attr (Wave 4)
H. Validator V3 — superset of V2, all V2 fixtures auto-validate
J. User-explicit overrides — no backward-compat constraint, no time/cost limit
|
||
|---|---|---|
| .github/workflows | ||
| .sisyphus | ||
| docs | ||
| packages | ||
| scripts | ||
| .dockerignore | ||
| .gitignore | ||
| docker-compose.dev.yml | ||
| docker-compose.yml | ||
| Dockerfile.dev | ||
| eslint.config.js | ||
| lefthook.yml | ||
| LICENSE | ||
| package.json | ||
| playwright.config.ts | ||
| README.md | ||
| tsconfig.base.json | ||
| tsconfig.json | ||
| vitest.workspace.ts | ||
@paratype
A Doorenbos-style Rete II rules engine for TypeScript games, with an authoritative WebSocket chess demo.
Packages
packages/rete— Rete II engine corepackages/chess— Browser chess demo (React + Vite)packages/server— Authoritative Bun WebSocket server
Docs
- SPEC.md — Engine specification
- PHASES.md — Development phases & perf budgets
- RULES.md — Chess rule presets
- PROTOCOL.md — WebSocket message protocol
Getting Started
bun install && bun run check