Skip to content
hikari
RenderingEditorAIToolchainDocumentation
Download

© 2026 Flying Rat Studio.
All rights reserved.

Explore the engineDocumentationContributorsDownloadLicenseBack to top
Documentation / Tutorials
Browse docs
Overview
Tutorials17
OverviewPlay, Edit, and scenesFirst UI documentFirst game projectFirst entityComponent properties and the inspectorFirst mesh and materialFirst physics body and triggerFirst character controllerFirst session servicesFirst UIFirst input actionFirst messagesFirst runtime spawnFirst motionFirst skeletal animationAssets in Play (soft refs and hot reload)Dynamic editor recompile
Guides25
OverviewWorking in the editorDevelopment guideGameplay APIActor and component lifecycleThreads, jobs, events, and routinesGameplay AI tasksGame AI: perception and movement playgroundBrain assetsBrain execution for swarm populationsLocalizationGame cursorsChoosing component storageBuild and packagingProject filePluginsHikari Plugin APIData-driven content, JSON, and pathsScripting with KawaShader authoringChoosing and scaling shadowsTime of dayUser interfaceUI layoutUI widgetsMigration from Unity / Unreal
Systems32
OverviewArchitectureApplication lifecycleFrontends and driversPlatforms and supportSession services and cross-scene stateScenes and gameplayActor communication (hi.actors)Game-facing refsSave / replication wire versionCoordinate space and camera conventionsRenderingRenderer architecture mapFrame governorPipeline compilationSkeletal animationGPU particlesVisual ZonesVolumetric mediaInputAudioPhysicsMotion KitTemporal KitUI documentsAssets and ShinraPrefabsAsset residencyAsset formats (Shinra pipeline)Document schemasUI and editorEditor asset hot reloadEditor Project Selector
Language reference3
OverviewAkari GPU ABIAkari language referenceKawa language reference
Engine overview
Start exploring
  • No matching sections. Try fewer words or another topic.
NavigateEnter Openesc Close
Overview
Tutorials17
OverviewPlay, Edit, and scenesFirst UI documentFirst game projectFirst entityComponent properties and the inspectorFirst mesh and materialFirst physics body and triggerFirst character controllerFirst session servicesFirst UIFirst input actionFirst messagesFirst runtime spawnFirst motionFirst skeletal animationAssets in Play (soft refs and hot reload)Dynamic editor recompile
Guides25
OverviewWorking in the editorDevelopment guideGameplay APIActor and component lifecycleThreads, jobs, events, and routinesGameplay AI tasksGame AI: perception and movement playgroundBrain assetsBrain execution for swarm populationsLocalizationGame cursorsChoosing component storageBuild and packagingProject filePluginsHikari Plugin APIData-driven content, JSON, and pathsScripting with KawaShader authoringChoosing and scaling shadowsTime of dayUser interfaceUI layoutUI widgetsMigration from Unity / Unreal
Systems32
OverviewArchitectureApplication lifecycleFrontends and driversPlatforms and supportSession services and cross-scene stateScenes and gameplayActor communication (hi.actors)Game-facing refsSave / replication wire versionCoordinate space and camera conventionsRenderingRenderer architecture mapFrame governorPipeline compilationSkeletal animationGPU particlesVisual ZonesVolumetric mediaInputAudioPhysicsMotion KitTemporal KitUI documentsAssets and ShinraPrefabsAsset residencyAsset formats (Shinra pipeline)Document schemasUI and editorEditor asset hot reloadEditor Project Selector
Language reference3
OverviewAkari GPU ABIAkari language referenceKawa language reference
Engine overview
Tutorials3 min read

Tutorial: first runtime spawn

On this page
On this pageLayer membershipSpawn from a descriptorVerifyNext Back to top

Scene JSON is not the only way to create actors. Spawn at runtime from session code or an entity when content is dynamic (pickups, VFX hosts, debug helpers).

Deep reference: Session services — layer membership. Related: First session services.

Layer membership

