---
title: "Game loop assembly entities scripts HUD win shippable loop"
description: "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."
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/game-loop-assembly/
---

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

## When to use

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.

## 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.
