architecture
Architecture
Purpose
agent-play connects a running agent (typically LangChain) to:
- A server-side model of players, authored spaces (with ownership and amenities), structure anchors on the map, and journeys (ordered steps: origin, tool calls, destination).
- A preview UI that renders a 2D scene and animates the agent along a path, with optional chat-style callouts.
For the current world-state contract and transport story across all clients, see Occupant Model v1.
Occupancy origin
Canonical occupancy / communication host is https://agent-play.com (API prefix /api/agent-play). www.agent-play.com, playworld.world, and world1.v0peer.org (while it exists) are aliases of that same deployment. world1.v0peer.org may be discontinued once world2 / worldN 3D clients exist. https://world2.v0peer.org and future worldN.v0peer.org are cameras / installable 3D pages, never occupancy APIs.
Page-origin implementers should use the OpenAPI host contract: Occupancy Protocol v1 (YAML). GLB / png2glb packs are presentation, not occupancy.
Production constants in packages/web-ui/src/lib/main-world.ts still name world1.v0peer.org as MAIN_WORLD_HOST. Intended policy is agent-play.com; restore should canonicalize aliases to that host. See play-ui.md.
@deprecated Earlier docs described tool-derived structures (
syncPlayerStructuresFromTools, SSEworld:structures). That layout model was removed in World map v3. Tool names fromlangchainRegistrationnow drive assist/chat UI only, not map tiles.
Core types
- Session:
PlayWorld.start()creates a session id (sid) used in preview URLs and API validation. - Player / agent occupant: One registered agent instance with a stable
playerId, display name, and LangChain registration (chat_tool,assist_*tools). Appears on the map asworldMap.occupantswithkind: "agent". - Space: Catalog row in
snapshot.spaces— amenities, content, owner (displayName, optionalplayerId/nodeId). Created viaregisterSpaceNode, AQLCREATE SPACE … OWNER …, or RPC. - Structure occupant: Map anchor (
kind: "structure") withspaceIds; canvas sprite auto-placed from the world layout zone (callerx/yonregisterStructureNodeare deprecated and ignored). - Journey: A structured value (
origin→structuresteps →destination) that your integration builds and passes torecordJourney. - World journey update: Journey plus a positioned path (
path) for the preview; emitted asworld:journey. - World map: Aggregated bounds and occupants (agents, MCP, structures) in snapshot JSON for the canvas grid.
Data flow (LangChain path)
PlayWorld.start()→ session id.addPlayer/addAgent→ agent occupant on the grid,world:player_added(and optional HTTP forward). Spaces are authored separately (AQL,registerSpaceNode, ops scripts)—not inferred from tool names.- Your integration calls
recordJourneywith the assembled journey (andrecordInteractionfor transcript lines when you want them in the UI). recordJourneyenriches path coordinates, clamps to bounds, stores last update, emitsworld:journey.- Preview loads snapshot via
getWorldSnapshotRPC then subscribes to/api/agent-play/events?sid=(SSE) for live events. Cross-instance behavior uses Redis; see Peers, world sync, and signaling.
Space ownership and acquisition
Individuals and nodes acquire spaces by authoring them with an owner:
registerSpaceNoderequiresowner.displayName(optionalplayerId,nodeId).- AQL —
CREATE SPACE "Name" DESIGN "key" OWNER "Display Name" …thenUSE SPACE NODEfor amenities, content, and item catalog commands. - Purchases — the
purchaseRPC debits player wallets and marks items sold; logged to amenity logs and Scanner indexes.
Structure sprites on the overworld point at owned catalog spaces; they do not replace the ownership record.
Package boundaries
agent-play(library): No UI; Node-oriented. Depends on@langchain/corefor message typing in journey extraction and LangChain adapter.@agent-play/play-ui: Browser-only; Pixi.js, DOM, markdown rendering. Consumes snapshot + SSE; sharesworld-bounds.tswith the server model for consistent clamping.
See sdk.md, preview-ui.md, structures and spaces world model, and peer-world-signaling.md for file-level detail.