APILayerSurvives additive unload?
Scene-authored actorLoading scene’s layerNo
w.spawn with .layer = .loosenull (loose)Yes (until replace unload / destroy)
w.spawn with .layer = .{ .layer = key }Named layerNo
w.spawn with .layer = .{ .inherit = id }Copied from parentDepends

In Play, the hierarchy Global group lists loose entities (layer_key == null).

Spawn from a descriptor

Game modules spawn through hi.world().spawn with a SpawnDesc. The host returns an ActorRef (EntityId is the same type — prefer ActorRef).

zig
const hi = @import("hikari_game");

const cube_mesh = hi.AssetRef.must(.model, "asset://./models/cube");
const pickup_material = hi.AssetRef.must(.material, "asset://./materials/cube");
const pickup_script = hi.AssetRef.must(.script, "asset://./scripts/pickup");

const w = hi.world();
const id = try w.spawn(&.{
    .archetype = "cube",
    .id = "pickup_01",
    .name = "Pickup",
    .active = true,
    .transform = .{ .position = .{ 0, 1, 0 } },
    .components = .{
        .physics = .{
            .body_type = .dynamic,
            .collider_shape = .sphere,
            .collider_radius = 0.35,
            .mass = 0.5,
        },
        .render = .{
            .geometry = cube_mesh,
            .material = pickup_material,
        },
    },
    .script = .{
        .mode = .override,
        .asset = pickup_script,
        .params_json = "{\"respawn_seconds\":5}",
    },
    .user_data_json = "{\"score\":100}",
    .layer = .loose,
});
_ = id;

Omit id (or pass "") to let the host generate a unique scene id. Prefer stable unique ids when you will look the actor up later — additive loads reject duplicates across layers.

The request can initialize parent, active state, transform, render, physics, camera, light, visual zone, audio, script parameters, and authored component fields. An override is accepted only when the archetype declares that capability. Asset references, JSON, component values, parent/layer handles, and the scene id are validated before the entity is published.

awake and start observe the complete initial state. A failed request is rolled back; it does not leave a partially configured entity in the world. Script mode defaults to the archetype script; use .none to suppress it or .override to replace it.

Kawa uses the same pipeline:

kawa
let pickup = World.spawn({
    archetype = "cube",
    id = "pickup_02",
    position = [2, 1, 0],
    user_data_json = "{\"score\":100}",
    components = {
        physics = { body_type = "dynamic", collider_shape = "sphere", collider_radius = 0.35, mass = 0.5 },
        render = { mesh = "asset://./models/cube", material = "asset://./materials/cube" }
    },
    script = { asset = "asset://./scripts/pickup", params_json = "{\"respawn_seconds\":5}" },
    layer = "loose"
});

Kawa returns an actor ref or nil when validation or spawning fails. script: nil suppresses the archetype default script. parent and inherit_layer accept actor refs; layer accepts "loose" or a loaded layer key.

Open scenes/runtime_spawn_showcase.json for a side-by-side executable example. The red group is spawned by spawn_showcase_zig_entity.zig; the blue group is spawned by assets/scripts/spawn_showcase_kawa.kawa. Each path creates a parented configured prop, a dynamic physics sphere, a runtime light, initial component data, and a configured child script.

scenes/runtime_spawn_showcase inherits the scene-placed anchor’s layer (inherit_layer / .layer = .{ .inherit = anchor }); step through the scene tour on the session HUD to reach it. Use .layer = .loose when the actor must survive additive unload.

Keep cross-scene policy on the subsystem; do not re-place a “manager” actor in every scene JSON.

Verify

  1. Spawn a loose cube from a button or onSceneLoaded.
  2. Additive-load then unload a layer — loose actor remains; layer actors disappear.
  3. requestSceneLoad (replace) — loose actors are torn down with the world rebuild.

Next

  • Play, Edit, and scenes
  • First physics
PreviousTutorial: first messagesNext Tutorial: first motion

Documentation follows the current engine checkout.

Snapshot 86f12d68Source docs/tutorials/first-runtime-spawn.md
On this pageLayer membershipSpawn from a descriptorVerifyNext Back to top