Skip to content
hikari
RenderingEditorAIToolchainDocumentation
GitHub
hikari

© 2026 Flying Rat Studio.
All rights reserved.

Explore the engineDocumentationContributorsLicenseBack to top
Documentation / Systems
Browse docs
Overview
Tutorials16
OverviewFirst game projectFirst entityAuthored user_data and the inspectorFirst mesh and materialFirst physics body and triggerFirst character controllerFirst session servicesFirst UIFirst input actionFirst messagesPlay, Edit, and scenesFirst runtime spawnFirst motionFirst skeletal animationAssets in Play (soft refs and hot reload)Dynamic editor recompile
Guides16
OverviewDevelopment guideGameplay APIChoosing component storageBuild and packagingProject filePluginsHikari Plugin APIData-driven content, JSON, and pathsScripting with KawaShader authoringTime of dayUser interfaceUI layoutUI widgetsMigration from Unity / UnrealActor and component lifecycle
Systems28
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 governorGPU particlesVisual ZonesVolumetric mediaInputAudioPhysicsMotion KitTemporal KitAssets and ShinraPrefabsAsset residencyAsset formats (Shinra pipeline)UI and editorEditor asset hot reloadEditor Project Selector
Language reference2
OverviewAkari language referenceKawa language reference
Engine overview
Start exploring
  • No matching sections. Try fewer words or another topic.
NavigateEnter Openesc Close
Overview
Tutorials16
OverviewFirst game projectFirst entityAuthored user_data and the inspectorFirst mesh and materialFirst physics body and triggerFirst character controllerFirst session servicesFirst UIFirst input actionFirst messagesPlay, Edit, and scenesFirst runtime spawnFirst motionFirst skeletal animationAssets in Play (soft refs and hot reload)Dynamic editor recompile
Guides16
OverviewDevelopment guideGameplay APIChoosing component storageBuild and packagingProject filePluginsHikari Plugin APIData-driven content, JSON, and pathsScripting with KawaShader authoringTime of dayUser interfaceUI layoutUI widgetsMigration from Unity / UnrealActor and component lifecycle
Systems28
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 governorGPU particlesVisual ZonesVolumetric mediaInputAudioPhysicsMotion KitTemporal KitAssets and ShinraPrefabsAsset residencyAsset formats (Shinra pipeline)UI and editorEditor asset hot reloadEditor Project Selector
Language reference2
OverviewAkari language referenceKawa language reference
Engine overview
Systems4 min read

Game-facing refs

On this page
On this pageZigKawaDemo Back to top

Game-facing identity handles. The only way game code (Zig / Kawa) references things.

TypeSchemeUse forNot for
AssetRefasset://… stem + AssetKindCooked assets: texture, model, material, model_doc, audio, collision, script, shader, font, sprite_atlas, prefab, particle, animation_graphJSON tables, OS paths, cooked suffixes, skybox (use a .texture ref)
ContentRefcontent:// (dirs allowlist, AssetStore only) · writable:// / project:// (FS)Tables, configs, savesScenes, cooked assets
SceneRefrelative stem scenes/foo (runtime: cooked .shinscene; authoring .json Debug only)Level load via AssetStoreContent tables, free-form content
PrefabRefrelative stem prefabs/foo (runtime: cooked .shinprefab; authoring .prefab.json Debug only)Prefab retain / spawnScenes, loose content
ActorRefgeneration handle (EntityId alias)Live actors (find / send / bind)Strings as “entities”
VoiceHandlegeneration-checked slotLive audio voice from hi.audio().playCue / crossfadeCue paths (use AssetRef)

Note

AssetRef paths are extension-free. Disk names (.shinmodel, .shintexture, …) belong to packaging. AssetStore / Shinra maps AssetKind to the on-disk suffix; game code never writes cooked extensions.

URI forms (full rules: Assets and Shinra — Asset URIs and packs):

FormMeaning
asset://<pack>/<logical>Explicit pack; that pack must be retained by the scene root packs array
asset://./<logical>Unscoped absolute logical path; product catalog maps path → pack; that pack must be retained. Not FS-relative

There is no pack-search form. Seal enforces one path → one pack.

Path identity (engine internals): Shinra pipeline events may still emit cooked suffixes. Compare stems with asset_kind.stemsEqual / asset_deps.stemsEqual (not bare string/pathsEqual). Scenes use scene_ref.stemOf / withAuthoringJson / withCooked for store and editor disk loads.

