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: first UI

On this page
On this pageChoose an ownerScene-owned UI entitySession HUDLayout tipsVerifyNext Back to top

Runtime UI is immediate-mode: each frame you rebuild widgets through the bound UI facade (const ui = hi.ui();). Nest controls in stacks (ui.vStack / ui.hStack) and always defer ui.end(scope).

Deep reference: User interface, UI layout, UI widgets, UI and editor, Motion Kit.

Choose an owner

UI kindOwnerLifetime
Screen / level-specific panelsScene entity updateDies with the scene
Cross-scene HUD / pause / settings chromeGameSubsystem.onTickSurvives scene replace

Do not hang tween timelines on UiContext — store drivers on entity or subsystem state (hi.motion).


Scene-owned UI entity

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

const HudLogic = hi.defineComponent(.{
    .name = "hud_logic",
    .storage = .embedded,
    .data = struct {
        pub fn update(_: *@This(), _: hi.ActorContext, _: *const hi.TickContext) void {
            const ui = hi.ui();

            const panel = ui.vStack(.{
                .position = .{ 16, 16 },
                .width = .{ .points = 240 },
                .padding = 12,
                .spacing = 8,
                .surface = .surface,
            });
            defer ui.end(panel);

            ui.text("Scene HUD", .{ .role = .secondary });

            if (ui.button("Reload", .{
                .id = "scene-hud.reload",
                .variant = .primary,
            })) {
                hi.world().requestSceneReload();
            }
        }
    },
});

pub const HudEntity = hi.defineActor(.{
    .archetype = "scene_hud",
    .components = .{HudLogic},
});

Place "archetype": "scene_hud" in the scene (no render/physics required). Rebuild, Play, and click the button.

Stable .id values matter when labels repeat — hit-testing keys off the id.

Sample overlays: session HUD profiler / G-buffer toggles in src/games/example/src/session_ui.zig (settings sheet). Scene-placed debug (debug_entity.zig) is an empty marker.


Session HUD

From GameSubsystem.onWorldAttach, reserve capacity for each World:

zig
const ui = hi.ui();
ui.reserveCapacity(64 * 1024, 64, 48);
ui.setDensity(.compact);

From onTick, draw the same stack pattern with hi.ui(). Full sample: src/games/example/src/session.zig — compact session card plus an optional non-modal settings sheet (graphics knobs, keybind legend) so the scene stays visible while tuning.

Modals: finish the page stack, then open beginModal at the root (see sample quit confirm). Prefer a second positioned vStack for settings/tools that should not dim the world.


Layout tips

  • Root stacks default near {16, 16}; use .width = .{ .percent = 0.30 } with min_width / max_width for responsive panels.
  • justify / flex reflow uses previous-frame geometry for hit-testing — expect a one-frame lag when a layout first appears.
  • Game theme is Theme.runtime(); do not copy the editor retained theme onto the runtime UI context.

Verify

  1. Play with a scene HUD entity or the sample session panel.
  2. Confirm entity UI clicks work only while Play (Edit freezes entity updates; GameSubsystem.onTick still runs in editor Play).
  3. Replace the scene — session HUD should remain; scene entity UI should disappear.

Next

  • First input action
  • First session services
PreviousTutorial: first session servicesNext Tutorial: first input action

Documentation follows the current engine checkout.

Snapshot cc148c75Source docs/tutorials/first-ui.md
On this pageChoose an ownerScene-owned UI entitySession HUDLayout tipsVerifyNext Back to top