> ## Documentation Index
> Fetch the complete documentation index at: https://docs.eucaengine.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Simulation

> Drive the fixed-timestep tick loop by hand — step, play, pause, reset — and run a match through its lifecycle, watching the clock and scene change between calls. Built end to end on a local server.

The simulation is a **fixed-timestep loop**: each tick (`1/60 s`) runs the shared schedule — physics,
combat, status effects, abilities, AI, [rules](/concepts/rules-as-data) — over the
[world table](/concepts/world-as-table). Nothing happens between calls; you advance it explicitly with
`/step`, or hand control to the free-running loop with `/play` and `/pause`. Stepping is
[deterministic](/concepts/determinism): the same seed and inputs produce a bit-identical trajectory.
This page drives the loop and a match by hand; every command is real and runnable against a
[local server](/quickstart), with output captured from one.

## Drive the loop and run a match

**1. Check the clock.** `GET /` reports the engine rollup, including the current `tick`.

```bash theme={null}
curl -s http://localhost:3917/
# {"engine":"Euca Engine","version":"1.1.0","entity_count":107,"archetype_count":18,"tick":100}
```

(`entity_count` and `tick` reflect the loaded project the headless host boots, so your numbers will differ.)

**2. Spawn, then step.** `/step` advances N ticks and reports the new tick and live entity count. The
tick is `1/60 s`, so 60 ticks is one second.

```bash theme={null}
curl -s -X POST http://localhost:3917/spawn -H 'Content-Type: application/json' -d '{"health":100,"team":1}'
curl -s -X POST http://localhost:3917/spawn -H 'Content-Type: application/json' -d '{"health":100,"team":2}'

curl -s -X POST http://localhost:3917/step -H 'Content-Type: application/json' -d '{"ticks":60}'
# {"ticks_advanced":60,"new_tick":60,"entity_count":3}
```

A single `/step` is capped at 10,000 ticks per call — ask for more and it advances 10,000 and reports
the real count:

```bash theme={null}
curl -s -X POST http://localhost:3917/step -H 'Content-Type: application/json' -d '{"ticks":99999}'
# {"ticks_advanced":10000,"new_tick":10060,"entity_count":3}
```

**3. Free-run with play / pause.** These toggle the background loop instead of stepping by hand.

```bash theme={null}
curl -s -X POST http://localhost:3917/play
# {"ok":true,"message":"Simulation playing"}
curl -s -X POST http://localhost:3917/pause
# {"ok":true,"message":"Simulation paused"}
```

**4. Reset the scene.** `/reset` despawns every non-`Persistent` entity and reports how many it removed
— and crucially **leaves the tick counter alone**. It clears the scene, not the clock.

```bash theme={null}
curl -s -X POST http://localhost:3917/reset
# {"ok":true,"message":"Reset: despawned N entities. Tick: 10060"}

curl -s http://localhost:3917/
# tick is still 10060; entity_count dropped to whatever the project marked Persistent:
# {"engine":"Euca Engine","version":"1.1.0","entity_count":<persistent only>,"archetype_count":...,"tick":10060}
```

**5. Run a match lifecycle.** `/game/create` starts a match; `/game/state` reports the phase
(`lobby` → `countdown` → `playing` → `post_match`), `elapsed` time, and per-entity `scores`. Elapsed
advances as you step.

```bash theme={null}
curl -s -X POST http://localhost:3917/game/create -H 'Content-Type: application/json' \
  -d '{"mode":"deathmatch","score_limit":10,"time_limit":300,"respawn_delay":3}'
# {"ok":true,"message":"Match created: deathmatch, score limit 10"}

curl -s http://localhost:3917/game/state
# {"phase":"playing","mode":"deathmatch","elapsed":0.0,"scores":[]}

curl -s -X POST http://localhost:3917/step -H 'Content-Type: application/json' -d '{"ticks":180}'
curl -s http://localhost:3917/game/state
# elapsed advanced ~3s with the 180 ticks:
# {"phase":"playing","mode":"deathmatch","elapsed":2.9999979,"scores":[]}
```

## Behavior and gotchas

The things you only learn by running it:

* **`/reset` does not zero the tick.** The message above reports `Tick: 10060` after the reset, and
  `GET /` confirms the clock is unchanged. Reset clears entities, not time.
* **`/reset` keeps `Persistent` entities and clears the rest.** Ground and lights a project marks
  `Persistent` survive a reset; everything else is removed. How many entities remain depends on the
  served project — a world that marks nothing persistent drops to `entity_count: 0`. Use
  `POST /observe` as the authoritative read of what the scene holds after a reset —
  `GET /entities/{id}` may still answer `200` with a bare `{"id","generation"}` for
  an index that previously held an entity.
* **`/step` is capped at 10,000 ticks per call.** Larger `ticks` are clamped; `ticks_advanced` tells
  you what actually ran. Loop the call to go further.
* **`/game/state` before `/game/create` is an error, not an empty match.** It returns
  `{"error":"No game state. Use POST /game/create first."}`. Create the match first.
* **Entity transforms read `[0,0,0]` until the first `/step`.** `GlobalTransform` propagates on a tick,
  so step once after spawning before reading positions.

## Endpoints

| Method | Path           | Description                                                                              |
| ------ | -------------- | ---------------------------------------------------------------------------------------- |
| `POST` | `/step`        | Advance N ticks (capped at 10,000); reports `ticks_advanced`, `new_tick`, `entity_count` |
| `POST` | `/play`        | Hand control to the free-running loop                                                    |
| `POST` | `/pause`       | Pause the free-running loop                                                              |
| `POST` | `/reset`       | Despawn non-`Persistent` entities (the tick counter is left unchanged)                   |
| `POST` | `/game/create` | Start a match (`mode`, `score_limit`, `time_limit`, `respawn_delay`)                     |
| `GET`  | `/game/state`  | Match `phase`, `mode`, `elapsed`, and per-entity `scores`                                |

## What runs each tick

Physics integration, collision and the impulse solver, combat (damage / projectiles), status-effect
ticks, ability cooldowns, AI steering, navigation, and [rule](/concepts/rules-as-data) evaluation — all
in a fixed, deterministic order. See [Engine internals](/concepts/engine-internals) for the schedule
and [Determinism](/concepts/determinism) for the reproducibility guarantee.

## Status

* **Shipped, all headless** — manual `/step` with the 10,000-tick cap, the free-running play/pause
  loop, scene reset that preserves `Persistent` entities and leaves the clock untouched, and the match
  lifecycle (create + phase/elapsed/score state). Stepping is deterministic.

<Card title="Simulation endpoints" icon="play" href="/api-reference/introduction" horizontal>
  Step, play, pause, reset, and match-lifecycle endpoints, with request and response schemas.
</Card>
