3D / VRM
live-vrm Heavy — wants a real GPUA real 3D body with a living 2D face painted onto it — the whole figure walks, sits, gestures and speaks, and its face is drawn by the same engine that runs the flat avatars.
WebGL through three.js and the VRM humanoid standard. The face is a 1024×1024 canvas, painted by the Hybrid engine, swapped in as the head material's texture.
What it can express
- A whole body, not a head — 45 expressive body verbs — nod, shrug, wave, point, lean in, walk, hop, celebrate, hand-heart, stance shifts and more. (The roster file holds 52 keys; seven are rig-calibration verbs for checking a body's joints.)
- Four families of talking hands — hand-talk precise, open, soft and lively — the gesture register changes with what is being said
- Presence when nobody is typing — a library of choreographed presence acts on auto — stage walks, a wave, a knock on the inside of the glass, a full 360, a stretch-and-reset — rate-limited by a rolling energy budget and per-act cooldowns, never repeating an act until the others have played
- Attentive while you talk — during your turn the idle pool narrows to 4 listen-legal picks — tilt, nod, weight shift, elbow ease; wandering eyes and stage strolls sit the moment out because they read as inattention
- Rest by word — ships OFF — armed on the stage's presence panel, the guest says “quiet time” and motion quiets while breath and blink continue. The mic is never muted and no audio track is touched — which is why any word wakes her with no wake phrase, and that part cannot be dialled off. Never costs a reply.
- Held promises — ships OFF, no switch yet — “remind me to stretch in 20 minutes” sets a real timer, up to 12 held, five seconds to seven days, on a deliberately narrow digit-anchored grammar. Complete and running on the stage, but with no control of its own yet — see Honest limits.
- Speaking up on her own — ships OFF, and it spends — the one presence lane with a meter: in a call you already started, she may speak in a quiet moment — that turn spends your own AI & voice budget, same account, same meter as every turn. Needs an accepted consent card as well as the switch; defaults cap it at 2 per call, 6 per visit, one every 2 minutes.
- Postures and locomotion — it can stand, kneel, sit on the floor or sit in a chair (which brings the chair), and it can walk, spin and hop between them
- Six body moods that retint everything — serious, warm, empathetic, playful, curious, reassuring — a mood change re-colours posture, hands and face together
- The full 2D face rack, in 3D — because the face is painted by the Hybrid engine, it inherits the same brows, lids, lashes, lips, teeth and 25-mood recipes — the 3D body does not get a cruder face
- Touch responses — shy, flinch, protest, startle and look-away reactions to being touched on screen
- Wear any VRM model — the stage ships no model at all — you drop a .vrm and the body-verb lane drives its humanoid bones; nothing you drop leaves your machine
- Reduced motion is a hard clamp — if the visitor asks their OS for reduced motion, motion is scaled to 0.4 and the agent itself cannot override it — it re-clamps live if the setting changes mid-session
- A 110-dial control panel — identity, persona, character, hands, motion, presence, backdrop, device and initiative — the deepest configuration surface in the estate
Moods: two systems at once — six body moods retinting posture and gesture, and the full 25-mood face engine painting the head. The only engine here where body and face carry emotion separately.
What it costs a device
| measured on this box | 375×667 | 1440×900 |
|---|---|---|
| cold mount → first frame | 1,445 ms | 2,192 ms |
| rAF fps — idle | 2 | 1 |
| rAF fps — speaking | 1.7 | 1.3 |
| CPU cores busy — idle | 6.20 | 5.31 |
| CPU cores busy — speaking | 5.49 | 5.74 |
| worst frame gap (p95) | 883 ms | 1,350 ms |
| over the wire | 9.71 MB | 9.71 MB |
| JS heap | 51 MB | 51 MB |
Two orders of magnitude past every 2D engine, and the only one that cannot hold frames at all: 1–2 fps with worst-case gaps approaching 1.4 seconds, burning 5–6 CPU cores. This is SwiftShader doing on 18 server cores what a GPU is meant to do — a real GPU changes this number more than any other on these six cards, so read it as "needs a GPU", not as "2 fps on your phone". The 9.71 MB is one of the SMALLEST models on disk; the rack runs to 148 MB.
Why heavy: A full 3D scene with skinned humanoid bones, rendered here with no GPU at all. This is the one engine whose class is decided by the hardware rather than by the code — give it a GPU and it moves; withhold one and it cannot hold a frame.
Dials it really exposes today
Try it
/alive-site/demo/wire-sw/vrm/
The config door — all 110 dialsgated · walt pass/alive-site/demo/wire-sw/config/
The wire figure — the rig contract, ungatedopen/alive-site/demo/wire-sw/body.html
Honest limits
- It needs a real GPU. Measured here it managed 1–2 frames per second with worst-case gaps near 1.4 seconds while burning 5–6 CPU cores — because this box has no GPU and rasterizes in software. That is the honest shape of the requirement, not a phone prediction.
- The models are big. The one measured here is 9.4 MB and is among the smallest on the rack; the largest on disk is 148 MB. That is the download before a single frame is drawn.
- Most models cannot wear the live face. The face plate needs a specific rig baked into the model; of the models checked, only the purpose-built liveface one carried it — everything else falls back to a plain VRM head.
- The stage is gated behind the walt pass. The page still returns 200 to everyone — the gate hides the UI, it is not access control, and nothing behind it is protected.
- Before any model loads, the 3D vendor stack alone is about 2.3 MB of JavaScript — three.js core and module, the VRM plugin and the glTF loader.
- All three named presence behaviours ship switched off. Rest, held promises and speaking-up are each
falseby default in the source — the stage you load carries them but performs none of them until someone arms them. That is deliberate, and it means a fresh stage is not a demonstration of them. - Held promises have no control surface at all yet. The rest lane has a panel section on the stage; the reminder lane has none, and no row in the config registry either — its own source comment says the panel is owed. Today it can only be armed from a developer console, and the arming dies with the page.
- The config door lists these dials but does not yet deliver them. Its apply step sends exactly two things to the stage — the backdrop and the model pointer — and says so in its own output; every other field, presence and initiative included, is saved to your agent file and waits on a seam that has not landed. Setting a rest phrase there today changes nothing on the stage.
- The rest lane's spoken tier does not exist on this base. The dial is present, but the stored value is deliberately not consulted — the read returns
offwhatever you set, because the entry point it depends on has not landed. Rest still works; it just answers in written text and motion, never in speech. - Speaking up currently has one real reason to speak, not two. Of its two fact classes only “still connected” is ever staged, and that one is capped at once per call — the “unanswered question” path is declared in the state machine but nothing reaches it yet. Switched on, expect her to speak up rarely.
Numbers are software-renderer numbers. Measured 2026-08-04 on the estate box
(18 vCPU, load 2.8–5.3 during the run) under chromium_headless_shell-1232 + SwiftShader, 3 runs per cell, median reported.
SwiftShader rasterizes on the CPU, so a real phone GPU changes the picture — most of all for 3D.
Read the ordering between engines, not the absolute figures.
Evidence for every claim: CARD-FACTS.md. Harness: work/measure-engines.mjs.