---
title: "Quickstart"
description: "Your first world in 15 minutes - a numbered path from an empty workspace to a world open in Play, naming the real action and MCP tool for each step and what you should see after it."
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/start/quickstart/
---

# Quickstart: your first world in 15 minutes

{% version engineVersion="v1.0.232" coordinate="docs-public.v0" /%}

_Last verified 2026-09-03 against engine v1.0.232._

The shortest real path from an empty workspace to a **world** (a persistent, stateful environment) you can open in **Play**. Every step names the canonical **action** the workbench runs and the **MCP tool** an agent calls to run the same action, then states exactly what you should see before you move on. If a term is unfamiliar, the [Glossary](../glossary.md) defines it in one sentence; when you want the same path narrated in depth, follow [Tutorial: Create a World](../tutorials/create-a-world.md).

Two framings carry through every step:

- The backend owns the truth and the frontend is a projection of it, so the workbench and an MCP client funnel into the same canonical actions. See [Explanation: Backend Authority](../explanation/backend-authority.md).
- You ask the engine what exists before you name a field or a node; you never invent one. See [The Project Graph](../explanation/project-graph.md).

{% proof class="docs.quickstart" registry="docs/cycles/v1-engine-readiness-loop/PROOF_REGISTRY.json" status="pending" %}
This page is verified against the v1 docs export and the generated references. Runtime-sensitive claims still require their own receipts; seeing a scene render is not the same as proving playability.
{% /proof %}

## Before you start

You need a workspace and a project. A **project** (called a `game` in the control plane) is the container; a world lives inside it as persistent state. If you are driving from an MCP client rather than the workbench, point it at the Gessa MCP server first, following the [MCP quickstart](../../../creator/mcp/quickstart.md) and [security guide](../../../creator/mcp/security.md).

{% recipe id="zero-to-running-world" goal="From an empty workspace, create a world with a camera, a light, and a floor, attach behavior, and open it in Play" audience="both" %}

## 1. Discover the component contract

Ask the engine what exists before you set a field. List the built-in ECS component types with {% mcp-tool name="engine_list_component_types" /%} `engine_list_component_types`, then read one schema with {% mcp-tool name="engine_get_component_schema" /%} `engine_get_component_schema`. The canonical inventory these tools project is the generated [ECS component reference](../reference/ecs-components.md).

**You should see:** the built-in component types listed back, among them {% component name="TransformComponent" /%} `TransformComponent`, {% component name="CameraComponent" /%} `CameraComponent`, {% component name="LightComponent" /%} `LightComponent`, {% component name="RenderableComponent" /%} `RenderableComponent`, and {% component name="ColliderComponent" /%} `ColliderComponent`, and the field contract of the one schema you fetched.

## 2. Create the workspace and project

Create the workspace with {% action name="workspace.create" /%} `workspace.create`, then the project with {% action name="game.create" /%} `game.create` (MCP: {% mcp-tool name="project_create_game" /%} `project_create_game`).

**You should see:** a project id returned. Every later call in this quickstart carries it as `game_id`; note it now.

## 3. Create a world

Create a world inside the project with {% action name="project.world.create" /%} `project.world.create` (MCP: {% mcp-tool name="project_create_world" /%} `project_create_world`). Give it a stable key such as `main` so later calls can reference the world by key instead of by uuid.

**You should see:** a new, empty world under your project, addressable by its key. Nothing draws yet because the world has no entities.

## 4. Add a camera

A world that draws needs a viewpoint. Create an entity with {% action name="project.entity.create" /%} `project.entity.create` (MCP: {% mcp-tool name="project_create_entity" /%} `project_create_entity`), attaching `component.transform` and `component.camera` at creation. The highest-priority active {% component name="CameraComponent" /%} `CameraComponent` is what Play looks through.

**You should see:** a camera entity in the world outliner. The scene is still dark, but Play now has something to look through.

## 5. Add a light

