Gessa Docs
Recipes

Recipe

Game loop assembly entities scripts HUD win shippable loop

You have or want a scene and need it to become a GAME: something that starts, lets the player act, tracks a score or objective, and reaches a win or end state. This is the assembly order that wires the parts into one loop.
engine v1.0.234since script-semantic-patch-ops.v1, world-build-operation-catalog.v1, ui.v1, match.v1Copy for LLM

Use this for

composing a full playable loop; the assembly ORDER of structure, components, behavior, HUD, and win; turning a static scene into a game that starts, scores, and ends

Not for

the deep mechanics of one system (see the topic playbook); durable cross session saves (see saves-and-persistence)

Pairs with: World build document authoring compile apply loop, Collectibles pickups scoring and win condition, UI HUD panels widgets and world nameplates, Playtest verification loop proving gameplay executed evidence, Juice and polish pass the presentation phase after the playtest proof

Game loop assembly entities scripts HUD and win into a shippable loop

The layers, in order

Assemble in this order so each layer can reference what the layer before it created.

  1. STRUCTURE. Land the world in one document with world_build_apply_semantic_operations (see authoring-with-the-world-build-document): floor, boundaries, the objective entities (pickups, targets, goals), camera, and sky as one atomic transaction.
  2. GAMEPLAY COMPONENTS. The objective entities usually need a ColliderComponent (a trigger collider to detect contact) and a query tag the behavior can find them by. Attach these in ONE atomic precision write with project_apply_transaction, with the exact keys and tags your script will query. This is the component layer the document does not emit.
  3. BEHAVIOR. One project_apply_script_semantic_patch composes the loop from neutral primitives: findEntitiesByTag to gather the objective set, addTriggerHandler to react to a pickup, incrementNumericState to raise the score, despawnEntity to consume the item, and declareWinCondition (or a compareRemainingCount check on a tick handler) to end the match when the remaining count hits the threshold. See collectibles-and-scoring for the exact op payloads.
  4. HUD. Create a panel with project_create_ui_panel, then bind one widget to the SAME score field with a wireHudStateBinding op in a script patch. The HUD displays state, it does not own it. See ui-hud-panels-and-widgets.
  5. PROOF. Playtest with world_playtest_scenario: possess the player, execute the actions that should score, and confirm the after state changed. See playtest-verification-loop.
  6. POLISH. Once the loop is PROVEN, run the polish pass as a distinct phase: a lighting rig and sky, a material palette, a camera hero frame and post look, world-text labels, audio beds and stingers, transient impact cues, and generated hero models replacing primitive placeholders. Each is a real authorable op, ordered so lighting frames materials and the camera frames the lit scene. Do this AFTER the proof so you decorate a real loop, not a scene that might still change shape. See juice-and-polish-pass.

Why the order matters

  • Behavior queries entities by tag, so the tags (layer 2) must exist before the script (layer 3) runs.
  • The HUD binds a field the script writes, so wire the HUD (layer 4) to the same storeKey, recordKey, and field the behavior increments, never a separate copy.
  • The playtest needs a possessable player and a real objective, so it comes last.

Pitfalls

  • Do not spread structure across dozens of single create calls. One document, one transaction (layer 1). The per mutation tools are for the component and behavior layers, not for bulk placement.
  • Do not declare the win in two places. One declareWinCondition on the authority; do not also flip the phase from the client.
  • A loop with no declareWinCondition and no end phase never finishes; add the win layer even for a simple arena.
  • Do not report a loop that was built on primitive placeholders as visually finished. Placeholders (a gray box for a chest, a capsule for an enemy, an asset.placeholder.request marker) are correct scaffolding for proving the loop, and the polish pass replaces the hero ones. If placeholders remain when you hand back the work, DISCLOSE it: name what is still a stand-in and that it awaits polish. See juice-and-polish-pass for the disclosure norm in full.

Verify

  • project_get_graph_snapshot: the objective entities, the script, and the HUD panel all exist.
  • world_playtest_scenario: the score rises when the player acts and the win phase fires when the objective is met.
  • A snapshot proves the loop's STRUCTURE, not its appearance. If the brief asked for a finished look, confirm the hero objects render as real meshes (see juice-and-polish-pass and scenery-composition) and say so honestly if any are still placeholders.
Was this helpful?Report an issueContact support

On this page