Voxta docs

App triggers

Drive the host app — Voxta Talk UI, VAM scenes, Voxy avatar, custom apps — from a scenario script.

App triggers are how a scenario reaches outward and tells the host app to do something: change the chat view, swap avatar images, play music, fire a sound effect, change a VAM scene state.

You call them from a script:

import { chat } from "@voxta";

export function trigger(e) {
  chat.appTrigger("TriggerName", ...params);
}

The available triggers depend on which app is running the chat. The trigger names below are for Voxta Talk (the default web UI). For VAM, see VAM app triggers.

Asset helpers

Most modern triggers take an Asset object instead of a path string. Get an asset from a character's or scenario's asset collection:

FunctionWhat it does
assets.get(name)Get a specific asset by filename. Throws if it doesn't exist.
assets.oneOf(prefix)Random pick from assets whose filename starts with the prefix. Throws if none match.
assets.oneOrNoneOf(prefix)Same as oneOf but returns null/undefined instead of throwing.
// Specific
const happy = e.character.assets.get("happy_face.webm");

// Random from a set
const emote = e.character.assets.oneOf("emote_");

// Optional random
const effect = chat.scenario.assets.oneOrNoneOf("special_effect_");

Path-based access still works for legacy triggers — just pass a string path relative to the character or scenario Assets folder.

Voxta Talk triggers

Emote

Pop an emoji bubble above the character.

chat.appTrigger("Emote", "💡", "yellow");
chat.appTrigger("Emote", "❤️");
ParamTypeNotes
emojistringA single emoji.
colorstring?Color name ("red") or hex ("#FF0000").

SelectView

Switch the chat interface mode.

chat.appTrigger("SelectView", "portrait");

ChatView values:

  • talk — voice-centric, minimal UI.
  • portrait — avatar-focused.
  • chat — full view with chat history.
  • stage — visual-novel-style stage with backgrounds and custom buttons. See the Stage Editor.

SetAvatar (asset-based)

Recommended. Set the avatar using an Asset object.

chat.appTrigger(
  "SetAvatar",
  e.character.assets.get("mood.png"),
  e.character.id,
  "untilEndOfSpeech"
);
ParamTypeNotes
assetAssetThe image/video to display.
targetCharacterIdstring?Whose avatar to change. Defaults to the asset's owner.
untilAvatarExpiration?How long the override sticks.

SetAvatar (path-based)

Legacy. Set the avatar with a string path.

chat.appTrigger("SetAvatar", "talk.webm", e.character.id, e.character.id, "untilNextMessage");

SetAvatarFromScenario

Avatar from the scenario's asset folder instead of a character's.

chat.appTrigger("SetAvatarFromScenario", "intro.png", e.character.id);

PlayMusic

Background music track. Starting a new one stops the previous one.

chat.appTrigger("PlayMusic", chat.scenario.assets.get("background_music.mp3"), 0.5);
ParamTypeNotes
assetAssetThe audio track.
volumenumber?0.0–1.0. Defaults to engine default.

PlayAmbient

Ambient sound. Multiple ambient tracks can play simultaneously with different track names.

chat.appTrigger(
  "PlayAmbient",
  chat.scenario.assets.get("rain_loop.ogg"),
  "weather_sounds",
  0.6  // volume 0.0–1.0
);

StopMusic / StopAmbient

chat.appTrigger("StopMusic");
chat.appTrigger("StopAmbient", "weather_sounds");

PlaySound

One-shot SFX. Overlaps with other sounds.

chat.appTrigger("PlaySound", e.character.assets.get("door_creak.wav"), 0.9);

PlayVoice

Queue a pre-recorded voice line as if it were TTS output.

chat.appTrigger("PlayVoice", e.character.assets.get("greeting_line_01.mp3"));

PlayCharacterAudio

Play audio from a character's asset folder by path. Combines voice/music/sfx playback into one call — the method decides which audio bus is used.

chat.appTrigger(
  "PlayCharacterAudio",
  "greeting.mp3",       // path inside the character's Assets folder
  e.character.id,       // character whose assets to look up (defaults to sender)
  "voice",              // method: "voice" (default) | "music" | "background" | "ambient" | "sfx"
  "main_track",         // trackKey (only used by music/ambient)
  0.8                   // volume 0.0–1.0
);
ParamTypeNotes
pathstringPath inside the character's Assets/ folder.
characterIdstring?Whose assets to read from. Defaults to the message sender.
methodstring?"voice", "music", "background", "ambient", or "sfx".
trackKeystring?Track identifier for music/ambient stacking.
volumenumber?0.0–1.0.

PlayScenarioAudio

Same as PlayCharacterAudio, but resolves paths from the scenario's asset folder instead of a character's.

chat.appTrigger(
  "PlayScenarioAudio",
  "intro_jingle.mp3",   // scenario-relative path
  "music",              // method
  "intro",              // trackKey
  0.6                   // volume
);

SetBackground

Swap the background image or video. Voxta Talk supports multiple background layers — useful for stacking a background image with overlay effects.

Basic — single background:

chat.appTrigger("SetBackground", chat.scenario.assets.get("main_room_bg.jpg"));

With explicit layer (positional):

