Skip to content
hikari
RenderingEditorAIToolchainDocumentation
GitHub
hikari

© 2026 Flying Rat Studio.
All rights reserved.

Explore the engineDocumentationContributorsLicenseBack to top
Documentation / Tutorials
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
Tutorials2 min read

Tutorial: authored user_data and the inspector

On this page
On this page1. Declare fields + metadata2. Seed from scene JSON3. Verify in the editorNext Back to top

Supported logic-component fields become scene user_data and inspector properties automatically. metadata.properties is optional presentation and policy metadata; use it to rename, constrain, hide, order, or choose a widget for a field. Edit in the inspector in Edit mode; values seed the live actor on Play / scene load.

Deep reference: Scenes and gameplay. Sample: cube_entity.zig (health / max_health + transient current_health).

1. Declare fields + metadata

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

const BeaconLogic = hi.defineComponent(.{
    .name = "beacon_logic",
    .storage = .embedded,
    .data = struct {
        spin_speed: f32 = 1.0,
        label_color: [3]f32 = .{ 1, 1, 1 },
        /// Not serialized / not shown in the inspector.
        runtime_angle: f32 = 0,

        pub const metadata = .{
            .properties = .{
                .spin_speed = hi.UserDataPropertyOptions{ .label = "Spin Speed", .min = 0, .step = 0.05 },
                .label_color = hi.UserDataPropertyOptions{ .label = "Color", .min = 0, .max = 1, .step = 0.01 },
                .runtime_angle = hi.UserDataPropertyOptions{ .transient = true },
            },
        };

        pub fn onChanged(self: *@This(), actor: hi.ActorContext, property: []const u8) void {
            const id = actor.id;
            _ = .{ self, id, property };
            // React to inspector edits while live (Edit preview / Play).
        }

        pub fn update(self: *@This(), _: hi.ActorContext, ctx: *const hi.TickContext) void {
            self.runtime_angle += self.spin_speed * ctx.dt;
        }
    },
});

pub const BeaconEntity = hi.defineActor(.{
    .archetype = "beacon",
    .components = .{BeaconLogic},
});
OptionEffect
.label, .tooltip, .min, .max, .step, .orderInspector presentation and ordering
.hidden = trueOmitted from the authoring surface; typed gameplay code still owns the field
.transient = trueNot authored in scene JSON; skipped by applyJson
metadata = .{ .runtime_only = true }No editor property schema; scene user_data may still seed JSON-safe fields

runtime_only means “no inspector sheet”, not “cannot place in a scene” and not “scene cannot seed”. JSON-safe POD fields (bools, numbers, vectors, nested POD structs) still load from user_data; pointer/slice fields and anything marked transient are skipped. Reflection and metadata are compile-time/static declaration work: component instances gain no property bags, maps, allocations, or per-tick reflection.

2. Seed from scene JSON

json
{
  "id": "beacon_01",
  "archetype": "beacon",
  "transform": { "position": [0, 1, 0], "rotation_euler": [0, 0, 0], "scale": [1, 1, 1] },
  "user_data": {
    "spin_speed": 2.5,
    "label_color": [0.2, 0.8, 1.0]
  }
}

Omit keys to keep struct defaults. Multiple actors can share an archetype with different user_data (see demo disco_light_*).

3. Verify in the editor

  1. Rebuild, open the scene, select the actor.
  2. Inspector shows Spin Speed / Color; change a value — onChanged runs when live.
  3. Save the scene and confirm user_data persisted (non-transient fields only).

Next

  • First motion — tween those fields
  • First mesh and material
PreviousTutorial: first entityNext Tutorial: first mesh and material

Documentation follows the current engine checkout.

Snapshot cc148c75Source docs/tutorials/first-user-data.md
On this page1. Declare fields + metadata2. Seed from scene JSON3. Verify in the editorNext Back to top