---
title: "Blank game quickstart cold start recipe empty project"
description: "You are on a fresh or empty game and need to get moving. This is the cold start recipe. Follow it top to bottom."
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/blank-game-quickstart/
---

# Blank game quickstart the cold start recipe for an empty project

## When to use

You are on a fresh or empty game and need to get moving. This is the cold start
recipe. Follow it top to bottom.

## Do not study the whole corpus first

The measured failure on blank games is a study spiral: dozens of knowledge
searches and loads before the first write. Do not do that. This page plus the
output of `world_build_get_operation_catalog` is enough for an arena class build.
Pull ONE topic playbook only when you hit that specific need (scoring, physics,
HUD), not preemptively.

## Template plus delta: the cold-start rule for a playable genre

If the user asked for a playable game of a recognizable genre (first-person,
explorer, shooter, arena, voxel), the biggest waste is re-deriving a player,
camera, and controller by hand. The platform ships those as CERTIFIED starters.
Start from the closest one, then author only the DELTA.

- The default first-person controller starter is `first_person_template`
  (package key `package.launch.first_person_template`); it ships a possessable
  player with input, character movement, a collider, and a first-person camera
  already wired. This is the exact shape the trigger-participant work uses (KCC
  player, no RigidBody). Other playable starters include
  `three_d_explorer`, `first_person_explorer`, `voxel_frontier`,
  `hero_shooter_arena`, and `competitive_arena_5v5`.
  Call `engine_list_smart_asset_packages` to see every starter with its
  variants; the full id list is `CREATION_TEMPLATE_IDS` in the protocol package.
- Two corridors, and the scope rule that separates them:
  - Your conversation's own game is EMPTY and the user wants a playable genre:
    land the closest starter INTO this game with
    `project_apply_smart_asset_package` (`package_key`
    `package.launch.first_person_template`, plus an optional `variant_key`). A
    blank game is a genuinely empty graph, so the starter's own world and
    entities reconcile in cleanly. Then go to the recipe below and author the
    delta. This is the sanctioned blank-game exception to the world-identity
    scope rule.
  - The user explicitly asks for a NEW game from a template: `project_create_game`
    with `creationIntent { mode: "template", templateId }`. This MINTS A SEPARATE
    GAME and does not rebind this conversation, so only do it on an explicit
    new-game request, never as a silent switch of the game you are authoring.

## The recipe

1. Ensure a world exists. A blank game created with `creationIntent { mode:
   "blank" }` is an EMPTY graph (no world, no entities) - create one world with
   the `project.world.create` operation, or skip this step if you applied a
   starter above (the starter brings its own world).
2. Read what exists once: `project_get_graph_snapshot` returns the entities and
   the world(s), including anything a starter just added.
3. Read the operation catalog once: `world_build_get_operation_catalog`.
4. Structure in ONE document: land the delta static shell (floor, walls,
   pickups or obstacles, camera, sky, lighting - only what the starter did not
   already provide) with `world_build_apply_semantic_operations` as one atomic
   transaction. See authoring-with-the-world-build-document for the document
   shape and the arena worked example.
5. Behavior lands IN the document (the collectible score loop's components and
   script patch ride the same apply); only the HUD panel and any data store
   still use their precision tools after the apply. See game-loop-assembly for
   the assembly order and collectibles-and-scoring for the canonical collect count win loop.
6. Playtest: `world_playtest_scenario` to possess the player and prove the loop
   runs. See playtest-verification-loop. Then you are done.

## What is enough

For an arena class build (a floor, some walls, a set of pickups, a score, a win
condition, a HUD), steps 1 through 6 above are the whole job. You do not need
more than: this page, the operation catalog, and, when you reach the scoring
step, collectibles-and-scoring. Resist loading unrelated references.

## Verify

- `world_playtest_scenario`: possess the player, drive it, and confirm the after
  state actually changed. An unchanged after state is not proof the loop works.
- `project_get_graph_snapshot`: confirm the entities, script, and HUD panel exist
  at the expected revision.