Create a second entity with {% action name="project.entity.create" /%} `project.entity.create`, attaching `component.transform` and `component.light`.

**You should see:** the world is now lit, so whatever you place next will be visible rather than black.

## 6. Add a floor

Create a third entity with {% action name="project.entity.create" /%} `project.entity.create`, attaching `component.transform`, `component.renderable`, and `component.collider`. The floor is solid because of its {% component name="ColliderComponent" /%} `ColliderComponent`, not because it is drawn; rendering and collision are separate contracts. To change any component on an existing entity afterwards, use {% action name="project.entity.component.set" /%} `project.entity.component.set`, never a raw write to the model.

**You should see:** a lit surface in the viewport that draws and that something could rest on. You now have the minimum world that renders.

## 7. Attach behavior with Script Semantic Patch

Author behavior through typed, intent-level operations, never raw graph node ids. Create a script shell with {% action name="project.script.create" /%} `project.script.create` (MCP: {% mcp-tool name="project_create_script" /%} `project_create_script`) and attach it to an entity, then apply your intent with {% action name="project.script.patch.apply" /%} `project.script.patch.apply` (MCP: {% mcp-tool name="project_apply_script_semantic_patch" /%} `project_apply_script_semantic_patch`).

The MCP path accepts the `mcp_safe` operation pack, for example `addTickHandler`, `addTriggerHandler`, `attachComponentWithValidatedDefaults`, and `incrementNumericState`. The compiler lowers these into canonical Script IR; the generated source and the visual graph re-project from it. Read the generated [Script Semantic Patch reference](../../../spec/generated/script-semantic-patch.md) for the operation surface.

**You should see:** a script attached to the entity, with its source and node graph re-projected from the IR you never hand-wrote.

## 8. Generate an asset (optional)

To populate the world with a model, texture, or audio clip you did not build by hand, quote and create a generation job with {% action name="generation.job.quote" /%} `generation.job.quote` and {% action name="generation.job.create" /%} `generation.job.create` (MCP: {% mcp-tool name="generation_quote_job" /%} `generation_quote_job`, {% mcp-tool name="generation_create_job" /%} `generation_create_job`). Generation is asynchronous.

**You should see:** a job accepted and running. When the asset lands, reference it from an entity's {% component name="RenderableComponent" /%} `RenderableComponent`.

## 9. Open Play

Open **Play** in the workbench to run the world in a live session against authoritative state. Play is a workbench surface, not an MCP verb; there is no play tool in the MCP inventory.

**You should see:** the scene draw through your camera. That proves the world renders. It does not yet prove the world is **playable**.

{% /recipe %}

## Do not mutate the model directly

{% warning severity="critical" title="Every change goes through an action or a semantic operation" %}
Each step above uses a canonical action or a semantic-patch operation. Do **not** bypass them with raw Project Graph writes or hand-built Script IR node ids; those skip authority and validation. See [The Project Graph](../explanation/project-graph.md) and [How-To: Edit Components](../how-to/edit-components.md).
{% /warning %}

## What "running" does and does not mean

Opening Play and seeing the scene draw proves **renderability**, not **playability**. A Play proof in v1 additionally requires camera, spawn, and possession demonstrated under a live session, as [Explanation: Playability Proofs](../explanation/playability-proofs.md) makes precise. The engine is pre-launch: every row of the [v1 readiness ledger](../../../cycles/v1-engine-readiness-loop/FEATURE_LEDGER.json) is currently unaccepted, so treat this page as the intended contract, not a guarantee that a given world runs end to end today.

## Next steps

- Build the full first world step by step: [Tutorial: Create a World](../tutorials/create-a-world.md).
- Reach a real Play proof: [Tutorial: Create a Playable Game](../tutorials/create-a-playable-game.md).
- Follow the reader spine in order from here: [Journey: Get Started](../journeys/get-started.md).
- Drive everything from an agent: [How-To: Use MCP Tools](../how-to/use-mcp-tools.md).