// Layer 1 = base background, higher layers = overlays
chat.appTrigger("SetBackground", chat.scenario.assets.get("room_bg.jpg"), 1);
chat.appTrigger("SetBackground", chat.scenario.assets.get("rain_overlay.webm"), 2);

With explicit layer (object form):

chat.appTrigger("SetBackground", {
  path: chat.scenario.assets.get("rain_overlay.webm").toUrn(),
  layer: 2
});

Clear a layer:

// Omit the asset to clear that layer
chat.appTrigger("SetBackground", null, 2);
ParamTypeNotes
asset or optionsAsset | string | { path, layer }The image/video, a URN string, or an options object.
layernumber?Layer index. Defaults to 1. Higher values stack on top.

There's also a typed helper that wraps this call:

chat.setBackground(chat.scenario.assets.get("room_bg.jpg"));
chat.setBackground(chat.scenario.assets.get("rain.webm"), 2);
chat.setBackground({ path: someUrn, layer: 3 });

Layer rendering zones (z-index)

The layer number maps to one of three visual zones — pick the zone that matches the kind of asset you're placing:

LayersZoneWhat rendersUse for
1–3BackgroundBehind characters and UIStandard scenery, wall textures, distant objects. Layer 1 is the default for legacy single-background calls.
4–9Mid-groundIn front of characters, behind the Chat UIFog, rain, foreground props (tables, desks) the characters stand behind — but that shouldn't block the user from typing.
10+ForegroundOn top of everything, including the Chat UIFull-screen maps, cutscenes, heavy weather effects, HUD overlays, vignetting.

All layers from 4 upwards are rendered with pointer-events: none. This means even if a foreground layer covers the whole screen (e.g. a map at layer 10), the user can still click buttons and input fields underneath transparent sections of the image.

Clearing layers

Pass null (or omit the asset) to clear a specific layer:

chat.setBackground(null, 4);   // remove the desk
chat.setBackground(null, 10);  // remove the rain overlay

Common recipes

// Standard background scene
chat.setBackground(chat.scenario.assets.get("bg_forest.jpg"), 1);

// A desk in front of the character but behind the chat box
chat.setBackground(chat.scenario.assets.get("prop_desk.png"), 4);

// A rain effect on top of everything (clickable through transparent areas)
chat.setBackground(chat.scenario.assets.get("effect_rain.webm"), 10);

SetBackgroundFromScenario

Set the background using a string path relative to the scenario's asset folder. Single-layer only — for layered backgrounds, use SetBackground with an asset object.

chat.appTrigger("SetBackgroundFromScenario", "lobby_bg.jpg");

SetAvatarAnimation

Apply a looping animation (video asset) to a character's avatar.

chat.appTrigger(
  "SetAvatarAnimation",
  e.character.assets.get("idle_loop.webm"),
  e.character.id
);
ParamTypeNotes
animationAssetAssetA video asset to play on loop. Must be a URN — string paths not accepted.
characterIdstring?Whose avatar to animate. Defaults to the sender. Narrators cannot be targeted.

Pass a null/empty asset to remove the animation override.

SetAvatarBlendshape

Drive a single blendshape on a character's avatar — useful for facial expression rigs that expose blendshape parameters.

chat.appTrigger("SetAvatarBlendshape", "smile", 0.8, e.character.id);
chat.appTrigger("SetAvatarBlendshape", "smile", 0);  // reset
ParamTypeNotes
blendshapeNamestringThe blendshape identifier on the avatar rig.
valuenumberTypically 0.0–1.0.
characterIdstring?Whose avatar to modify. Defaults to the sender.

Avatar expiration values

Used in SetAvatar / SetAvatarFromScenario:

ValueBehavior
untilNextMessageReverts after the next chat message is processed.
untilEndOfSpeechReverts when the current TTS line finishes.
undefined (omit)Persists for the session until explicitly changed.

Queued vs immediate triggers

By default chat.appTrigger(...) fires immediately. If you want the trigger to fire after the character finishes speaking (e.g. play a sound effect once the dialogue line completes), use chat.queue.appTrigger(...) instead:

chat.queue.appTrigger("PlaySound", chat.scenario.assets.get("door_close.wav"));

The queued trigger waits in the message queue and fires when the character's speech completes.

Other queued operations

chat.queue is a sub-module with other queue-aware operations beyond just app triggers:

MethodWhat it does
chat.queue.appTrigger(name, ...args)App trigger queued to fire after speech.
chat.queue.roleMessage(role, text)Send a message as the character associated with role, queued.
chat.queue.roleEnabled(role, enabled)Toggle a role's participation, queued.
chat.queue.setFlag(value) / chat.queue.setFlags(...)Set scenario flags, queued.

Each maps to the same operation as the non-queued version on chat.*, but waits for the current speech turn to finish before being applied.

VAM triggers

When the chat is hosted by the VAM plugin, app triggers can drive any VAM atom storable — Timeline animations, light intensities, material params, etc. The trigger signature is different (atom + storable + param + value):

chat.appTrigger('Action', 'Person', 'plugin#2_VamTimeline.AtomPlugin', 'Play wave_hello');

See VAM → App triggers for the full VAM-specific reference.

What's next

On this page