language-reference
AQL language reference
The Agent Query Language (AQL) is the in-browser command surface for
agent-play. This page is the single canonical reference for every
statement the playground supports, including the amenity-content and
wallet commands introduced in 3.1.1 and the scoped amenity commands
(USE AMENITY, REMOVE AMENITY ITEMS, extended INSPECT AMENITY) in 3.1.2.
packages/web-ui/src/app/playground/_lib.
The play canvas (overworld → space yard → amenity stage) is driven by the stage controller. Exit keys and the exit-door sprite are documented in Play canvas exits below.
Contents
- At a glance
- Connection and session
- Inspection
- Agent + intercom
- Space lifecycle
- Amenity content (new)
- Wallet and purchases (new)
- World layout (browser console)
- Play canvas exits (non-AQL)
- Error catalog
- End-to-end recipes
At a glance
- Execution model: each line is a statement; statements run in order via
executeAqlProgram. - Comments:
#starts a line comment. - Strings: double-quoted; escape
\"and\\. - Numbers: integers and decimals (e.g.
12.5). - Variables:
$nameand$obj.field. - Lexer / parser / validator entry points: see
aql-lexer.ts,aql-parser.ts,aql-validator.ts.
LET
LET name = expr
Binds a value to $name for later statements in the same program.
WITH HEADER / WITH TIMEOUT
WITH HEADER "X-Trace" = "abc"
WITH TIMEOUT 5000
Set per-request headers and operation timeouts.
MACRO / CALL / RETURN
MACRO stockShelf(items) {
CALL items
RETURN $items
}
Defines reusable statement lists; CALL name(args) runs them.
Source:
aql-parser.ts,
aql-executor.ts.
Connection and session
CONNECT
CONNECT "http://localhost:3000"
Selects the runtime client. Required for FETCH, SEND, and every RPC.
USE AGENT NODE / SHIFT AGENT NODE
USE AGENT NODE "alice"
SHIFT AGENT NODE
Targets an agent by node id. SHIFT rotates to the next agent in the
catalog.
USE SPACE NODE
USE SPACE NODE "node:…" PASSPHRASE "word1 word2 … word10"
Activates a space context for ADD SHOP ITEM, ADD SUPERMARKET ITEM,
ADD CARWASH CAR, lease operations, USE AMENITY, REMOVE AMENITY ITEMS,
and amenity content removals. Requires a ten-word PASSPHRASE after the
node id (see aql-parser.ts).
Inspection
INSPECT MAIN NODE
INSPECT MAIN NODE
Reads metadata about the main intercom node.
INSPECT SPACE / INSPECT AMENITY / INSPECT AGENT
INSPECT SPACE
USE AMENITY "shop"
INSPECT AMENITY
INSPECT AMENITY "supermarket"
INSPECT AGENT
INSPECT SPACEcallsinspectSpaceand returns{ catalog, logs }.INSPECT AMENITYcallsinspectAmenity. With an explicit kind string ("shop","supermarket", or"car_wash"), the response includeskind,items(array for that kind), andlogs. With no kind argument, the executor sends nokindfilter; the server returnsitemsas{ shopItems, supermarketItems, carWashCars }pluslogs. If you omit the kind expression but have runUSE AMENITY "<kind>", the executor supplies that kind soINSPECT AMENITYalone inspects the scoped amenity.INSPECT AGENTreads the active agent context.
FETCH OCCUPANTS | METADATA | SNAPSHOT
FETCH SNAPSHOT
SHOW RESPONSE
Pulls a slice of state from the runtime. INTO name copies the last
response into $name.
SHOW RESPONSE | HEADERS | <var>
SHOW RESPONSE
SHOW HEADERS
SHOW $myVar
SHOW <var> overrides the last response for display.
Agent + intercom
SEND
SEND "ring the bell"
Routes a message to the active agent node. Requires USE AGENT NODE.
Space lifecycle
CREATE SPACE / REMOVE SPACE / REMOVE SPACE NODE
CREATE SPACE "SandMill Circle"
REMOVE SPACE "space-sandmill-circle"
REMOVE SPACE NODE deletes a space node by node:… id: catalog entry,
amenity sidecar data (shop / supermarket / car wash rows, logs), and the
Redis node auth record. Requires USE PLATFORM KEY in the script (server must
have AGENT_SERVICE_KEY set).
USE PLATFORM KEY "<AGENT_SERVICE_KEY>"
REMOVE SPACE NODE "node:…"
ADD SPACE AMENITY / REMOVE SPACE AMENITY
ADD SPACE AMENITY "shop"
REMOVE SPACE AMENITY "shop"
Mutates the amenity set on the active space. Both require
USE SPACE NODE.
Amenity purchases
In-world purchases use the purchase RPC (shop, supermarket, car wash). Space
operators manage catalog items via ADD SHOP ITEM, ADD SUPERMARKET ITEM, and
ADD CARWASH CAR, and monitor revenue on /platform or the Scanner.
Amenity content (new)
USE AMENITY
After USE SPACE NODE, selects which amenity kind subsequent commands target
when the kind would otherwise be ambiguous. Required before
REMOVE AMENITY ITEMS. Cleared when you switch to another space node or to
an agent node.
USE AMENITY "shop"
USE AMENITY "supermarket"
USE AMENITY "car_wash"
REMOVE AMENITY ITEMS
Deletes persisted amenity content rows (shop items, supermarket items,
or car-wash cars) for the active space. Does not remove the amenity slot
from the space catalog; for that, use REMOVE AMENITY "<spaceId>" "<kind>"
(space lifecycle section).
USE AMENITY "shop"
REMOVE AMENITY ITEMS ALL
USE AMENITY "supermarket"
REMOVE AMENITY ITEMS "sm-uuid-1", "sm-uuid-2"
ALL— delete every item of the scoped kind in this space.- Comma-separated quoted ids — delete only those rows (must match the
current
USE AMENITYkind).
The RPC is removeAmenityItems with { spaceId, kind, all: true } or
{ spaceId, kind, itemIds: [...] }. Each successful removal fans out like
the single-item removeShopItem / removeSupermarketItem /
removeCarWashCar operations.
Every amenity content row is created with sale.status: "available".
Buying an item flips sale.status to "sold" and records
soldToPlayerId + soldAt. Items in the sold state can be removed
only with the --force flag (see
removeShopItem).
ADD SHOP ITEM
Syntax
ADD SHOP ITEM TYPE "book" NAME "Hitchhiker"
DESCRIPTION "Don't Panic" PRICE 9.99
Fields
TYPE— one of"book","music","coffee".NAME— display label.DESCRIPTION— tooltip body.PRICE— USD, decimal accepted.
Returns the persisted item (with sale.status: "available").
Source:
aql-parser.ts,
route.ts.
ADD SUPERMARKET ITEM
Syntax
ADD SUPERMARKET ITEM ROW 1 NAME "Apple"
DESCRIPTION "fresh and crisp" PRICE 1.25 COLUMN 2
Fields
ROW— 1 (Fruits), 2 (Mens), 3 (Womens), 4 (Kids).COLUMN— optional, 1..5; the server auto-picks a free slot when omitted.NAME,DESCRIPTION,PRICE— same as above.
Returns the persisted item.
ADD CARWASH CAR
Syntax
ADD CARWASH CAR SLOT 3 NAME "Sport Coupe" MODEL "GT 350"
YEAR 2024 PRICE 28999 COLOR "#5a87d1"
Fields
NAME,MODEL,YEAR,PRICE,COLOR(hex#rrggbb).SLOT— optional, 1..9; auto-assigned when omitted.
Returns the persisted car.
Sold-state semantics
When a purchase succeeds, the server atomically:
- Sets
sale.status = "sold",sale.soldToPlayerId = playerId,sale.soldAt = ISO-timestamp. - Decrements the player wallet by
priceUsd. - Appends a purchase audit row.
- Fans out the updated snapshot so every connected client repaints the
card with a desaturated body and the red
SOLDbanner (seesprite-sold-overlay.ts).
Re-attempting a purchase against the same item returns
ITEM_ALREADY_SOLD.
Wallet and purchases (new)
Every player starts with a wallet seeded at
DEFAULT_PLAYER_WALLET_BALANCE_USD = $10 on first read. The seeding
is lazy and atomic — see
redis-session-store.ts.
No manual setup is required for a new player to start spending.
INSPECT WALLET
INSPECT WALLET OF PLAYER "player-42"
SHOW RESPONSE
Returns the persisted wallet (or seeds one at $10 on first call).
SET WALLET BALANCE
SET WALLET BALANCE OF PLAYER "player-42" 100
Sets the wallet balance directly. Useful for resetting test environments.
Purchases
Purchases are issued by the play-canvas tooltip (the Buy button calls
the purchase RPC). They are not currently authored from AQL —
authoring purchases through the language reference is not exposed
because real purchases must originate from a player session, not a
script. The RPC contract is documented in
route.ts.
World layout (browser console)
world.layout.bounds.set(field, value) adjusts world layout bounds at
runtime. This is a browser console API, not AQL. See
world-layout-model.ts.
Play canvas exits (non-AQL)
When the player is inside the space yard or any amenity stage:
- Press
Escto leave the current inner stage (amenity → yard, yard → overworld). - Walk into the exit door sprite anchored at stage-local
(0, 0)for the same effect. The proximity radius isEXIT_DOOR_PROXIMITY_RADIUS_WORLD ≈ 1.5world cells (seesprite-exit-door.ts). - On touch devices, the bottom action bar exposes an
Exitchip when the door is the active proximity partner.
The keymap is implemented by
stage-input-router.ts.
Error catalog
| Code | Where it surfaces | Remediation |
|---|---|---|
AQL_PARSE_ERROR |
Lexer / parser | Fix the offending token; the message points at line/col. |
AQL_SEMANTIC_ERROR |
Validator | Add the missing context (e.g. USE SPACE NODE), define the variable, supply the required field. |
AQL_RUNTIME_ERROR |
Executor | Confirm CONNECT has been issued and the active context is correct. |
AMENITY_NOT_ON_SPACE |
RPC route | Run ADD SPACE AMENITY before adding content of that kind. |
ITEM_ALREADY_SOLD |
purchase RPC |
The tooltip refreshes to the sold view; no action needed beyond informing the player. |
INSUFFICIENT_FUNDS |
purchase RPC |
Top up the wallet (SET WALLET BALANCE) or pick a cheaper item. |
End-to-end recipes
1. Stock a bookstore and let a player buy a book
CONNECT "http://localhost:3000"
USE SPACE NODE "space-sandmill-circle"
ADD SPACE AMENITY "shop"
ADD SHOP ITEM TYPE "book" NAME "Hitchhiker"
DESCRIPTION "Don't Panic" PRICE 12.5
ADD SHOP ITEM TYPE "music" NAME "Symphony No. 9"
DESCRIPTION "Beethoven's choral finale" PRICE 9.99
ADD SHOP ITEM TYPE "coffee" NAME "House Blend"
DESCRIPTION "Locally roasted, medium body" PRICE 4
Then in the play canvas, walk the human into the shop and press P
near the card. The tooltip's Buy button calls the purchase RPC.
2. Stock a supermarket row via a macro
CONNECT "http://localhost:3000"
USE SPACE NODE "space-sandmill-circle"
ADD SPACE AMENITY "supermarket"
MACRO stockFruit(name, price) {
ADD SUPERMARKET ITEM ROW 1 NAME $name
DESCRIPTION "Fresh produce" PRICE $price
}
CALL stockFruit("Apple", 1.25)
CALL stockFruit("Banana", 0.75)
CALL stockFruit("Mango", 2.10)
3. Stock the car-wash lot, then inspect inventory
CONNECT SERVER "http://localhost:3000" MAIN_NODE "main-1"
USE SPACE NODE "node:…" PASSPHRASE "ten word passphrase here …"
ADD SPACE AMENITY "car_wash"
ADD CARWASH CAR SLOT 1 NAME "Sport Coupe" MODEL "GT 350"
YEAR 2024 PRICE 28999 COLOR "#5a87d1"
USE AMENITY "car_wash"
INSPECT AMENITY
SHOW RESPONSE
The inspectAmenity response includes items (the cars when scoped), plus
logs. Sold cars in items have sale.status: "sold" and a
sale.soldToPlayerId.