@awaken/assets
Asset storage, the shared import IR, every model/engine importer, and the persistence formats. It depends on @awaken/core and @awaken/render (for MeshData, Material, and texture types).
This package is the seam between importing (turning a Unity/Godot/Unreal/glTF project into engine data) and shipping (writing that data to a binary project or a self-contained game file).
ts
import { AssetStore, spawnImportedScene, encodeProject, bundleToSceneFile } from "@awaken/assets";AssetStore
The in-memory library of everything a scene references, keyed by string id. It is data-only - the renderer uploads from it, the animation system reads skeletons/clips/skins from it.
| Member | Type | Description |
|---|---|---|
meshes | Map<string, MeshData> | Geometry by mesh id. |
textures | Map<string, TextureData> | Device-neutral texture pixels by id. |
materials | Map<string, Material> | Authored materials by id. |
skeletons / clips / skins | Map<string, …> | Skeletal-animation assets (skins keyed by the skinned mesh id). |
revision | number | Bumped on every add/replace, so a per-frame uploader can skip re-scanning when nothing changed. |
addMesh/addTexture/addMaterial/addSkeleton/addClip/addSkin | (id, data) => void | Register an asset. |
addSound | (id, bytes, mime) => void | Register an imported sound (encoded bytes, decoded by the audio engine at load). See Audio. |
has/hasTexture/hasMaterial, list/listTextures/listMaterials | - | Membership + key listing. |
TextureData stores pixels device-neutral (data is RGBA8, with an optional role), so the renderer can compress for the local GPU at upload - a project ships safely to any device.
Import IR (types)
Every importer produces the same ImportedScene intermediate representation, so one consumer (spawnImportedScene) handles all sources. See the Import Overview for the pipeline philosophy.
| Symbol | Shape | Description |
|---|---|---|
ImportedScene | { meshes: ImportedMesh[]; roots: ImportedNode[]; skeletons?; clips? } | The whole imported scene. |
ImportedMesh | { id; data: MeshData; color; modelName?; submesh?; skin? } | One mesh + its default colour and optional per-vertex skin binding. |
ImportedNode | { name; position; rotation; scale; meshId; children; animator? } | One node in the imported hierarchy. |
spawnImportedScene
The single consumer of the IR: register the scene's assets in an AssetStore, then instantiate its node hierarchy into a World as GameObjects with MeshRenderer components.
| Symbol | Signature | Description |
|---|---|---|
spawnImportedScene | (world, scene, store, opts?) => Entity[] | Register meshes/skeletons/clips/skins, spawn the node tree, return the root entities. opts.onAnimator is called for skinned nodes so the caller can attach an Animator (the assets layer can't reference the runtime type). |
AnimatedNode | { entity; clip; skeleton } | Reported for each skinned node via onAnimator. |
Importers
Each importer parses a source format into an ImportedScene (or a richer result for whole-project imports). They are all generic - no model-pack-specific hardcoding.
| Format | Entry point(s) |
|---|---|
| glTF / GLB | importGltf(bytes, name), parseGlb, parseGltfJson, importModel(bytes, name) (auto-detects glTF/GLB/OBJ) |
| OBJ | parseObj(text, idPrefix) |
| FBX | (the fbx module - parsed via importModel / the editor's import flow) |
Unity .unitypackage | isUnityPackage(entries), parseUnityScene(…), parseMaterial, prefab helpers |
Unreal .uasset / project | decodeUassetStaticMesh, parseUassetTexturePng, isUnrealProject, importUnrealProject(files, onProgress?) |
| Godot | parseGodotText, parseGodotMeshResource, parseGodotMeshSurfaces, plus the godotImport IR types |
| Retarget / anim | makeRetargeter, buildCharSkeleton, buildIdleClip, remapSkin |
Awaken file formats also round-trip here: parseMaterialFile/serializeScriptFile/parseScriptFile/serializePrefabFile/parsePrefabFile. See Import Overview and the per-engine pages (Unity, Godot, Unreal, Models).
Geometry helpers
| Symbol | Signature | Description |
|---|---|---|
weldMesh | (m: MeshData) => MeshData | Merge duplicate vertices (shrinks geometry before shipping). |
quantizePositions / dequantizePositions | (Float32Array) ⇄ (Uint16Array + PosBbox) | Positions → u16 over the mesh AABB, and back. |
quantizeNormals / dequantizeNormals | (Float32Array) ⇄ Int8Array | Normals → octahedral int8, and back. |
quantizeUvs / dequantizeUvs | (Float32Array) ⇄ (Uint16Array + UvBbox) | UVs → u16 over the UV bbox, and back. |
Quantization cuts per-vertex bytes ~32 → ~12 and is idempotent (a value on the grid re-quantizes to the same index), so re-saving never compounds error. It backs both the binary project and the shipped scene file.
Persistence
Two output formats, both defined here. Their exact byte-level shapes and version relationship are in Data Formats & Versions.
The binary project (.awaken)
A glTF-.glb-style container: a JSON metadata chunk followed by one binary blob holding every mesh/texture byte and every baked clip's keys.
| Symbol | Signature | Description |
|---|---|---|
PROJECT_VERSION | 15 | Current project format. v15 stores each RGBA texture as a PNG file in the blob instead of deflated pixels; v14 saves the open world once (sceneRef names the library scene it copies) and stores baked clip keys as exact float64 blob spans instead of JSON; v13 gives font faces a family, weight, style and licence; v12 adds Simulations and Time settings; v11 render textures and render layers; v10 compute shaders; v9 App Settings; v8 UI images; v7 deflated texture pixels; v6 adds each script's uses list (the modules it runs jobs on); v5 added a script's language, folding v4's separate modules map into scripts; v4 added native module assets; v3 persisted the skeletal-animation library and particle-effect metadata; v2 quantized meshes; v1 stored raw f32. |
ProjectBundle | interface | The in-memory round-trip shape: scene, scenes, entry, open (which library scene the open world is, so a reopened project edits that scene and its look, and the export ships those edits), prefabs, scripts, materials, meshMaterials, materialAssets, render, dock, assetSources, meshes[], textures[]. |
encodeProject | (b: ProjectBundle) => Uint8Array | Serialize a bundle to the AWKN binary (quantizes meshes). |
decodeProject | (bytes: Uint8Array) => ProjectBundle | Parse it back (dequantizes to Float32Array, so the in-memory MeshData is identical either way). |
The shipped scene (SceneFile JSON)
The self-contained JSON the standalone player loads as scene.awaken.json.
| Symbol | Signature | Description |
|---|---|---|
SCENE_FILE_VERSION | 1 | Current ship-file format. |
SceneFile | interface | { version, title?, entry?, scene, meshes: MeshJSON[], prefabs?, scenes?, scripts?, compiled?, materials?, meshMaterials?, shaders?, textures?, render? }, plus everything a shipped game needs to animate and play: skeletons?, clips?, skins?, animGraphs?, particleEffects?, uiClips?, fonts?. volumes? is read-only legacy, kept so games exported before volumes became components still grade. |
MeshJSON | interface | One mesh's geometry as base64 typed-array bytes, optionally quantized (q) with bbox/uvbb; indices are u16 (idx16) when the mesh has < 65536 verts. |
ScriptAsset / ScriptMap | { name, source, kind?, language?, uses?, obfuscation? } / Record<string, ScriptAsset> | Scripts keyed by stable id, so renaming is safe. kind "editor" or "plugin" is not shipped; language picks the toolchain (typescript by default, or assemblyscript/c, which compile to wasm and run as jobs); uses lists the modules this script runs jobs on. What a script can do is inferred from what it exports, not from language. |
meshToJSON | (id, data) => MeshJSON | Encode one mesh (quantized) for the ship file. |
loadScene | (world, assets, types, file) => void | Load a SceneFile into a world + asset store (dequantizes meshes). |
loadSkeletalAssets | (assets, file) => void | Register a ship file's skeletons, clips, skins, anim graphs, particle effects and UI clips into an asset store. |
bundleToSceneFile | (b: ProjectBundle) => SceneFile | The export seam - convert an editor project bundle into the shippable JSON. |
normalizeScripts | (raw) => ScriptMap | Accept the legacy name → source shape and return the current id-keyed shape. |
bundleToSceneFile is a pure function, so it currently ships geometry + vertex/material colour but not albedo textures (encoding base64 PNG needs a browser canvas the editor supplies separately). See Export to a game file.
The ship container
An optional single-blob binary wrapper around a SceneFile + its meshes (used by the compressed export path).
| Symbol | Signature | Description |
|---|---|---|
encodeSceneContainer | (base, meshes) => Uint8Array | Pack a SceneFile (sans meshes) + mesh buffers into one blob. |
decodeSceneContainer | (bytes) => { file, meshes } | Unpack it. |
isSceneContainer | (bytes) => boolean | Magic-number check. |
compactSceneForShip | (scene, types) => SceneJSON | Drop editor-only data to slim the shipped scene. |
App Settings
The project's app identity and store setup, which both exports read. See App Settings.
| Symbol | Signature | Description |
|---|---|---|
AppSettings | interface | name, shortName, id (bundle id), version, build, orientation, icon and launch designs with their images, developerReadout, androidBackup, saveKey, androidKey and store products. |
resolveApp | (app, sourceName) => ResolvedApp | The app as the exports write it: what is set, the rest derived from the project's file name. |
appProblems | (app) => string[] | Why these settings cannot be exported, one sentence each; empty when they can. |
exportedApp | (app) => AppSettings | null | The settings an export writes, or null when the project has none worth writing. |
drawIcon / drawLaunchLogo | (app, images, ...) => Rgba | Render the icon for a target and size (full, or one adaptive-icon layer), and the launch-screen logo. |
encodePng / encodeIco | (img, opts?) => Uint8Array | Standard 8-bit PNG (RGB without alpha for the iOS icon); a multi-size .ico. |
StoreProduct / StoreSettings | interface | One product the game sells, and the list (at most STORE_MAX_PRODUCTS = 100). See In-app purchases. |
isSaveKey | (v) => boolean | A well-formed save key: 64 hex characters. |
Fonts and audio
| Symbol | Signature | Description |
|---|---|---|
FontAsset | interface | One imported font face: bytes, mime, and family, weight, style, variable range and licence. A face from an older project reads as family = its id, weight 400, normal style. |
fontFaceMeta / fontFaceRule | functions | The face fields worth writing, and the @font-face rule that registers a face at a URL. |
isOggOpus / OGG_OPUS_MIME | (bytes) => boolean / "audio/ogg; codecs=opus" | Detect an Ogg stream carrying Opus, the recommended format: iOS Safari cannot decode Ogg Vorbis. See Audio. |
Terrain, clips and update shaders
| Symbol | Signature | Description |
|---|---|---|
packTerrain / terrainToJSON / terrainFromJSON | functions | Write a terrain asset into the project blob or a shipped scene, and read it back. See @awaken/terrain. |
packClips | (clips, push) => Record<string, PackedClip> | Pack baked clip keys into the project blob as exact float64 spans (project v14). |
PNG_TEXTURES_VERSION | 15 | The first project version whose RGBA textures are stored as PNG files. |
CompiledUpdateShader / packUpdateUniforms | interface / function | An update graph compiled for a Simulation pass, and the uniform block for one pass (the same packing the renderer uses, so the editor preview and a running Simulation agree). |
buildRigProfile | (skel, id) => RigProfile | Map a skeleton onto canonical humanoid slots by name-anchored endpoints and structural paths, for retargeting. |
autoTPose | (skel, profile) => Record<string, Quat> | Pose a rig into the canonical T in its own space. |
bakeRetargetedClip | (clipTop, charSkel, charAvatar, name, keys?) => AnimationClip | Retarget a humanoid clip from its source FBX onto a character. See Animation. |
See also
- Import Overview - the shared-IR import philosophy.
- Data Formats & Versions - the three formats side by side, with migrations.
- Export to a game file - where
bundleToSceneFile+ the container are used. - Projects - saving/loading the binary
.awakenproject. - @awaken/render - the
MeshData/Material/TextureRoletypes this package stores.