One click
How Export Works
Build ▸ Export Project… turns a project into a
standalone game: the game runtime plus your assets cooked and
packed into a single .hpak archive. The export runs
asynchronously with a live build log; you keep working while it
packs.
Cooking bakes assets into their runtime form — mesh vertex buffers, texture compression, precompiled material shader variants for the target backends, baked particle shaders — and rewrites all asset references as UUIDs so nothing resolves by fragile file paths at runtime.
Presets
Export Profiles
Exports are driven by named profiles stored in the project file — every project starts with Development (uncompressed, mods enabled) and Shipping (compressed + encrypted). Profiles are edited right in the export dialog and saved back with Save / Save As.
| Setting | Effect |
|---|---|
| Output Directory | Defaults to
<Project>/Export/<profile>. |
| Startup Scene | The scene the game boots into (defaults to the open scene). |
| Target Platform | Host / Windows / macOS / Linux — see below. |
| Compress assets | zstd (or LZ4HC) per-asset compression. |
| Encrypt assets | AES-256-GCM per-entry encryption — see Encryption. |
| Enable mod support | The shipped game mounts overlay paks from a
Mods/ folder. |
| Incremental packing | Unchanged assets are reused byte-for-byte from the previous export. |
| Compile HorizonCode | Translates all graphs to native C++. Compiler → |
| Exclude patterns | Content-relative globs
(e.g. Debug/*,
*_test.hasset) left out of the
pak. |
Cross-platform
Target Platforms
A profile targets Host (the machine you're on)
or cross-targets Windows,
macOS or Linux using the
per-platform game runtimes distributed with the editor. On macOS
the export can produce a signed, double-clickable
.app bundle — executable and
libraries in Contents/MacOS, the pak and config in
Contents/Resources, with a generated
Info.plist and code signature.
Python projects automatically bundle the Python runtime and standard library with the game, so it runs on machines without a Python install.
The archive
The hpak Archive
.hpak is the engine's pack format (version 2): a
table of contents indexed by asset UUID, followed by the
compressed data blocks. Everything the game needs goes in — every
cooked asset, all scenes in compact binary form, the GameInstance
graph, a scene index, and a path index so assets referenced by
path from scripts (for example widgets created with
createWidget("UI/HUD")) resolve too.
- Per-entry compression — zstd or LZ4; small or incompressible entries stay stored.
- Integrity — a TOC hash is verified at mount and every entry carries a content hash checked on read, so corrupted files fail loudly instead of glitching.
- Patch-friendly — archives support overlay mounting (the basis for mods and patches).
Protect
Encryption
With Encrypt assets on, every entry is encrypted with AES-256-GCM (a unique nonce per entry, with an authentication tag that makes tampering detectable). The key is generated at export and embedded into the game executable — on macOS the binary is re-signed after patching — so no key file ships next to the pak.
Honest scope: since the key necessarily ships inside the game, encryption is asset obfuscation — it keeps honest people honest and protects against casual extraction, but it is not a security boundary.
Fast re-exports
Incremental Packing
Each export writes a manifest next to the pak. On the next export, entries whose content and settings are unchanged are copied byte-for-byte from the previous archive — no recompression, no re-encryption (the previous key is reused so encrypted entries stay identical). Change one texture and only that texture repacks. Changing the codec or encryption settings invalidates the cache automatically.
At runtime
Streaming at Runtime
The exported game mounts the pak without parsing
it — startup doesn't block on loading everything up front. The
startup scene loads, and everything it references streams in on
background threads, following the asset reference graph
(scene → meshes → materials → textures). Completed loads register
on the main thread under a per-frame budget, so even a burst of
finished assets never causes a hitch. Additional scenes and zones
stream the same way through the
scene API.
Community
Mod Support
With mod support enabled, the shipped game scans a
Mods/ folder next to the executable and mounts every
.hpak it finds as an overlay, in
alphabetical order. An entry with the same UUID as a base asset
replaces it; new UUIDs add
content; later mounts shadow earlier ones. Mods can even replace
the startup scene. Mod paks are expected unencrypted — modders
build them with the same pack tooling.
On disk
What Ships
| File | Purpose |
|---|---|
<Game>.exe / HorizonGame |
The game runtime (with the embedded pak key when encrypted). |
| Engine libraries | Core/Scene/Rendering/Tools DLLs or dylibs, SDL3 — plus the C++ runtime on Windows. |
<Project>.hpak +
.hpak.manifest |
All assets; the manifest powers incremental re-exports. |
project.hcfg |
Runtime config — window title, startup scene pointer, mod flag. |
GameLogic.* (C++ projects) |
Your native gameplay library. |
HorizonCodeGen.* (compiled HC) |
The compiled HorizonCode classes. |
| Python runtime (Python projects) | Interpreter library, stdlib zip and native extensions. |
Mods/ (optional) |
Overlay paks, scanned at startup. |