what
Four primitives, two lanes.
A zero-dependency ESM library. One contract - four primitives over one semantic tree - plus reference renderings for both audiences and two transport bindings.
npm install gamestructThe four primitives
Every door exposes exactly these four. A client that uses only these four can operate the surface.
1observe
() -> Snapshot - the surface's state for this seat.
2act
(handle, verb?, value?) -> Result - do one thing, by stable handle.
3wait_for
(predicate, timeoutMs) -> Outcome - resolve when a condition holds, or time out honestly.
4events
(sinceFrame) -> { frame, events[] } - what changed while you were not looking.
The two lanes
Both read the SAME tree - two renderings of one description, not two implementations of one feature.
◧ human lane
render, a11yDump, audit - the assistive-technology view: roles, accessible names, focus order, live regions.
◨ agent lane
toolCatalog, affordances, toolCall - the machine view: one MCP-shaped tool per actionable node, each with an inputSchema so a client auto-wires.
⇄ the bindings
Transport only: bindings/http (/observe, /act, /wait_for, /events, /health, fail-closed auth) and bindings/mcp (JSON-RPC 2.0).
The smallest surface
A door and a client share exactly one vocabulary: the handle. Everything else is a rendering.
import { Bridge, ROLES, human, agent } from 'gamestruct' const bridge = new Bridge({ name: 'pause menu' }) bridge.tree.add(null, { id: 'ui:start', role: ROLES.BUTTON, name: 'Start game' }) bridge.on('ui:start', { activate: () => startGame() })