Asset Store
The Store is a dock panel that browses a remote catalog of ready-made packages and imports one straight into the project you have open, without leaving the editor.
Why it exists
A new project starts with nothing - no player controller, no test props, no VFX. Building a third-person controller from scratch (capsule collider, follow camera, locomotion anim graph, movement script) is the kind of setup every project repeats. The Store gives you that starting point as a single click: browse, Import, and the prefab is in your Asset Browser ready to drag into a scene.
Opening it
Click Store in the Toolbar's right-hand button group, or open it from the Windows ▾ menu. The Store is an on-demand panel - it is not docked by default; opening it (store.openPanel("store")) docks it into your layout, and you can close its tab (the ✕) when you're done.
The remote catalog
The Store fetches catalog.json from https://store.awaken3d.dev (STORE_URL in apps/editor/src/store/catalog.ts) and downloads package files from the same host's packages/*.awakenpkg. This is a static file host, not a backend service - it serves the manifest and the package bytes with permissive CORS, since the editor calling it is a different origin.
This makes the Store the one deliberately networked feature in Awaken. Everything else - editing, importing local files, exporting a game - runs entirely on your machine and never phones out. Opening the Store panel triggers an HTTP fetch to store.awaken3d.dev; nothing else in the editor does.
Browsing
The panel has a search box, a category filter dropdown, and a sort dropdown (Featured, Name A-Z, Newest, Size), above a Featured strip and a grid of cards. Typing in search or picking a category hides the Featured strip and switches the grid to a result count. Each card shows a thumbnail, name, author, category, a per-type contents line (for example "1 prefab, 1 anim graph, 1 script"), and a price badge.
Three non-happy-path states are handled explicitly: a loading message while the first fetch is in flight, an error state with the failure text and a Retry button if the fetch fails, and a "No assets match" message when a search/category combination returns nothing.
📸 Screenshot - save as img/editor-store-front.png
The Store panel's storefront: search box, category and sort dropdowns, the Featured strip with 2-3 cards, and the main grid below it.
Clicking a card opens a single-asset detail view: a larger thumbnail (or screenshot gallery, if the entry has screenshots), the full description, a What's inside breakdown of the package's per-type contents, and the Import button. A ← Store button returns to the grid.
📸 Screenshot - save as img/editor-store-detail.png
The Store's detail view for one package: thumbnail, name/author, category and tag chips, the "What's inside" contents grid, description text, and the Import button.
Importing a package
Import downloads the package's bytes, decodes them, and merges the result into the currently open project - the same merge path a .awakenpkg file dropped onto the editor window takes. There's no separate download step and no second tab to manage: click Import, and the assets show up in the Asset Browser's Prefabs tab (and Scripts, Anim Graphs, etc., depending on what the package contains). A success banner confirms this and names where to look; a failure logs the error and stays on the detail view so you can retry.
Import is id-based dedup, not a wholesale replace: every asset the package carries (mesh, texture, material, prefab by name, script, and so on) is added only if that id isn't already present in the project. Re-importing the same package, or importing two packages that share a dependency, doesn't create duplicates.
What a package actually is
A store item is a .awakenpkg package - a self-contained bundle that can hold any mix of prefabs, meshes, textures, materials, particle effects, anim graphs, scenes, scripts, and editor plugins, plus every asset those items depend on. The bundle is a ProjectBundle (the same structure a project save uses) with a package: true flag and an empty scene, zstd-compressed. decodePackage (apps/editor/src/state/project.ts) checks that flag: a file that decodes without it is a full project, not a package, and the import path refuses it rather than merging a whole project's scene into yours.
Import is content-sniffed rather than relying on the file extension: importFile.ts looks at the first byte of a .awakenpkg / .awakenprefab file. A leading { means JSON - the older, single-prefab .awakenprefab format - and is parsed and merged through the legacy prefab path (which can prompt you to locate missing script/material dependencies one at a time). Anything else is treated as a binary package and goes through decodePackage / importPackage, the same dependency-complete merge the Store uses. Both extensions and both encodings still import correctly.
The seed catalog
The catalog currently ships 5 packages, all free (price: 0):
| Package | Category | Contents |
|---|---|---|
| Third Person Player | Characters | 1 prefab, 1 anim graph, 1 script |
| First Person Player | Characters | 1 prefab, 1 script |
| Physics Ball | Physics | 1 prefab |
| Campfire VFX | VFX | 1 prefab, 1 particle effect |
| Essentials Kit | Kits | all four of the above, deduplicated - 4 prefabs, 2 scripts, 1 anim graph, 1 particle effect |
Essentials Kit exists to demonstrate the dedup behaviour directly: it bundles the same prefabs, script, and anim graph the four individual packages ship, assembled once so importing it (or importing it after already importing the others) never produces two copies of the same asset.
v1 is free-only
Every current catalog entry has price: 0 and the Import button always reads "Import". The StoreEntry.price field and a Buy $X.XX label already exist in the UI code, but there is no purchase flow behind them yet - a paid item would need payment and entitlement handling that hasn't been built. Treat everything in the Store today as free.
Authoring a package
Packages aren't only for the store team - you can bundle any of your own project's assets into a .awakenpkg to hand to another project or contributor. Two entry points:
- The Asset Browser's header has an Export Package… button, which opens the Create Package dialog.
- Right-click a prefab in the Asset Browser for Export as package…, which packages that one prefab (and its dependencies) directly, skipping the dialog.
The Create Package dialog lists every packageable asset in the project, grouped into sections - Prefabs, Scenes, Meshes, Textures, Materials, Particle effects, Anim graphs, Scripts, Plugins - each with a checkbox per item and an All/Clear toggle for the section. You don't need to hunt down dependencies by hand: ticking a prefab is enough, because assemblePackage (packages/assets/src/packageBundle.ts) walks its component graph and pulls in every mesh, texture, material, script, anim graph, and particle effect it references. A live footer line ("Package contains: 1 prefab, 1 anim graph, 1 script") updates as you check items, and notes when the total includes auto-bundled dependencies beyond what you directly picked.
📸 Screenshot - save as img/editor-create-package.png
The Create Package dialog: the package-name field, the expandable Prefabs/Scripts/… sections with checkboxes, and the "Package contains: …" footer above the Export .awakenpkg button.
Exporting writes a zstd-compressed .awakenpkg file (exportPackage, same file). That file is exactly what the Store hosts - dropping it into another project's editor window, or publishing it to store.awaken3d.dev's packages/ folder and adding a catalog.json entry, uses the identical decode-and-merge path described above.
See also
- Asset Browser - where imported store assets land, and where Export Package… lives
- Plugins - editor-only tooling that can ride inside a package alongside gameplay assets
- Prefabs - what a store package's prefabs actually are once imported
- Projects - the
ProjectBundle/PROJECT_VERSIONformat a package borrows its encoding from - Importing assets - the local-file import path (
+ Import, drag-and-drop) that a.awakenpkgalso goes through