Handbook
Games engine + LCDL layer — alpha status
Snapshot for forge_lcdl.games and related governed tasks/contracts. Intended for engineer handoff: what exists, how to invoke it, and what is deliberately out of scope for this alpha.
Implemented modules (src/forge_lcdl/games)
| Area | Paths | Role |
|---|---|---|
| Engine core | games.engine — interfaces, models, errors, loop, log, serialization, replay, rng, cli |
Game protocol; moves, views, transitions; hashing; replay; CLI; JSON facade |
| Topology | games.engine.mechanics — grid, graph, connectivity |
Positions, square grid, graph boards, flood-fill / path checks, line detection on grids |
| Reference rules | games.engine.reference — tic_tac_toe, nim, connect_four_like (+ REFERENCE_GAMES_META, new_reference_game) |
Small rulesets implementing Game |
| Adapters | games.adapters.web_json |
state_response, legal_moves_response, apply_move_request, error_response (stdlib JSON only) |
| Task shapes | games.tasks.schemas |
TypedDict helpers for payloads (no transport) |
| Placeholders | games.agents |
Reserved for policies / play loops |
| Shared errors | games.errors |
Thin-layer exceptions |
Related (older / parallel): forge_lcdl.game_engine — separate reference registry and types; see GAME-ENGINE.md. Long-term, consumers may prefer games.engine as the primary façade.
Reference games
tic_tac_toe— full-information 3×3; stableplace_<r>_<c>move ids.nim— take tokens; configurable start; stabletake_<n>ids.connect_four_like— rectangular column-drop grid, four-in-a-row win;drop_col_*ids; usesmechanics.connectivityfor line detection.
Supported mechanics
- Grid —
Position,SquareGrid, JSON helpersposition_to_json/position_from_json. - Graph —
GraphBoardfor edge-adjacency games. - Connectivity —
flood_fill,path_exists_grid,path_exists_graph,find_lines_on_grid.
Supported LCDL tasks (v1)
Registered via TASK_REGISTRY_V1 and forge_lcdl.tasks.registry (lazy ensure_builtin_tasks_registered):
task_id |
Contract folder | Purpose |
|---|---|---|
game_move_parse |
contracts/game_move_parse/v1/ |
NL utterance → selected / ambiguous / illegal_or_unmatched against caller-supplied legal_moves |
game_move_explain |
contracts/game_move_explain/v1/ |
Explanation for one validated selected_move_id |
game_move_rank |
contracts/game_move_rank/v1/ |
Rank subset of moves; heuristic_scores keys must match legal ids |
Validation lives in forge_lcdl.game_lcdl.validate (confidence_in_unit_interval, subset checks, rankings). Model output must not introduce unknown move_id values before Ok results are returned.
How to run (developers)
cd forge-lcdl
python -m pytest tests/ --ignore=tests/integration
Engine CLI (stdlib only)
PYTHONPATH=src python -m forge_lcdl.games.engine list-reference-games
PYTHONPATH=src python -m forge_lcdl.games.engine replay tests/games/fixtures/replay/tic_tac_toe_three_moves.json
PYTHONPATH=src python -m forge_lcdl.games.engine random-play nim --seed 1
Examples
Run from repo root with PYTHONPATH=src:
examples/games/play_tic_tac_toe.pyexamples/games/play_connect_four_like.pyexamples/games/replay_fixture.py(wraps CLI replay)examples/games/llm_advisor_fake.py— offlineTaskRunner+game_move_explain
Using the engine in code
state = game.setup(seed=..., ...)view = game.player_view(state, player_id)— JSON-serializable dict fields only.moves = game.legal_moves(state, player_id)result = game.apply_move(state, move)— checkresult.ok.- Repeat until
game.is_terminal(state), thengame.score(state).
Using LCDL tasks
Build input_data with player_view (object) and legal_moves (list of objects with move_id). Call run_task("game_move_parse", "v1", input_data, profile=..., chat=fake) in tests with a ChatFn returning JSON strings.
Test coverage checklist (alpha)
| Concern | Location / notes |
|---|---|
| Engine forbids LLM/transport imports | tests/games/test_architecture_imports.py, tests/games/test_no_engine_llm_imports.py — AST scans of games/engine. |
move_id validation |
tests/tasks/test_game_move_*.py. |
| Replay + hash | tests/games/engine/test_replay.py, tests/games/fixtures/replay/*.json. |
| CLI | tests/games/test_cli.py. |
| Adapters | tests/games/adapters/test_web_json.py. |
| Serialization | tests/games/engine/test_serialization_roundtrip.py. |
| Seeded RNG | tests/games/engine/test_rng.py. |
| Fake transport for game tasks | tests/tasks/test_game_move_*.py. |
| Docs present | tests/docs/test_game_docs_exist.py. |
| Hidden information | Gap: asymmetric Game + dedicated tests for PlayerView.private. |
Known limitations (alpha)
games.agentsstub only.- Hidden information — no first-class “secret hand” reference rule in
games.engine.referenceyet. game_enginevsgames.engine— two stacks coexist.- Operators / full play tree — not wired; tasks are single-step assist (parse / explain / rank).
Next recommended sprints (handoff order)
- Hidden-info reference +
test_hidden_information.py. - Flesh out
games.agents(heuristic / scripted players). - Converge
game_enginefaçade withgames.enginewhere practical. - Broader adapter coverage (batch apply, score snapshots).
- Optional package entry point for
forge-lcdl-games-cli.
Doc index
- Architecture:
GAMES-ARCHITECTURE.md - Engine API / LCDL / tasks / examples / testing:
GAMES-ENGINE-API.md,GAMES-LCDL-LAYER.md,GAMES-LCDL-TASKS.md,GAMES-EXAMPLES.md,GAMES-TESTING.md - Legacy
game_enginepackage:GAME-ENGINE.md - This status page:
GAMES-ALPHA-STATUS.md(living document)