---
title: "World build document authoring compile apply loop"
description: "Any intent with more than one part: a floor plus walls, a batch of pickups, a lit and framed scene. Do not open with a string of one entity per call writes. Express the whole structural intent as ONE document and land it in ONE decisive call. This is the primary authoring write path; the per mutation create/update tools are the precision and repair tier described at the end."
engineVersion: v1.0.234
date: 2026-09-28
license: "(c) Gessa, proprietary. Cite with attribution to https://gessa.ai/docs/. Terms: https://gessa.ai/terms/."
canonical: https://gessa.ai/docs/knowledge/playbooks/authoring-with-the-world-build-document/
---

# Authoring with the world build document compile and apply loop

## When to use

Any intent with more than one part: a floor plus walls, a batch of pickups, a
lit and framed scene. Do not open with a string of one entity per call writes.
Express the whole structural intent as ONE document and land it in ONE decisive
call. This is the primary authoring write path; the per mutation create/update
tools are the precision and repair tier described at the end.

On a blank game whose user asked for a playable genre, do NOT rebuild a player,
camera, or controller here first: start from a certified starter template
(see blank-game-quickstart, template plus delta), then use this document to
author only the delta on top of it.

## The three tools

- `world_build_get_operation_catalog` returns the high level operation catalog
  (intent level operation ids, not raw component payloads). Read it once so you
  author with catalog operations instead of endpoint shaped payloads.
- `world_build_compile_semantic_operations` is the DRY RUN twin: it validates the
  document and returns diagnostics and the lowered operations without writing.
- `world_build_apply_semantic_operations` is the WRITE twin: it compiles through
  the SAME validator, then lands the result as one atomic, idempotent, undoable
  transaction. A replay of the same document is a no op.

## The loop

1. Ensure a target world exists (a blank game ships a start world). Name it with
   `context.world_id` OR `context.world_key` (either coordinate resolves); a
   single-world game needs neither - apply binds the only world. Apply does NOT
   create the game or world.
2. Read the operation catalog once with `world_build_get_operation_catalog`.
3. Write the whole intent as one `operations` array. Each operation is
   `{ "operationId": <catalog id>, "payload": { ... } }`.
4. If you are confident, call `world_build_apply_semantic_operations` directly.
   If you are uncertain, call `world_build_compile_semantic_operations` first,
   read the diagnostics, fix the document, then apply.
5. Read the result: `createdEntityCount`, `createdKeys`, `revision`, and the
   compiler `diagnostics`. Then verify by playing (see playtest-verification-loop).

## What apply lands (the seam)

Apply lands, in ONE atomic idempotent commit: lowered `project.entity.create`
(entities into the target world, honoring EXPLICIT per-item `key` and `tags` -
required exact keys are spec, write them on the items), `project.component.create`
and `project.component.update`, and - as receipted post-commit stages under the
same idempotency umbrella - `script.semantic_patch.apply` (creates the script
shell if missing, fills version and fingerprint from its own read, patches,
then attaches the ScriptComponent to every entity named in the cluster's
`entityKeys`), `typed_state.store.create` (resolve-or-replay), and
`ui.hud.bind`/HUD recipes. EVERY lane is wired: the whole playable game -
bodies, behavior loop, per-entity script attachments, typed-state store, HUD -
lands in ONE document. `gameplay.collectible_cluster.create` is the loop
carrier: give it `tag`, `entityKeys`, `scriptKey`, `score`, `victory` and it
composes the touch-pickup trigger loop, attaches the script to every listed
collectible, completes a static trigger collider on every collectible body this
same document creates (an item that declares its own collider wins; do NOT add
RigidBody to a static sensor), and auto-creates the referenced store. `prefab.create` defines a named reusable
entity subtree (components + scripts per entity) that scripts spawn with
`spawnEntityFromTemplate` `prefabKey`; the default gameplay loop's projectile
prefab is compiler-ensured, and an explicitly named prefab is yours to declare
(same document or precision tool). Package and proof
operations are compile-visible but never applied here (proofs run via
`world_playtest_scenario`).

## Worked example: the arena shell in one document

A blank game already has a start world; read its id from
`project_get_graph_snapshot`. Then apply the shell (floor, four walls, a ring of
coin bodies, camera, sky) as ONE transaction with real operation ids:

```
world_build_apply_semantic_operations({
  game_id: <gameId>,
  context: { world_id: <worldId> },
  operations: [
    { operationId: "entity.role_batch.create", payload: { items: [
      { name: "Arena Floor", primitive: "box", position: {x:0,y:0,z:0},   scale: {x:20,y:1,z:20}, role: "boundary", materialTint: "#3f3f46" },
      { name: "Wall North",  primitive: "box", position: {x:0,y:1,z:-10}, scale: {x:20,y:2,z:1},  role: "boundary" },
      { name: "Wall South",  primitive: "box", position: {x:0,y:1,z:10},  scale: {x:20,y:2,z:1},  role: "boundary" }
      /* Wall East, Wall West ... */
    ] } },
    { operationId: "entity.primitive_batch.create", payload: { items: [
      { key: "arena_coin_1", name: "Coin 1", tags: ["coin"], primitive: "sphere", position: {x:6,y:1.2,z:0},    scale: {x:0.6,y:0.6,z:0.6}, materialTint: "#facc15" },
      { key: "arena_coin_2", name: "Coin 2", tags: ["coin"], primitive: "sphere", position: {x:4.24,y:1.2,z:4.24}, scale: {x:0.6,y:0.6,z:0.6}, materialTint: "#facc15" }
      /* arena_coin_3..8 around a radius 6 ring ... */
    ] } },
    { operationId: "gameplay.collectible_cluster.create", payload: {
      tag: "coin", clusterKey: "arena_coins", scriptKey: "script.arena.coin_pickup",
      entityKeys: ["arena_coin_1", "arena_coin_2" /* ..._8 */], removeOnPickup: true,
      score: { field: "score", increment: 1 },
      victory: { message: "All coins collected!" } } },
    { operationId: "ui.hud_recipe.apply",             payload: { panelKey: "arena_hud_score", name: "Score HUD" } },
    { operationId: "camera.hero_frame.set",           payload: { position: {x:0,y:14,z:16} } },
    { operationId: "environment.sky_atmosphere.apply", payload: {} }
  ]
})
```

The cluster operation composes the whole gameplay loop: an `onTriggerEnter`
handler that despawns the touched collectible and increments the score, an
`onTick` handler that re-scans the tag, writes the `won` flag, and declares the
win condition, a HUD wire when the document carries a panel, the ScriptComponent
attached to every entity in `entityKeys`, a static TRIGGER COLLIDER completed
onto every collectible body created in the same document (no RigidBody - a
static sensor plus the KCC player is the proven trigger pair), and the
referenced typed-state store auto-created. Explicit item keys make required
exact keys land exactly.

One call, one commit, one undo unit. `entity.primitive_batch.create` and
`entity.role_batch.create` each fan a `payload.items` array (max 32 per batch)
out to one entity per item; the compiler owns the `TransformComponent`,
`RenderableComponent`, and material defaults. Apply returns the created keys.

## Compile diagnostics repair loop

When a document is rejected, `world_build_apply_semantic_operations` returns
`{ ok: false, stage, code, message, diagnostics }` and writes NOTHING. Common
stages: `compile` (a payload the validator refused), `budget` (the document
lowers to more than the apply cap; split it), `owner` (a post-commit stage
failed or is `owner_unavailable` - the graph part COMMITTED and the result
names what landed; finish the unavailable lane with its precision tool),
`apply` (a transaction conflict). Read `diagnostics`,
edit the one offending operation, and re apply. Prefer
`world_build_compile_semantic_operations` to inspect diagnostics without a write
when you are iterating.

## The precision tier (per mutation is the repair tool, not the default)

The document carries the WHOLE game: bodies with exact keys and tags, the
behavior loop with per-entity attachments (the cluster operation), the
typed-state store, and the HUD. Do not follow a document with a string of
`project_add_component` / `project_create_ui_panel` / `project_create_data_store`
calls to "finish" it - the document already landed those lanes. Reach for a
single `project_create_entity`, `project_add_component`, or a field update only
to REPAIR or precisely target ONE entity after verification. The document is
the write path; the per mutation call is the scalpel.

## Verify

- `project_get_graph_snapshot` to confirm the created entities and the new
  `revision` landed.
- `world_playtest_scenario` to PLAY the result (see playtest-verification-loop):
  an after state that is identical to the before state is not proof of gameplay.
