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 gamestruct

The 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() })