@kvyverse/world-runtime
v0.6.2
Published
Runtime for worlds exported from the Kvyverse platform for self-hosting
Readme
@kvyverse/world-runtime
Runtime for worlds exported from Kvyverse — a web-based 3D world editor. When you export a world for self-hosting, Kvyverse gives you a generated JS module; this package is the engine that module runs on.
Install it only together with such a module: on its own it does nothing.
1. Export the world from Kvyverse
In the editor: burger menu → Export → Build for self-hosting. You get a
<world>.zip with index.js (the world) and index.d.ts (its types), plus a
dialog with two ready-to-copy snippets — the install command and the import.
2. Put the world into your project
Unzip the folder into your sources, for example src/my-world/. Nothing else
from the archive is needed: your bundler picks the module up like any local file.
Asset files (models, textures, audio, fonts) are not in the archive — they stay on the Kvyverse CDN, and the module carries a table of their URLs.
3. Install the dependencies
Copy the command from the export dialog — it already lists exactly what your world needs and pins the runtime version the world was built with, for example:
npm i @kvyverse/world-runtime@<version> three three-start @dimforge/rapier3d-compatEverything the runtime needs is a peer dependency, so nothing is duplicated
in your node_modules:
| Package | When |
| --- | --- |
| three, three-start | always |
| howler, vanjs-core, eventemitter3, nanostores | always — npm 7+ installs them for you |
| @dimforge/rapier3d-compat | worlds with physics (a collider on the scene is enough) |
| @tweenjs/tween.js, animejs, nipplejs, stats.js | worlds that enable these optional libs |
The optional ones are listed in the dialog only when the world actually uses
them. Skip one it does need and the build fails with a clear
failed to resolve import — install it and rebuild.
Requirements for your project: ES modules, a bundler (Vite, webpack, Rollup, …),
and a browser with WebGPU (the world renders through three/webgpu).
4. Run it
import { loadWorld } from "./my-world/index.js";
const world = await loadWorld({
onProgress: (p) => console.log(p.stage), // optional loading screen
});
world.mount(document.getElementById("app")); // creates the canvas, starts the render loop
world.start(); // activates the world's behavioursmount and start are separate on purpose: you can show your own intro or wait
for a click before the world comes alive. If the world plays audio or locks the
pointer, call start() from a user gesture — browsers require it.
loadWorld(options)
| Option | What it does |
| --- | --- |
| onProgress | ({ stage, details }) => void while the world loads — for your loading screen |
| dracoPath | Folder with your own Draco decoder for compressed models; defaults to Google's public one |
| assetsBaseUrl | Prefix for relative asset paths (only for worlds built that way) |
The world object
World extends ThreeStart from three-start, so the usual lifecycle and
context are yours:
world.ctx.scene, world.ctx.camera, world.ctx.renderer
world.unmount(), world.runLoop(), world.stopLoop(), world.dispose()On top of that: world.getUrl(path) resolves an asset URL the same way scripts
inside the world do, world.events is the world lifecycle emitter (the same
world.events your scripts use), and world.stores is the world's shared
reactive state (the same world.stores) — your host page can read it, write it
and subscribe to keys the world's scripts use:
world.stores.listen("score", (value) => hudElement.textContent = value);
world.stores.set("difficulty", "hard");Good to know
- Scripts, behaviours, materials and shaders written in the editor are baked into the module — no Kvyverse code runs at load time to interpret them.
- Re-exporting a world overwrites the same folder with the same file names, so your import never changes.
- Runtime version. The module records the runtime version it was built with and the world format version, and refuses to load on an incompatible runtime. Re-export the world after a major runtime update.
- Not everything crosses over. Platform features (multiplayer server, user state, launcher worlds, the editor's debug overlay) stay in Kvyverse; the export report lists whatever your particular world loses.
License
Proprietary, see LICENSE.md. In short: free to use (including commercially) only to run worlds exported from Kvyverse; no modification or redistribution; bundling the unmodified package into your app build is allowed.
