Embeddable viewers
Put Trove's 3D models, particle effects and game sounds on your own site.
Kiwi renders Trove content in the browser - voxel .blueprint models,
whole creatures assembled on their skeleton with animation clips, PopcornFX
.pkfx effects, and the audio inside Wwise .bnk sound banks.
The embeddable viewer puts that same renderer and player in an
<iframe> on your pages.
It can show a mod you host yourself, a creature straight out of the live game, or any single game file - you don't need to ship game assets, and you don't need to build anything 3D.
Before you start: embedding is allowed per-origin. Send us the
exact origin(s) your pages are served from (for example
https://example.com) and we'll enable them. Until then the viewer
refuses to render in a frame on your site.
Quick start
Drop in the loader once, then mark up each spot you want a preview:
<div data-kiwi-embed data-game="dragon_head.blueprint"></div>
<script src="https://trove.aallyn.net/static/embed.js" async></script>
Every marked element becomes a responsive iframe. If you'd rather not run our script, write the iframe yourself - it's the same URL:
<iframe src="https://trove.aallyn.net/embed/viewer?game=dragon_head.blueprint"
style="width:100%;height:420px;border:0;border-radius:12px"
title="Trove 3D preview" loading="lazy" allowfullscreen></iframe>
Choosing what to show
Every embed needs exactly one source.
A creature from the game
prefab=<path> - a mount, dragon, ally, mob or costume, named the
way the game names it. You get the whole creature: every part placed on its skeleton,
with its animation clips, straight out of the current game files.
?prefab=prefabs/collections/mount/duck_dragon.binfab
?prefab=prefabs/collections/mount/duck_dragon
?prefab=duck_dragon
?prefab=adventurer_artist
The .binfab is optional, and so is the folder when the filename is
unique - which it usually is. A few NPCs are filed in several places under the same
name (beetle_firebug exists four times over); if a name could mean more
than one creature we say so, and name one of them, instead of picking for you.
A file from the live game
game=<path> - any .blueprint, .pkfx or
.bnk in the current game files. A full path works, and so does a bare
filename; we resolve it against the game tree.
?game=prefabs/creatures/dragon/dragon_head.blueprint
?game=dragon_head.blueprint
?game=fx_fire_medium.pkfx
?game=audio/ui.bnk
When the blueprint you name is part of a creature, the viewer offers the
whole creature - every other part pulled from the game files,
placed on its skeleton, with its animation clips. One filename, the full model.
(If you already know which creature you want, prefab= above says so
directly.)
Game sounds
A .bnk is a sound bank - one file holding anywhere from a single
effect to the 1,600 in Trove's UI bank - so pointing at one gives you a player: a
filterable list of everything inside, with a waveform transport above it. Nothing is
decoded until a visitor presses play, so embedding an 87 MB music bank costs your page
one small request.
?game=audio/ui.bnk
Add sound= to pin one sound and drop the list - the embed becomes a
single player, which is usually what a page showing off one effect wants. It takes the
sound's name or its numeric id.
?game=audio/ui.bnk&sound=ui_gems_upgrade_sm_01
?game=audio/ui.bnk&sound=1099092
A mod you host
Upload the .tmod once from your backend and embed the token you get
back. See Uploading a mod below.
?tmod=<token>
A mod on the Kiwi Mods Hub
release=<id> - a published release id. Nothing to upload. A hub
release that bundles a .bnk gets the sound player too.
?release=66f1c0a3e4b0a1d2c3e4f5a6
Options
All optional. With the loader script, each one is a data- attribute
(data-theme="light"); on a hand-written iframe it's a query parameter.
| Option | Values | What it does |
|---|---|---|
path | a file path | Which file inside the source to open first. Defaults to the first one; the visitor can switch with the picker. |
sound | a sound name or id | Pins the player to one sound inside a .bnk and hides the list.
A name matches in full before it matches a fragment, so hit finds
the sound actually called "hit" rather than hit_critical_02. |
mode | auto · blueprint · assembled · vfx · audio |
Which view to open on. auto picks the most interesting one
available - the assembled creature when there is one. |
theme | dark · light |
Match your page. Defaults to dark. |
height | any CSS height | Loader script only - the height of the 3D view. Defaults to
420px. Below about 340px the footer hides itself. An assembled
creature also gets a row of animation clips; when it does, the loader grows the
iframe by the height of that bar so the model keeps the size you asked for
rather than being squeezed to make room. (Growing needs a px
value - any other unit is left exactly as you set it. A hand-written
<iframe> is never resized; give it ~120px of extra height if
you're embedding creatures with animations.) |
title | text | Loader script only - the iframe's accessible name. |
If you render your mod list client-side, call KiwiEmbed.scan() after
your own render pass to mount any placeholders that appeared since page load.
Uploading a mod
For mods you host yourself, POST the .tmod as your mod page renders
and put the token you get back in the embed. This needs a Kiwi API token with the
mods:read scope - it's a server-to-server call, so the token never
reaches a browser.
POST https://api.aallyn.net/v1/embed/tmod
curl -X POST https://api.aallyn.net/v1/embed/tmod \
-H "Authorization: Bearer kiwi_..." \
-F "file=@MyMod.tmod"
{
"token": "9f2c…",
"size": 184320,
"expires_in": 1800,
"reused": false,
"viewer_url": "https://trove.aallyn.net/embed/viewer?tmod=9f2c…"
}
We don't keep your file. It's held in memory for
expires_in seconds - long enough for a visitor to look at it - and then
it's gone. Nothing is written to disk on our side, and there's no copy to delete
later. That's also why the token is short-lived rather than permanent.
Post it per page render, not once per publish. The clock starts at upload and does not extend while someone is watching, so a token cached for days will be dead by the time a visitor loads the page. Posting on render costs you one small request and always yields a fresh token. The token is the file's SHA-256, so re-posting an unchanged mod refreshes the same entry rather than holding a second copy.
A visitor who leaves a page open past the expiry sees "This preview has expired - reload the page", and reloading re-renders your page, which mints a new token. To check a token yourself first:
GET https://api.aallyn.net/v1/embed/tmod/<token>
→ {"token": "…", "live": true, "size": 184320}
Mods must be under 8 MB to preview this way. Larger ones can still go on the Kiwi
Mods Hub and embed with release=.
What renders, and what doesn't
Models are exact - the same voxel data the game reads, with glass, glow and tint shaded the way the game shades them.
Effects are a best-effort preview. Billboard and ribbon particles render; mesh-based and light renderers are approximated, and a few effect types aren't drawn at all. The viewer says so on-screen when a preview is partial, including when an effect references an asset we can't resolve. Treat it as a good look at an effect, not a substitute for seeing it in game.
A creature only assembles when the game's own data tells us which skeleton its parts belong to and where each attaches. If we don't know, we show the individual blueprints instead of guessing - a model built on the wrong skeleton looks like a bug in your page, not a limitation of ours.
Sounds are the game's own audio, converted to something a browser can play. Names come from the log Wwise writes beside each bank, so most sounds list under the name the studio gave them; a handful that bank carries no entry for show as an id. A media object we can't decode stays in the list, marked, rather than vanishing.
Privacy and cost
The viewer sets no cookies, stores nothing in the visitor's browser, and reads nothing from your page. The loader script only writes an iframe.
On our side, a mod you upload is held only for the life of its token and never written to disk - we keep no library of partner mods, and nothing needs deleting when you stop using the embed. Embedding a hub mod or a game file stores nothing at all, since both are already ours.
It's free to embed. There's a per-visitor request budget so one page can't monopolise the renderer; a normal page with a few previews is nowhere near it.
Troubleshooting
| What you see | Why |
|---|---|
| The frame is blank or the browser blocks it | Your origin isn't allowed yet. Send us the exact origin, scheme included. |
| "This preview has expired" | The token outlived its TTL. POST the .tmod as the page renders
rather than caching the token for later. |
| "No '…' in the current game files" | The filename doesn't exist in the live game tree - check spelling and extension, or pass the full path. |
| "'…' is the filename of N different creature prefabs" | A short prefab= name that more than one creature is filed
under. The message includes a real full path - use that shape. |
| "This mod has no 3D models or effects to preview" | The .tmod contains no .blueprint or
.pkfx - a texture-only or UI mod, for instance. |
| "Sounds can't be previewed from an uploaded mod" | Indexing a sound bank writes every sound to our store, and we promise an
uploaded .tmod is never written to disk. Publish the mod to the
Kiwi Mods Hub and embed it with release= instead. |
Anything else: support@aallyn.net.