# Tutorial: first game project

What you need for a new game package the editor and Kaji can open. The sample under `hikari-games/example/` is the reference layout.

Deep reference: [Project file](/docs/guides/project-file.md), [Build and packaging](/docs/guides/build-and-packaging.md), [Frontends and drivers](/docs/systems/frontends-and-drivers.md).

## Layout

```text
my_game/
  hikari.project.json     # identity only (kind, version, id, name, source, assets, content_dirs)
  configs/
    game.json             # window + startup.scene
    render.json           # render pipeline
    drivers.json          # driver recipe
    editor.json           # editor recipe
    packaging.json        # kaji --package identity
    input_actions.json    # authored actions + default bindings (config://)
  packaging/
    icon.png              # used by kaji --package (optional macos.icon = Icon Composer .icon)
  src/
    root.zig              # exports config, content_manifest, optional GameSubsystem
    config.zig            # ProjectConfig Zig defaults
    entities/             # conventional; any .zig under src/ is discovered
      *.zig               # defineActor / defineComponent exports
  assets/                 # one authoring tree; folders are yours to choose
    scenes/main.json      # a scene is any .json with "kind": "com.hikari.scene"
    materials/ models/ textures/ scripts/ shaders/ …
```

`hikari.project.json` is identity only — durable `id` (UUID), `source`, `assets`, optional `content_dirs`, optional `engine_sdk` (omit or `"bundled"` → packaged SDK or parent walk). Zig `ProjectConfig` supplies defaults; present fields in `configs/*.json` win. Shipping identity is `configs/packaging.json` (optional nested `editor` for project-bound editor packages). The standalone editor (`kaji editor` with no `--project`) uses engine-owned `src/hikari/editor.project.json` ([Project file](/docs/guides/project-file.md)).

Minimal project descriptor for the layout above:

```json
{
  "kind": "com.hikari.project",
  "version": 5,
  "id": "b0d18223-4b45-4611-b17f-fcf4175a51b7",
  "name": "My Game",
  "source": "src",
  "assets": "assets"
}
```

> [!TIP]
> Generate a fresh UUID for each new project (`uuidgen` or any RFC 4122 v4 generator). The id is durable: keep it when renaming the folder or the display `name`.

## Minimum Zig exports

```zig
// root.zig
pub const config = @import("config.zig").config;
pub const content_manifest = @import("content_manifest.gen.zig");
// optional:
// pub const GameSubsystem = @import("session.zig").GameSubsystem;
```

```zig
// config.zig — Zig defaults (optional configs/*.json override field-by-field)
const hi = @import("hikari_game");

pub const config: hi.ProjectConfig = .{
    .game = .{
        .window = .{ .title = "My Game", .width = 1280, .height = 720 },
        .render = .{ .look = .{ .tonemap = .aces } },
        .drivers = .{ .physics = "tenkai3d", .scripting = "kawa", .game_ui = "hikari" },
    },
    // Editor viewport render/drivers inherit the game recipe at compose —
    // author those on `.game` (or configs/render.json / drivers.json), not here.
    .editor = .{
        .window = .{ .title = "My Game Editor", .width = 1600, .height = 1000 },
    },
    .startup = .{
        .scene = "scenes/main", // extension-free stem (no .json / .shinscene)
    },
};
```

Optional override in `configs/game.json` (JSON wins when present):

```json
{
  "kind": "com.hikari.config.game",
  "version": 1,
  "window": { "title": "My Game — development" }
}
```

## Add a startup scene

Create `assets/scenes/main.json`. This empty level uses the built-in camera and needs no model, material, or game actor declarations:

```json
{
  "kind": "com.hikari.scene",
  "version": 1,
  "id": "main",
  "name": "Main",
  "primary_camera_id": "camera",
  "actors": [{
    "id": "camera",
    "archetype": "camera",
    "transform": { "position": [0, 2, 5] },
    "components": { "camera": { "fov": 60, "near_plane": 0.1, "far_plane": 1000 } }
  }]
}
```

The editor can now open the scene. Play has no visible geometry or controls yet; add those in the following tutorials. For gameplay input, copy `configs/input_actions.json` from the example project or follow [First input action](/docs/tutorials/first-input.md).

The example game itself uses `"assets": "."` and has scenes at its project root; its paths differ from this layout. For a populated starting point with dependencies already present, copy the complete example project, generate a new project UUID, and keep its assets root and startup scene until you replace them.

## Build and open

```bash
bin/kaji/kaji editor --workspace="$PWD" --project=/path/to/my_game --type=dynamic --config=debug --run
```

Or open the editor without `--project` and use the project selector. Generated editor state lands in `my_game/.engine/` — do not commit it.

## Gotchas

- Prefer `--project=` (never rely on a bare positional path through Kaji).
- Author under the project assets root — never into packaged `bin/.../data/scenes`.
- After changing `Entity` / `World` layouts in the engine, fully rebuild the editor for dynamic games (not only Recompile). See [Dynamic editor recompile](/docs/tutorials/dynamic-recompile.md).

## Next

- [First entity](/docs/tutorials/first-entity.md)
- [First session services](/docs/tutorials/first-session-services.md)
