Examples
Example: Sample Companion Pack
A data-only pack — an avatar look with its own motions, and two ready-made characters.
Example plugin · 1 look with motions · 2 characters · no code, no permissions
This pack ships everything companion mode can take from a plugin, with no index.ts at all: nothing runs in the
sandbox, and the Browse page shows no permissions and nothing it can reach.
Layout
readme.md
companion-models/sample-seed/
model.json seed-san.vrm thumbnail.png background.jpg
idle-neutral.vrma talk-idle.vrma listen.vrma think.vrma wave.vrma laugh.vrma
companion-characters/sample-seed-character/character.json
companion-characters/sample-rose-character/character.json
Three keys — sample-seed, sample-seed-character, sample-rose-character — all different, because keys are
unique across the whole package (a character can't share its model's key). The readme uses version: 1.3.
The look and its motions
model.json lists the look's motions as file: clips in the model's own folder — every base role gets one body
clip, plus one gesture and one reaction:
| Motion | Role | Format | Notes |
|---|---|---|---|
file:idle-neutral.vrma |
idle |
VRMA | required — every look needs at least one idle |
file:talk-idle.vrma |
talkIdle |
VRMA | required — the loop while speaking; cues: ["calm"], so a calm reply prefers it |
file:listen.vrma |
listen |
VRMA | a nod while the user talks |
file:think.vrma |
think |
VRMA | hand to chin while the agent works |
file:wave.vrma |
gesture |
VRMA | required (at least one gesture) — cues: ["waving"], strokeSeconds: 0.9 |
file:laugh.vrma |
reaction |
VRMA | cues: ["laughing", "chuckling"] — plays on a [laughing] line |
- VRMA clips need nothing else — no
rig; they always drive the humanoid body. cuesandstrokeSecondslet the companion land the wave on a greeting at the right beat.- A companion wears the look by reference. Publish a new version and, once a user's installation moves to it, every companion wearing the look moves the new way.
{
"name": "Sample Seed-san",
"description": "VirtualCast's sample VRM avatar Seed-san, with a small set of its own motions, for testing plugin looks end to end.",
"avatar": "seed-san.vrm",
"thumbnail": "thumbnail.png",
"background": "background.jpg",
"outfits": [
{ "key": "plain", "name": "Plain", "meshes": ["wear"] },
{ "key": "cyborg", "name": "Robot arm", "meshes": ["wear", "robo_arm"] }
],
"motions": [
{ "id": "file:idle-neutral.vrma", "roles": ["idle"], "name": "Idle", "description": "A long, unhurried neutral standing idle loop." }
]
}
(The real file lists all six motions.)
- Outfits name parts of the VRM by mesh.
robo_armis in only one outfit, so it is hidden inplainand shown incyborg;wearis in both, so the clothes stay on either way, and the head, hair and tail (in no outfit) always show. The agent switches with[outfit:cyborg]; the Companion tab's wardrobe button does it by hand. background.jpgis a soft, out-of-focus room picture (1920×1080) drawn blurred behind her.
Beyond this sample: cloth, walking and 2.5D
This pack is the smallest one. Two other real packs show the rest of model.json:
- Yuzuki (
plugins/yuzuki, published asagentparley-yuzuki) is a VRM with four outfits that set body shapes, an ARKit face map, tail and earpartsGestureclips, and awalkclip ("roles": ["walk"]) so she paces. Her Casual, Loungewear and Swimwear outfits carry"cloth": [](no skirt), so only Dress uses the skirt the stage detects. She declares noframing,pacingorclothof her own: the defaults apply. - Mira (
infrastructure/plugins/hello-live2d) is a 2.5D look in a.zipwithavatar:motions and aframingblock (defaultPreset: "upperBody", afacewindow ofbottom: 0.58,top: 0.86). It declares nowalk, outfits or cloth, which a 2.5D look can't use.
See Companion packs for every field and what the stage does when you leave one out.
The item pack — Sample Companion Items
A second fixture, infrastructure/plugins/sample-companion-items, ships two props as data (no code, no permissions):
readme.md
companion-items/mug/ item.json mug.glb thumbnail.png
companion-items/party-hat/ item.json party-hat.glb thumbnail.png
{
"name": "Mug",
"description": "A warm mug of coffee, held in the right hand.",
"model": "mug.glb",
"thumbnail": "thumbnail.png",
"attach": { "bone": "rightHand", "position": [-0.03, 0, 0.03], "rotation": [0, 0, -90], "scale": 1 }
}
Install it next to the companion pack and the mug and the hat show up in every 3D companion's wardrobe menu; the agent can write
[hold:mug], [hold:party-hat] or [hold:none]. See Companion packs.
Two characters, two patterns
Sample Seed — the pack's own look, plus the built-in Rose look as a second option:
{
"name": "Sample Seed",
"vibe": "A test character with a plugin look that brings its own motions.",
"look": "sample-seed",
"soul": "You are Sample Seed, a cheerful test companion. You keep answers short and friendly.",
"instructions": "You talk with the person out loud. Keep replies to a sentence or two and avoid lists.",
"voice": {
"description": "A bright, friendly young voice.",
"suggestions": [
{ "provider": "fish-audio", "voiceId": "8ef4a238714b45718ce04243307c57a7", "voiceName": "Sample voice" },
{ "provider": "elevenlabs", "voiceId": "21m00Tcm4TlvDq8ikWAM", "voiceName": "Rachel", "models": ["eleven_v3"] }
]
}
}
Sample Rose — the built-in Rose look, only a new personality and voice:
{
"name": "Sample Rose",
"vibe": "A test character on the built-in Rose look, with a voice only Deepgram offers.",
"look": { "builtIn": "rose" },
"soul": "You are Sample Rose, a calm and precise test companion who keeps people on track.",
"instructions": "You talk with the person out loud. Be brief and clear.",
"voice": {
"description": "A calm, clear woman's voice.",
"suggestions": [
{ "provider": "deepgram", "voiceId": "aura-2-thalia-en", "voiceName": "Thalia" }
]
}
}
How she moves is data too. A character may add a
behaviourblock next tovoice, for example a calmer listener who reacts to her name and to the web-search tool:"behaviour": { "temperament": { "energy": 0.9 }, "behaviours": { "backchannels": { "strength": 0.75 } }, "wordReactions": [ { "phrases": ["{name}", "seed"], "reaction": "browRaise" } ], "toolActivity": [ { "when": ["builtin:web_search"], "reaction": "reading" } ] }Voice suggestions are ordered. Sample Seed's companion uses fish.audio if the account has it, else ElevenLabs. An account with neither gets captions only, with a notice offering to add a voice provider — which is exactly what Sample Rose shows on an account without Deepgram.
A character is a look + a suggested agent. In the Companions gallery (tagged with the plugin's name), Talk creates a new agent with the suggested soul and instructions; Talk as… adds the face to an existing agent.
The instructions are written for speech — short, no lists — because a companion's replies are spoken.
Publishing it
A pack with binary files is published as a zip (Publish from a .zip file instead, or
POST /plugins/{id}/versions/zip). Every binary must be referenced by one of the JSON files, or the publish is
refused naming it. See Companion packs.