Examples

Example: Sample Companion Pack

A data-only pack — a motion set with a tail wag, an avatar model, and two ready-made characters.

Example plugin · 1 motion set · 1 model · 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-motions/sample-moves/
  motions.json
  idle-neutral.vrma  talk-idle.vrma  listen.vrma  think.vrma  wave.vrma  laugh.vrma
  tail-wag.glb
companion-models/sample-seed/
  model.json  seed-san.vrm  thumbnail.png
companion-characters/sample-seed-character/character.json
companion-characters/sample-belle-character/character.json

Four keys — sample-moves, sample-seed, sample-seed-character, sample-belle-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.1.

The motion set

motions.json gives every base role one body clip, plus one gesture and one reaction, plus an extra-parts gesture:

Clip Role Format Notes
idle idle VRMA required — every set needs at least one idle
talk-idle talkIdle VRMA the loop while speaking
listen listen VRMA a nod while the user talks
think think VRMA hand to chin while the agent works
wave gesture VRMA cues: ["happy", "excited"], strokeSeconds: 0.6
laugh reaction VRMA cues: ["laughing", "chuckling"] — plays on a [laughing] line
tail-wag partsGesture GLB clip: "Tail_Wag" — a tail-only animation
{
  "key": "tail-wag",
  "file": "tail-wag.glb",
  "clip": "Tail_Wag",
  "role": "partsGesture",
  "name": "Tail wag",
  "description": "Wags her tail — happy."
}

What this shows:

  • VRMA clips need nothing else — no clip, no rig; they always drive the humanoid body.
  • The tail wag is a plain GLB with only tail bones. It needs clip (the animation's name inside the file) but no rig, because it moves named extra bones, not the body. At publish the server reads which bones it animates; at play time it's only offered to avatars that actually have those bones.
  • cues and strokeSeconds let the companion land the wave on a happy sentence at the right beat.

The model

{
  "name": "Sample Seed-san",
  "description": "A copy of the built-in Seed-san model, offered as a plugin companion model for testing.",
  "avatar": "seed-san.vrm",
  "thumbnail": "thumbnail.png",
  "defaultMotions": { "key": "sample-moves" }
}

A VRM avatar with its own thumbnail, defaulting to the pack's own motion set by key. When a user builds a companion on it, the avatar is copied into their account — it survives an uninstall.

Two characters, two patterns

Sample Seed — everything from the pack:

{
  "name": "Sample Seed",
  "vibe": "A test character with a plugin look and plugin motions.",
  "model": { "key": "sample-seed" },
  "motions": { "key": "sample-moves" },
  "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", "model": "eleven_v3" }
    ]
  }
}

Sample Belle — built-in look and motions, only a new personality and voice:

{
  "name": "Sample Belle",
  "vibe": "A test character on the built-in Belle look, with a voice only Deepgram offers.",
  "model": { "builtIn": "belle" },
  "motions": { "builtIn": "neutral-professional" },
  "soul": "You are Sample Belle, 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" }
    ]
  }
}
  • 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 Belle shows on an account without Deepgram.
  • A character is a look + motions + suggested agent. In the Companions gallery (tagged Plugin · Sample Companion Pack), 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.

The fastest way to build your own: create a motion set in Companions → Motions and use Export as plugin package — it writes this layout for you, with bone names already correct. See Companion packs.