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.