Step 6: Link the sketch to the world
Pin a finished drawing to a real card, by id — a sketch stops being an island.
Let's say you just sketched the room from the opening scenario. Right now that drawing lives
only inside this one sketch document — nobody browsing The Sunken Vale's card would
ever find it. Point the sketch at that world document and it becomes a linked artifact in
the world graph instead.
Read the world, live
import { useWorldQuery } from "@vvd/sdk"
const cards = useWorldQuery("documents", { type: "card" })That's it — no useEffect, no loading flag. cards is live: it re-renders when someone adds
one anywhere in the world, on any client. Reading the
world covers the whole API; this build uses one call
from it.
Store an id, never a copy
export const codec = defineStateCodec({
strokes: field.map<Stroke>(),
linkedDocumentId: field.value<string | null>(null),
})One field, and it's a reference — the same rule the first-tool tutorial used for a note's link. Rename the card later and this chip follows, because there's nothing to keep in sync; there's only one copy of the name, and it isn't on the sketch.
You should see: draw a couple of strokes, then click the dashed Link a card chip in the bottom-left corner. This frame's world has Aria of the North, The Sunken Vale, The Salt Road, and The Cartographers' Guild in it — pick The Sunken Vale, and the chip turns solid, showing its name. Click it again to unlink.
The grant is two lines, the same two Getting Started's world-data page covers:
{ "capabilities": { "readsWorld": true }, "needs": ["world"] }Forget readsWorld and useWorldQuery fails loudly the moment sketchTool mounts, naming the
capability it wanted — never a silently empty list. See Reading the
world for exactly what that failure looks like.
Recap
useWorldQuery("documents", { type: "card" })reads the world's cards live and read-only.- A link is one field —
linkedDocumentId: field.value<string | null>(null)— always an id. - Rename the linked card in the world and the chip's label follows; there's nothing to keep in sync.
capabilities.readsWorld+needs: ["world"]is the whole grant, and it's enforced every mount.