> Cinder 0.1.0 documentation: Sample game entry point
> Canonical page: https://cinder.ash10.dev/docs/examples/sample-game/ · Source: `sample/main.mojo` in the engine repository (engine commit 47c9352, imported 2026-11-09)
> Index of every page for agents: https://cinder.ash10.dev/llms.txt

# Sample game entry point

`sample/main.mojo` from the engine repository, verbatim: the entry point of the third-person sample game (ADR-0014). The game itself lives in `sample/game/` (components, levels, settings, gameplay) and is built only on public engine APIs.

```bash
tools/in_container.sh pixi run sample                    # windowed: arena level, WASD/Space, Esc for the menu
tools/in_container.sh pixi run sample -- --level sponza  # the Khronos atrium with a mesh collider
tools/in_container.sh pixi run sample-headless           # offscreen autopilot run
```

## `sample/main.mojo`

```mojo
"""Cinder sample game entry point.

    pixi run sample [--headless] [--level arena|sponza] [--autopilot] [--frames N] [--profile]
                    [--screenshot PATH]

`--headless` renders offscreen (tests, benchmarks); `--frames N` stops after N frames;
`--screenshot PATH` writes the last headless frame as a PNG.
"""
from std.sys import argv

from cinder.app import App, AppConfig, parse_app_args
from cinder.core.image import save_png

from game import SampleGame


def main() raises:
    var args = List[String]()
    var raw = argv()
    for i in range(1, len(raw)):
        args.append(String(raw[i]))
    var config = AppConfig(String("Cinder sample"), 1280, 720, False)
    var rest = parse_app_args(args, config)
    var level = String("arena")
    var autopilot = False
    var max_frames = -1
    var screenshot = String()
    var verbose = False
    var i = 0
    while i < len(rest):
        if rest[i] == "--level" and i + 1 < len(rest):
            level = rest[i + 1]
            i += 1
        elif rest[i] == "--autopilot":
            autopilot = True
        elif rest[i] == "--verbose":
            verbose = True
        elif rest[i] == "--frames" and i + 1 < len(rest):
            max_frames = Int(rest[i + 1])
            i += 1
        elif rest[i] == "--screenshot" and i + 1 < len(rest):
            screenshot = rest[i + 1]
            i += 1
        else:
            raise Error(t"unknown argument {rest[i]}")
        i += 1
    var game = SampleGame(level, autopilot)
    game.verbose = verbose
    config.render = game.settings.render_settings()
    var config_headless = config.headless
    var app = App(config^)
    var frames = 0
    while app.run_frame(game):
        frames += 1
        if max_frames >= 0 and frames >= max_frames:
            break
    if screenshot.byte_length() > 0 and config_headless:
        save_png(app.lib.ptr(), screenshot, app.read_frame())
    print(
        t"frames {frames}, collected"
        t" {game.collected}/{game.total_collectables}, won {game.won}, gpu"
        t" errors {app.gpu_error_count()}"
    )
    # The game holds physics and audio objects that live in the app: end it first.
    game.shutdown(app)
    _ = game^
    _ = app^
```