Shaders are AssetKind.shader but identity is a package id (gbuffer_wacky, _engine/gbuffer), not a file stem. Platform expand lives in graphics/material/shader_artifact.zig (Metal one .metallib; D3D12 _vs_/_ps_/_cs_.cso). Materials still set shader.package; runtime acquires expanded store paths only for the synchronous native copy/compile and then releases them. Session launch binds AssetStore; device-init must follow launch.

Not refs (plain names): archetype, input action, message name, physics preset, audio bus.

Engine-internal native atoms (AudioHandle, RenderHandle, PhysicsHandle in src/hikari/src/native/handle.zig) back subsystem tables — games use AssetRef for cue paths and VoiceHandle for live voices.

API surfaceType
RenderUpdate.mesh / .material / .albedoAssetRef (kinds .model / .material / .texture)
setSkyboxTexture / attachSessionScript / defineActor(.{ .script = … })AssetRef (skybox = .texture; script = .script)
paths.read / json.parseRefContentRef (content:// first segment ∈ project content_dirs)
requestSceneLoad (replace / additive)SceneRef
retainPrefab / spawnPrefabPrefabRef
find / findBySceneId / findByName / raycast hit / spawn return / lifecycle idActorRef
hi.audio().playCue / crossfade returnVoiceHandle
Procedural setMesh(vertices)no asset (CPU verts only)

Dead / invalid ActorRef → host no-ops (never crash). Bad AssetRef / ContentRef → validate fail / soft no-op.

Implementation: sdk/src/asset_ref.zig, content_ref.zig, scene_ref.zig, prefab_ref.zig, actor_ref.zig. Kind + suffix table: sdk/src/asset_kind.zig (engine assets/asset_kind.zig re-exports). Host: host_api.zig + game_api/host_bind.zig.

Zig

zig
const tex = hi.AssetRef.must(.texture, "asset://./textures/pbr_capsule_albedo");
const mat = hi.AssetRef.must(.material, "asset://./materials/default");
const cfg = hi.ContentRef.must("content://resources/ref_demo.json");

var parsed = try hi.json.parseRef(Config, allocator, cfg);
defer parsed.deinit();

const target = hi.world().find("target_zig");
if (!hi.world().isAlive(target)) return;

try hi.render().applyRender(target, .{
    .mesh = hi.AssetRef.must(.model, "asset://./models/cube"), // optional
    .material = mat,
    .albedo = tex,
    .notify_dirty = true,
    .release_primitive = true,
});

hi.world().send(target, ping);
hi.world().send(hi.ActorRef.invalid, ping); // no-op

hi.world().requestSceneLoad(hi.SceneRef.must("scenes/refs_demo"), .{});
  • Literals: AssetRef.must(kind, uri) / ContentRef.must / SceneRef.must (comptime non-empty; scene/asset cooked suffixes are compile errors).
  • Dynamic strings: tryFrom then host validate.
  • EntityId is an alias of ActorRef.

Kawa

text
World.find(id) / Actors.find(id)        → ActorRef | nil
Actor.is_alive / Actors.is_alive / send → safe on dead
Actors.has / get_number / set_number    → component fields by name (dead → false/nil)
Content.read("content://…")            → string | nil   (content_dirs + AssetStore; no FS fallback)
Render.set_material(actor, mat [, alb])→ asset:// stems only (no .shin*)
Scene.set_skybox_texture("asset://…")  → asset:// stem (primary)
Scene.set_skybox_texture_secondary(…)  → asset:// stem (secondary)
Scene.set_skybox_blend(t)              → dual cubemap mix [0,1]
Scene.load("scenes/foo")               → SceneRef stem (not content://; not .json)

ActorRef is weak (holding a ref never keeps an actor alive). Prefer Actors.* / hi.actors for new find/send/field access; full guide: Actor communication.

Demo

scenes/refs_demo (Browse scenes → Tutorials → References; on disk refs_demo.json / .shinscene):

ActorRole
target_zig / target_kawaref_target — flash on ping
driver_zigContentRef read → AssetRef material+albedo → ActorRef message
driver_kawascripts/ref_demo — same

Data: resources/ref_demo.json, resources/ref_demo_note.txt.

PreviousActor communication (hi.actors)Next Save / replication wire version

Documentation follows the current engine checkout.

Snapshot cc148c75Source docs/systems/refs.md
On this pageZigKawaDemo Back to top