Documentation

Programmatic Scene Building (DiscoVR class)

For experiences that are easier to build in JavaScript than to describe with <discovr> tag attributes and HTML markup, DiscoVR Engine exposes a DiscoVR class as window.DiscoVR. It's a thin, generic layer for creating A-Frame entities from code — it doesn't duplicate the <discovr> tag's config-driven features (environment/lights presets, player rig, teleport, networking; see the Configuration Reference for those).

window.DiscoVR becomes available as soon as discovr-core.js has run, so any <script> loaded after it can use it.

Standalone usage

Without a <discovr> tag, DiscoVR finds or creates its own <a-scene>, so this is all you need:

<script type="module" src="https://core.discovr-engine.eu/discovr-core.js"></script>
<script type="module">
    const discovr = new window.DiscoVR();
    discovr.addBox({ color: "red", position: "0 1 -3" }, "myBox");
</script>

Using it alongside a <discovr>-configured scene

DiscoVR looks for an existing <a-scene> and reuses it if found, instead of creating a second one — but the <discovr> tag's own scene is built asynchronously during boot, so your script needs to wait until it exists before instantiating DiscoVR. The safe pattern is to wait for the scene's loaded event:

function whenSceneReady(callback) {
    var scene = document.querySelector('a-scene');
    if (scene) {
        if (scene.hasLoaded) callback();
        else scene.addEventListener('loaded', callback);
    } else {
        setTimeout(() => whenSceneReady(callback), 100);
    }
}

whenSceneReady(() => {
    var discovr = new window.DiscoVR();
    discovr.addBox({ color: "blue" }, "myBox");
});

Instantiating DiscoVR before the <discovr> tag's scene exists will create a second, unrelated <a-scene> instead of adding to it — that's the one thing to avoid.

API

new DiscoVR()

Finds the page's <a-scene>, or creates and appends one to <body> if none exists yet.

getScene()

Returns the <a-scene> element this instance builds into.

getAssets()

Finds or creates the <a-assets> node inside the scene, and returns it. Called automatically by addAsset().

addAsset(id, src)

Registers an asset (model, image, audio, ...) under <a-assets> so it can be referenced elsewhere by "#id" — most commonly by addModel().

Param Type Description
id string The asset's id.
src string Path or URL to the asset file.

Returns the created element: an <a-asset-item>, or a <video> / <audio> element when the file extension is a video / audio one (an audio asset must not be an <a-asset-item> - see the sound component note in CLAUDE.md).

addEntity(tag = "a-entity", attributes = {}, id = "", parent = null)

Creates an element of any tag, sets each entry of attributes via setAttribute, and appends it to parent (or the scene, by default). This is what every add* convenience method below is built on — reach for it directly whenever you need a tag or component that doesn't have its own wrapper.

Param Type Description
tag string Element tag to create, e.g. "a-entity", "a-box", "a-text".
attributes object Map of attribute/component name → value. Values can be strings or objects, exactly like A-Frame's own setAttribute.
id string Optional element id.
parent Element Optional parent to append to. Defaults to the scene.

Returns the created element.

discovr.addEntity("a-text", { value: "Hello DiscoVR", color: "white" }, "greeting");

addBox(attributes = {}, id = "", parent = null)

addSphere(attributes = {}, id = "", parent = null)

addPlane(attributes = {}, id = "", parent = null)

addLight(attributes = {}, id = "", parent = null)

Convenience wrappers over addEntity() for a-box, a-sphere, a-plane, and a-light respectively. Same parameters and return value as addEntity().

discovr.addPlane({ width: 10, height: 10, color: "gray", rotation: "-90 0 0" }, "floor");
discovr.addLight({ type: "directional", intensity: 1.2 });

addModel(assetId, attributes = {}, id = "", parent = null)

Adds an a-entity with gltf-model pointing at a previously-registered asset.

Param Type Description
assetId string Id of an asset added via addAsset().
attributes object Additional attributes/components for the entity (position, scale, ...).
id string Optional element id.
parent Element Optional parent to append to. Defaults to the scene.
discovr.addAsset("chair", "models/chair.glb");
discovr.addModel("chair", { position: "1 0 -2" }, "livingRoomChair");

addTestCube(idname = "")

Adds a simple red box — useful as a quick sanity check that a scene is rendering. Equivalent to addBox({ color: "red" }, idname).

Nesting entities

Every add* method accepts a parent, so you can build a hierarchy the same way you would with nested HTML tags:

var group = discovr.addEntity("a-entity", { position: "0 1 -3" }, "group");
discovr.addBox({ color: "red" }, "child1", group);
discovr.addSphere({ color: "blue", position: "1 0 0" }, "child2", group);

What's next

  • Message bus — DiscoVR.bus, a page-wide publish/subscribe bus (available before the scene exists) for components and scripts to talk to each other, and the i-bus component to wire objects together without code.
  • Examples — a virtual tour built with addModel(), plus a few other complete pages.