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 input action

On this page
On this page1. Add an action2. Read from Zig3. Read from KawaVerifyNext Back to top

Gameplay code should read named actions, not raw key codes. Bindings live in JSON; Zig and Kawa both resolve the same ids.

Deep reference: Input.

1. Add an action

Edit configs/input_actions.json in your project (runtime path config://input_actions.json — not in startup config). Add an entry to the "actions" array:

json
{
  "kind": "com.hikari.config.input_actions",
  "version": 2,
  "actions": [
    {
      "id": "interact",
      "bindings": {
        "keys": ["r"],
        "gamepad_buttons": ["x"]
      }
    }
  ]
}

Bindings use readable control names, and arrays allow more than one control from the same device. Omit fields that do not apply; the defaults are scale 1, deadzone 0.15, and player 0. See the input reference for every accepted name and scalar-axis examples.

Rebuild / relaunch so the action map reloads.

2. Read from Zig

In an entity update:

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

pub fn update(_: *@This(), _: hi.ActorRef, _: *const hi.TickContext) void {
    if (hi.world().actionPressed("interact")) {
        std.log.info("interact", .{});
    }
}

Held state is hi.world().actionHeld("move_forward"). actionReleased reports the release edge, while actionValue returns a named scalar from digital pairs, gamepad axes, mouse delta, or wheel input. Compose two named scalars with actionVector2:

zig
const move = hi.world().actionVector2("move_x", "move_y");

Use actionBinding / setActionBinding for runtime rebinding. Changes affect the next input resolve and differences from authored defaults persist in the user's sparse configs/input_bindings.json when the session shuts down. Projects continue to own the action list and defaults in configs/input_actions.json. The current desktop input backend owns player slot 0; other player slots return disconnected until multi-controller backend support lands.

Samples: player_entity.zig (actionHeld for move); session HUD toggles profiler/visualizers in session_ui.zig (F3/F4/F5/F6).

3. Read from Kawa

kawa
fn update(dt, total_time) {
    _ = dt;
    _ = total_time;
    if (Input.pressed("interact")) {
        Debug.log("interact");
    }
    if (Input.held("move_forward")) {
        // ...
    }
}

Sample: assets/scripts/camera_controller.kawa (Input.held("move_forward"), Input.mouse_left / mouse_delta + Actor.set_rotation_euler for view).

Verify

  1. Play the scene that contains your entity/script.
  2. Press the bound control — log line or gameplay response once per press (pressed) vs while held (held).
  3. Confirm Edit mode does not run entity updates (actions will not fire there).

Next

  • First messages
  • First entity — attach the action to a new actor
PreviousTutorial: first UINext Tutorial: first messages

Documentation follows the current engine checkout.

Snapshot cc148c75Source docs/tutorials/first-input.md
On this page1. Add an action2. Read from Zig3. Read from KawaVerifyNext Back to top