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.

OptionValuesWhat it does
patha file path Which file inside the source to open first. Defaults to the first one; the visitor can switch with the picker.
sounda 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.
modeauto · blueprint · assembled · vfx · audio Which view to open on. auto picks the most interesting one available - the assembled creature when there is one.
themedark · light Match your page. Defaults to dark.
heightany 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.)
titletext 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 seeWhy
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.