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
Systems5 min read

Editor Project Selector

On this page
On this pageFlowZig toolchain discoveryWhere to read logsClosing a projectCode map Back to top

Launching hikari-editor without --project boots a full-screen project selector: the engine brand mark, an Open Project… action, and Exit.

text
hikari-editor                      # boots the project selector
hikari-editor --project=<path>     # opens the project directly (unchanged)

Flow

  1. No project argument. The native frontends (src/hikari/src/native_frontends/macOS/main.mm, src/hikari/src/native_frontends/Windows/main.cpp) pass an empty project path through the frontend ABI instead of rejecting the launch.

  2. Selector boot. src/hikari/src/application/editor_application.zig maps the empty path to a null Project. It skips the game-module compile worker and boots EditorApplication with boot_select_project = true and null project roots (all project inputs were already optional). The window uses a fixed Editor 1280×800 config since there is no project descriptor to read one from. Session scene_path is still anchored at staged <exe_dir>/data/untitled.json so content_root is product data/ — renderer device-init loads _engine/shaders from that tree even before a game project is open. A bare relative untitled.json would derive content_root="." and crash on shader load.

  3. Selection. Open Project… opens the platform's native folder dialog — NSOpenPanel on macOS, IFileOpenDialog with FOS_PICKFOLDERS on Windows (src/hikari/src/platform/dialogs.zig). The dialog is modal; cancelling returns to the selector.

  4. Validation. The chosen folder is opened with Project.open (src/hikari/src/editor/project.zig), the same code path a normal launch uses: hikari.project.json must exist and be com.hikari.project version 5 with a required durable UUID id (identity only — session policy lives in configs/*.json). engine_sdk may be a relative path, "bundled", or omitted (<exe_dir>/sdk if present, else walk parents for hikari/sdk). Failures surface as an inline message on the selector:

    FailureMessage
    descriptor missingThat folder has no hikari.project.json
    wrong kind / version / malformed JSONhikari.project.json is not a valid project descriptor
    engine SDK missingEngine SDK not found (<exe>/sdk, ancestor hikari/sdk, or set engine_sdk)
    anything elseCould not open the project — see the console log
  5. Editor version check. The editor compares current.version.number from its global identity (src/hikari/src/version.zig) to last_editor_version in hikari.project.json. Missing field = first open (no warning). A mismatch shows an Editor Version Changed alert (Open Anyway / Cancel). Cancel returns to the selector; Continue records the new version and proceeds.

  6. Open. On success the editor writes last_editor_version, spawns a fresh hikari-editor --project=<path> process, and closes itself. A session is composed around one project for its whole lifetime (asset roots, caches, the game-module build), so a process hand-off is the entire "open" implementation — the new process goes through the exact launch path a direct --project start uses, including the project's own window config. A direct --project= launch runs the same version check after boot (Cancel closes back to the selector).

Zig toolchain discovery

Game-module compile needs a Zig 0.16 toolchain. Before spawning zig build game-module, the editor runs a discovery phase (resolveZigExecutable in src/hikari/src/editor/project/zig_toolchain.zig) and picks the first usable candidate:

OrderSourceNotes
1HIKARI_ZIG_EXECUTABLEExplicit full path override
2<editor_exe_dir>/tools/zig/zig (.exe on Windows)Bundled SDK only if Kaji staged it via --vendor:zig=…bundle…
3PATHScan for zig / zig.exe
4Platform fallbacksmacOS: /opt/homebrew/bin, /usr/local/bin; Linux: /usr/local/bin, /usr/bin, Homebrew; Windows: C:\Zig, C:\Program Files\Zig

If none succeed, compile fails with guidance to rebuild with --vendor:zig=fetch+bundle, install Zig 0.16, or set HIKARI_ZIG_EXECUTABLE.

The winner is logged as Zig discovery: <source> plus Using <path> on the compile splash BUILD OUTPUT, and as std.log.info (Zig discovery: <source> → <path>) on the editor console / stderr / --log= file. Sources: HIKARI_ZIG_EXECUTABLE, tools/zig (bundled), PATH, platform fallback.

Packaged .app / Start Menu launches often have a stripped PATH (and no HOME). Shipping a self-contained editor means opting into --vendor:zig=bundle (usually fetch+bundle) at package time so step 2 hits. Without that flag, the editor still builds and packages — it just relies on discovery steps 1/3/4 at runtime. Zig caches are pinned under <project>/.engine/cache/game/zig/{local,global} so GUI launches do not hit AppDataDirUnavailable.

The game-module build also forwards the host product profile so GameModule validation matches the editor binary: -Doptimize=<builtin.mode> (Debug from --config=debug, ReleaseFast from --config=release) and the same -Dprofiler-timing / -Dprofiler-timing-markers / -Dprofiler-timing-pix / -Dprofiler-timing-xcode values baked into hikari_build_options when Kaji built the editor. Those flags appear on the compile splash as Profile …. Game modules compile against the thin hikari_game SDK only (no shared Entity/World layout). Editor recompile always adds -Deditor-contrib=true so projects may export registerEditor / hi.editor; standalone kaji game products leave that flag off (default false) so editor extension code is not compiled in. Details: Game editor SDK.

Where to read logs

SurfaceWhat it shows
Compile splash BUILD OUTPUTZig discovery source + path, then live Zig game-module compile lines (also the failure reason)
Editor console (bottom dock)Engine std.log after the splash closes
stderrSame engine log stream — visible when launching from a terminal
--log=<path> / HIKARI_LOG_FILERedirect engine NDJSON log file (default with project: .engine/logs/editor-latest.json; no file on selector-only boot)

Finder-launched .app bundles have no terminal; use the splash BUILD OUTPUT or relaunch with --log=….

Closing a project

When a project is open, File → Close Project relaunches the editor with no --project argument, landing back in the selector — the same hand-off as opening, in reverse. If the scene document has unsaved changes, the standard unsaved-changes dialog (Save / Discard / Cancel) runs first. The action is a no-op when the editor booted without a project.

Code map

PieceLocation
Selector screen (retained UI)src/hikari/src/editor/project_selector.zig
Boot flag + action handlingsrc/hikari/src/editor/editor_app/app.zig (boot_select_project); open/relaunch in editor_app/project_lifecycle.zig
Optional-project frontendsrc/hikari/src/application/editor_application.zig
Native folder dialog facadesrc/hikari/src/platform/dialogs.zig
macOS dialogsrc/hikari/src/native/macOS/src/services/Dialogs.m (engineDarwinPickFolder)
Windows dialogsrc/hikari/src/native/Windows/src/services/Dialogs.cpp (engineWindowsPickFolder)

The selector follows the compile-splash pattern: a full-screen retained-UI overlay owned by EditorApplication, updated at the top of tick, which early-returns while open so no editor chrome logic runs behind it. Linux has no native frontend yet; dialogs.pickFolder reports no selection there. Folder pick lives in the platform library (engineDarwinPickFolder / engineWindowsPickFolder).

PreviousEditor asset hot reloadNext Reference

Documentation follows the current engine checkout.

Snapshot cc148c75Source docs/systems/editor-project-selector.md
On this pageFlowZig toolchain discoveryWhere to read logsClosing a projectCode map Back to top