Skip to main content

Quick Start Examples

This page provides examples to quickly get started with the Genies Web SDK.

Typical Consumer Use Cases

Minimal Use Case

This script initializes the SDK and loads a basic mesh with no animations:

const naf = await initialize({ canvas, initScene });

const handle = await naf.loadAvatar(avatarDef, { renderer, lod: 0 });
scene.add(handle.mesh);

function tick(dt) {
naf.update(dt, renderer);
renderer.render(scene, camera);
}

Common Use Case

This script animates an Avatar with progressive LOD:

const naf = await initialize({ canvas, initScene });

const handle = await naf.loadAvatarProgressive(avatarDef, {
renderer,
scene,
lod: [2, 0],
idle: { id: 'idle_neutral', version: '1' },
});

function tick(dt) {
naf.update(dt, renderer);
handle.controller?.update(dt);
handle.controller?.syncPose();
renderer.render(scene, camera);
}

Full Use Case

This script sets up a smart Avatar with behaviors:

const naf = await initialize({ canvas, initScene });
naf.setBearerToken(token);
await naf.setEnvironment('prod');

const handle = await naf.loadAvatarProgressive(avatarDef, {
renderer,
scene,
lod: [2, 0],
idle: { id: 'idle_neutral', version: '1' },
behavior: {
slug: 'default',
talking: 'talking_clip',
onLoaded: () => console.log('behavior ready'),
},
onReady: async ({ controller }) => {
controller.setLookWeight(1.0);
},
onError: ({ error, phase }) => console.error(phase, error),
});

naf.on('avatar:error', ({ error, phase }) => console.error(phase, error));

Common Workflows

Load Multiple Avatars

const handle1 = await loadAvatarProgressive(def1, options);
const handle2 = await loadAvatarProgressive(def2, options);

// Both animate independently
function animate(dt) {
handle1.controller?.update(dt);
handle1.controller?.syncPose();
handle2.controller?.update(dt);
handle2.controller?.syncPose();
renderer.render(scene, camera);
}

Switch Shader Target Between Avatars

const mgr = getShaderManager();

// Avatar A is currently targeted
const cacheA = mgr.detachTarget(); // Save A's materials
mgr.reattachTarget(meshB, cacheB); // Switch to B

// Edit B's shaders...
mgr.toon.setParam('flatness', 0.5);

// Switch back to A
const newCacheB = mgr.detachTarget(); // Save B's materials
mgr.reattachTarget(meshA, cacheA); // Restore A

Unload Avatar

handle.unload();
// Frees: native entities, animation controller, LOD callbacks
// You must remove the mesh from your scene manually:
scene.remove(handle.mesh);