forge-lcdl

Games engine API (`forge_lcdl.games.engine`)

Pure, stdlib-facing rules surface. Detailed split with LCDL is in GAMES-ARCHITECTURE.md; alpha checklist in GAMES-ALPHA-STATUS.md.

Games engine API (forge_lcdl.games.engine)

Pure, stdlib-facing rules surface. Detailed split with LCDL is in GAMES-ARCHITECTURE.md; alpha checklist in GAMES-ALPHA-STATUS.md.

Game lifecycle

  1. setup(seed=None, ...) — Authoritative starting state (seed is optional metadata for rules that need RNG inside setup).
  2. acting_player(state) — Who must act, or None if terminal / undefined.
  3. player_view(state, player_id) — JSON-serializable PlayerView; never leaks hidden opponent data through this path.
  4. legal_moves(state, player_id) — Stable, finite tuple of Move instances; move_id is the externally stable handle.
  5. apply_move(state, move) — Returns TransitionResult; illegal plays use transition_fail("…") without raising.
  6. is_terminal(state), then score(state) (InvalidStateError if not terminal—by contract).

Error surface

Situation Preferred API
Illegal move TransitionResult(ok=False, error='…')
Caller bug / corrupt state decode ValueError, InvalidStateError
Scoring non-terminal state InvalidStateError

Hashing and logs

stable_state_hash and serialization.state_hash delegate to the same SHA-256 of canonical JSON. Use replay.replay_log to verify persisted GameLog rows.

Serialization facade

serialization.to_canonical_json / from_canonical_json coerce JSON-stable trees; ensure_json_serializable raises TypeError on unsupported leaves.

Bundled reference move_id prefixes

GAME_ID Prefix examples
tic_tac_toe place_<row>_<col>
nim take_<n>
connect_four_like drop_col_<col>

CLI (stdlib-only)

python -m forge_lcdl.games.engine list-reference-games
python -m forge_lcdl.games.engine replay path/to/fixture.json
python -m forge_lcdl.games.engine random-play tic_tac_toe --seed 1

See GAMES-EXAMPLES.md for scripted demos.