why

The same absence, twice.

A screen reader, a switch, voice control, and a machine agent all fail on the same UI: buttons with no accessible name, state with no text, controls with no stable handle. That is not four problems. It is one missing description.

The problem: the surface is invisible twice

Most games ship with no accessibility layer and no agent surface. Those look like two gaps, but they are one gap seen from two sides: a person using a screen reader hears "button" with no name and cannot act; an agent brain sees pixels with no handle and cannot act either.

Both need the same four things - a semantic tree, stable handles, a linear traversal, and an event stream - which is the whole reason a single contract can serve both.

The thesis: describe once, render twice

Describe the surface once as a semantic tree, and the two lanes are two renderings of that one description. The human lane hands the tree to the platform accessibility API (ARIA, AccessKit, NSAccessibility). The agent lane hands the same tree to an MCP client. Same nodes, same handles, same act().

// one tree, both audiences
human.a11yDump(bridge)      // what a screen reader reads
agent.toolCatalog(bridge)     // what an MCP client auto-wires
await bridge.act('ui:start')    // either lane, one code path

Why it is small on purpose

An accessibility layer that is a separate feature rots: it drifts from the real UI the day someone forgets to update both. gamestruct is one tree, so there is nothing to drift from. A game does not adopt gamestruct by rewriting itself - it writes one function that maps its own state to a tree, and both lanes fall out.