CommsLink Chat — The Complete Systems Reference
Last updated: 2026-09-02. This is a living document: it is shown to users at /chat/about and is
simultaneously the canonical orientation file for AI engineers (Claude) working on the project. If you
change a system, update this file in the same change — it lives at
services/web/content/chat-systems.md.
What this is
CommsLink Chat is an AI assistant with a voice and a 3D avatar. You talk to it by voice or text; it has a persona and gender you choose, remembers you across conversations, and runs real agents on your behalf (web browsing, terminal commands on your servers, a live trading desk). By default a new conversation is just the assistant — a responsive avatar on a plain stage, nothing to set up.
Optionally, on a Meta Quest 3/3S you can scan your real room and have the assistant inhabit it in passthrough AR — life-size, aligned 1:1 with your furniture, walking your floor, sitting on your furniture, making eye contact, feeling your touch, and seeing your body and gestures. That immersive "My Space" mode is opt-in, and VR is not the current focus; the sections below document it alongside the everyday assistant. Assistants are personas — you choose who they are, including their identity, personality, and gender.
The north star: an AI assistant that feels genuinely present and useful — voice, a responsive avatar, real memory, and real agents — with the option to step into your real space when you want it.
Table of contents
- The world: the stage, and the optional scanned room
- The assistant's body
- Touch and physics
- The assistant's senses
- The assistant's mind
- Motor schemas and habits
- Voice, rooms, and multiplayer
- Retained capabilities and roadmap
- For engineers: architecture and rules
1. The world: the stage, and the optional scanned room
By default the assistant stands on an empty stage — a plain dark backdrop with just the avatar, framed as a chest-height portrait that the camera follows as they move. This is the chat-first default; there is nothing to scan.
Optionally, scan your real room at /scanner (Quest 3/3S) to enter "My Space" mode: the scanner
drives Meta's Space Setup (walls, floor, ceiling, and labeled furniture volumes — bed, couch, table,
screen, storage), captures the scene as a SpaceScan (planes with polygons, objects with oriented
boxes and mesh vertices), and saves it per-user via POST /api/v1/space. The two live scene modes are
'avatar' (the empty stage, default) and 'myspace' (your scan); there are no virtual scene
templates (docs/MYSPACE_PIVOT.md).
A saved scan is a snapshot of Meta's room model, so it goes stale when the furniture moves — and
pressing Start scan again only re-reads the same model. Re-scan room (on /scanner and /vr)
calls XRSession.initiateRoomCapture() to reopen Meta's Space Setup itself so the room can be redrawn
at the source; the revised planes and meshes then stream back into the live session, replacing the old
ones. It has to be armed from the launcher before entry, because DOM controls are unreachable once the
headset is in-session.
/scanner and /vr draw coloured filled surfaces only — walls, floor, ceiling, and furniture
as bounding boxes. They do not create LineLoop / LineSegments / EdgesGeometry or
wireframe: true materials. Door and window planes render as a rim with a hole (openingFrameMesh)
so passthrough shows through the opening; filling that polygon or boxing the matching mesh is what
read as a solid door. Those meshes are not drawn. Door/window planes are four frame strips, never a
filled pane (Shape holes silently filled the door). Meta often leaves the doorway inside the wall
polygon; the wall is split into quads around the door (wallPiecesMinusDoors) so the opening stays
empty. Furniture uses a box so Meta's triangulation cannot
show through as edges. The plane allowlist is walls/floor/ceiling/window/door; the mesh allowlist is
desk/table/couch/bed/storage/shelf/screen/lamp/plant. Meta's unlabeled other bucket stays out of
/scanner by default. /vr still judges unlabeled meshes on footprint (1.5 m², cap four) via
selectDrawableMeshes — those are fills now, not outlines, and openings are skipped even with show-all.
The global mesh (Meta's whole-room reconstruction) is still captured and saved, but it is hidden
unless "Show room mesh" is on, and even then it is a translucent shell, not a wireframe. The old
40×40 depth net of raw depth lines is gone. If the measured line-object count is 0 and lines are
still on screen, they are the Quest's own Guardian / Space Setup overlay, composited into passthrough
outside WebGL — HIDE EVERYTHING on both pages turns off the three.js scene root to prove that.
initiateRoomCapture() (Re-scan room) opens Meta's Space Setup; Meta draws its own capture lines
while that UI is up, and no website can hide them.
Voice room editing (/vr). The headset has no Web Speech API, so speech reaches the server as raw
PCM — but over an isolated /vr Socket.IO namespace that does one thing: microphone in, transcript
out. No LLM, no agent, no credit metering, and nothing that can reach a chat room. Transcripts are
parsed on the client by the same deterministic parseEnvCommands module Chat uses and executed
against the same EnvironmentEngine, so the two apps share one grammar rather than forking it. The
voice channel requires a signed-in session because transcription is billed per second; the page
itself stays public.
The microphone repairs itself, because inside a headset nobody can repair it by hand. Opening a mic needs a user gesture, and the page that could provide one is unreachable the moment the session starts — so every way the audio path could die used to end speech for the rest of the session in silence, with the indicator still lit and audio still streaming into nothing. Three of them, now handled: the server keys a transcription session to the SOCKET, so a dropped websocket meant every chunk after it was discarded — a reconnect now asks for a new session; the server closes an idle session to stop billing, which released the microphone, so it now reopens the session and keeps the stream; and the audio graph stops producing samples when its context is suspended out from under it (a headset entering an immersive session, the page backgrounded), so capture watches its own sample clock and rebuilds the graph around the SAME granted stream — no second gesture, because the microphone was never let go. Each of those, and every failure that is genuinely fatal, is reported to the server log, since a status light on a page nobody can see is worth nothing. Before Enter VR, two dropdowns pick the assistant VRM and the wearer's VRM (or Ghost) from the shared roster; those choices load when the session starts.
Colour is part of that grammar: "Computer, change the colour of the walls from grey to white", "paint the floor black", "make the door frames black". Walls, floor, ceiling and frames each render through one shared material, so a colour repaints every instance at once, and painting also reveals — setting a colour on a surface left as a passthrough occluder would otherwise be a silent no-op. Colours persist per browser with the rest of the environment state. Colour is parsed BEFORE the opening grammar, because "make the door frames black" would otherwise cut a doorway.
Two views of the same room:
- Desktop replica — on a monitor, the scan renders as a recentred hologram-style model (glowing surfaces, labeled furniture) so you can watch your assistant in "your room" from outside.
- Hologram mode (the immersive option) — in the headset, entering VR from the chat starts passthrough AR and re-reads the live scene every frame in the current session's coordinates, which makes the assistant world-aligned with reality by construction: they stand on your actual floor and sit on your actual bed. Live geometry and the saved replica are kept in strictly separate coordinate frames.
The editable environment (voice-commanded). In hologram mode the room's shell — the wall, floor, and ceiling planes of the live scene model — always renders as passthrough occluders: depth-only masks that keep a persistent digital outdoor world completely hidden behind reality until the user opens it. That world surrounds the room at all times: grass terrain, a long beach with an animated ocean on one side, mountains on the other, trees swaying in a breeze, seagulls circling the shore, and a full sky dome with sun, moon, and stars.
Standalone /vr (not Chat hologram). The headset app at /vr uses the same EnvironmentEngine
for the room shell — occluders, door/window cuts, paint, lamps — and the outdoor world, so a cut
door looks out, not back into the room. The 520 m world disc is snow (cover: 'snow'), with
the floor polygon punched out (buildGrassGeometry) so snow cannot occupy the real floor. The
smaller sand strip and ocean plane stay off (beach: false) — those were the fake floors through a
doorway. Precipitation is always snow at one ninth rain speed (precip: 'snow'), without writing
weather: rain into Chat's shared env store. Chat hologram still has green grass, beach, ocean, and
weather-driven rain. The assistant stands at the floor-polygon centroid, facing the wearer
(lib/vr/companionStandPose.ts); if the wearer is already at that point they stand ~1.1 m off so
the two bodies don't overlap. Wait until Space Setup has a floor — do not spawn 1.7 m in front of
the camera.
Saying "Computer, …" edits the environment:
make the walls / floor / ceiling / bed / desk … visible— swaps that object from passthrough to a digital render (furniture becomes a solid holo volume);… invisiblereturns it to camera passthrough.cut a window here/cut a door here— cuts a framed opening into the wall being looked at, revealing the outdoors through the hole;remove the window / doorseals it. A door reaches the floor, so the wall is split into leftover quads around the opening (wallPiecesMinusOpenings) — a Shape hole that kisses the floor contour silently filled the pane and the real wall came back from some view angles. Duplicate coplanar wall planes get the same cut. Openings persist across sessions under intrinsic wall keys (label + wall span + distance from the room centroid), so they survive the death of session coordinates.make the sky visible/make the ground visible— opens the ceiling / floor occluder onto the sky dome / terrain;… invisiblerestores passthrough above or below.make it sunrise / morning / noon / afternoon / sunset / evening / nightandmake it rainy / foggy / cloudy / clear— atmosphere presets drive the sun and moon light, sky shader, fog, and rain particles (rain never respawns over the room footprint, so an open sky does not rain indoors). Commands combine in one utterance: "make it night time, and rainy".add a wall lamp here / add a ceiling light/remove the lamp— placed fixtures carry real point lights (max 4). Lights illuminate digital content — the assistant, solid volumes, the digital shell; camera passthrough cannot be lit.add a mirror here / remove the mirror— one wall mirror (a real planar reflection rendered from a mirrored virtual camera). It reflects only digital content — your worn avatar, the assistant, solids — because passthrough is a camera feed, not scene geometry, and cannot be reflected. The mirror's virtual camera renders the avatar's third-person (full-head) layer, so a user wearing an avatar sees their own face — the point of dressing up.- When several scanned objects share a label, a visibility command applies to the one being looked at ("make the table visible" while facing it); said without a gaze target, it applies label-wide.
list commands— reads the full command set back and prints it to the chat panel.
Environment edits are rendering-only: openings never change the walkable floor polygon. The one
deliberate, revocable exception: when the user has cut a door, the assistant may choose to step
outside through it — two walk legs, doorway first, so the body passes through the hole — onto the
digital terrain, and always comes back in when asked. The Movement Director only offers
gooutside/comeinside when a door actually exists, and the assistant's context carries the live
environment (time, weather, openings, inside/outside). A user who walks through a real doorway
simply leaves the occluder shell and stands in the outdoor world. State persists on-device
(openings and wall lamps under intrinsic wall keys); modules: lib/avatar/envModel.ts (pure
geometry, presets, leftover-quad door cuts), lib/avatar/envShellGeo.ts (shell BufferGeometry),
lib/avatar/envCommands.ts (pure parser), lib/avatar/envWorld.ts (outdoor geometry),
lib/avatar/environment.ts (renderer) — the pure modules are unit-tested.
Geometry invariants:
- Surface heights come from actual mesh vertices under the pose (
spatial.worldTopY), never from box centers plus local half-heights. - "The surface a body is on" is a 3D predicate (
surfaceUnder): footprint containment plus a top below the head at plausible clearance; the highest qualifying surface wins. - "Fits lying" requires length and depth and reachable height (
canLieOn).
2. The assistant's body
The assistant is a VRM avatar (VRoid-compatible; admins can add models of any gender or style)
driven by an engine in services/web/lib/vrm.ts with subsystems extracted into lib/avatar/*
(spatial math, schemas, player body, wrist UI, chat panel). Movement is procedural — walking gait,
turning, sitting, lying — computed against the scanned geometry, not canned clips.
The user wears an avatar too. Just as the user picks the assistant's VRM, they pick their own
from the same roster (lib/avatar/avatarRoster.ts — Eve, Enmiel, Amane, Everyman, Rai,
Aneki; Shibu and Melon (day) are admin-only) — plus a "Ghost" option (the debug skeleton,
no avatar). Every name is tagged (M)/(F); admin-only models are hidden from non-admins in both
pickers. Chat's avatar panel and the /vr launcher share those two dropdowns and the same
localStorage keys, so a pick on one screen is waiting on the other. Voice switching comes later.
Both the assistant choice and the user's own-avatar choice persist across sessions; a
never-chosen user defaults to Ghost (and Eve as the assistant). In hologram mode the chosen VRM is driven by the
same body engine that already solves the user's skeleton for the ghost: each solved joint
retargets onto the humanoid rig via measured-rest aiming (every driven bone's bind direction is
measured at load, so no model-axis assumption survives), the real headset quaternion drives the head,
tracked hands terminate the arm chains, and spring bones carry the motion of hair and clothes. When
the headset provides hand-tracking, the avatar's fingers articulate — each VRM finger bone is
aimed from the matching WebXR finger-joint segment, so the hands curl with the user's real hands. The
torso and legs follow the body's facing (parent-local aiming) while the arms aim in world space; the
left/right mapping is read from the VRM's own bone sides, so a camera-facing rig can't invert it. The
worn avatar replaces the ghost's tube visuals only — the engine, self-diagnosis, and snapshots keep
running underneath, and the whole avatar renders in first person (look down to see your body and
hands) as well as in the mirror. The chosen avatar's gender is sent to the assistant's
context, so it refers to the user with the right pronouns — the user's chosen embodiment is treated
as their gender in the shared space.
- Anchors — every labeled surface exposes computed spots: a sit-edge (seated at the lip, feet toward the room, at the surface's real height), a lie position (feet and head both constrained onto the mattress, head toward the pillow end), and stand-near points. Fit rules downgrade gracefully (can't lie on it → sit on it). While seated on a surface, facing is locked to the outward edge direction, so in-place turns cannot sweep the legs through the furniture volume.
- Routing — the assistant paths around furniture (
spatial.routeAround), never walks through walls (targets clamp to the floor polygon), and can't idle inside furniture (penetration resolves out). - The lie wall-gate — every lying pose, from any source (command, push, settle), is validated as
a full body segment against the room + lie-capable surfaces before it applies
(
enforceLieInRoominsidelieDown, the single choke point). The body cannot end up through a wall. - Render conventions — the model root composes rotation in
YXZorder so lying yaw is honored by the renderer. - Hair — spring-bone physics with a gravity floor (drapes when lying down) plus colliders that track your hands, so hair parts around your fingers.
3. Touch and physics
Touch is graded pressure through per-bone colliders, not events: the assistant's body is ~17 sphere colliders on their actual bones, and what your contact does depends on penetration depth. Every touch also resolves to a precise skin region in the touched bone's own axes (pose-invariant — inner thigh stays inner thigh lying down): ~40 named regions including a full facial map (forehead, nose, lips, chin, cheeks, ears), throat and nape, collarbone, ribs, waist, groin, individual butt cheeks, inner vs outer thighs, shins, calves, and feet.
There is also an anatomy education mode: a wrist-menu "Anat" toggle renders the skin as a glassy
translucent shell containing a full skeleton (bone shafts between every joint, skull, pelvis,
ribcage — the same structure the grab system operates on) and procedurally-shaped internal organs at
true anatomical anchors (a beating heart with vessel stubs, asymmetric lungs, two-lobed liver,
J-curved stomach, bean kidneys, the digestive tract from trachea to sigmoid colon, and the
reproductive system), all tracking the body through any pose. The brain's hemispheres show live
cognition (left lights while the verbal mind speaks, right while the motor/instinct systems run),
and the assistant can point to any body part on themselves (organs included) via the Director's
pointto:<part> move, with their own knowledge doing the teaching.
- Graze (< 2 cm): felt only — the touch enters the assistant's awareness by region name, and the contact renders as a glow on the user's own fingertips (per-finger, brightening with pressure); nothing moves. Tracked hands render as realistic hand meshes.
- Light press: only the touched part yields (the head tilts away a few degrees, an arm gives), and springs back when you lift off.
- Deep press: real force — proportional displacement, waist-bending (a spring at the spine), and past a threshold a balance break: the knees buckle, and a seat-height surface behind the legs catches the fall onto it; on open floor the assistant goes down and gets back up.
- Contact sources: your palms, all ten fingertips (touch-only — a fingertip cannot shove), your head, and your whole estimated body (chest, elbows, knees, feet). Body closeness is contact, not force — displacement requires actual approach motion, so cuddling doesn't push them around.
Where the skin actually is. Contact is resolved against the assistant's real mesh surface, not a capsule approximation of it — but without raycasting that mesh, which costs the whole model per ray because a skinned mesh must be re-posed to answer. Instead each bone's surface is measured ONCE into a radial field: for every slice along the bone and every angle around it, the distance out to the skin, recorded in the bone's own frame. A limb's shape relative to its own bone never changes — a forearm is the same forearm bent or straight — so that measurement is valid in every pose, forever. Querying it is arithmetic: put the point in the bone's frame, read the radius for that direction, compare.
The grid spans the FLESH, not the bone. A bone segment is often far shorter than what it carries — hips-to-spine is about five centimetres while the flesh around the hips spans thirty — so a grid laid over the segment clamped every groin, buttock and lower-back vertex into its last slice and collapsed the region to a single ring. Long bones hid the fault completely, because a thigh's flesh does fit inside it. Each field therefore records where the flesh starts along its axis as well as how far it extends.
The coarse capsules that decide which contacts are worth testing exactly are derived FROM the field — its own axis span and its widest radius — rather than from a separate measurement. Two measurements disagreeing means the capsule can miss a contact the field would have reported, and a contact the capsule misses is never refined, so the field would have no say at all in what a hand can feel.
The measurement can also be corrected by hand, in the headset. The precise tool is a PIN: hold a
fingertip exactly where the skin really is and say right here, and the surface snaps to that point —
a statement of fact rather than an analogue drag held against a moving surface. edit skin additionally
allows pinching and dragging the shell for small nudges, and draws that shell for you, because dragging
a surface you cannot see is not editing. Switching editing off takes it away again — plainly, every time,
with show skin to put it back. An attempt at being cleverer than that, leaving a shell alone if the
person had switched it on themselves, was removed: the shell is restored from saved settings at startup,
so anyone who had ever left it on got an "edit skin off" that deliberately left the lines where they were.
Because the field IS a radius per direction,
both are writing one of those numbers, so this is the same representation being edited rather than a
second one laid over it. Edits are recorded as strokes in grid-independent coordinates and stored
ALONGSIDE the measurement, never baked into it — so they can be undone after a save, and survive the
model being measured again or the format changing resolution. save the skin keeps them for that model
for everyone; reset the skin returns to the measurement. stasis holds the avatar still and silent
while you work — judging or editing a surface that is breathing and shifting its weight is guesswork.
The field is measured by ASKING THE SURFACE, not by sorting vertices. For every cell, a ray is fired outward from the bone's axis and the crossings it makes are the skin in that direction — whatever mesh those triangles belong to, however their weights are blended. Sorting each vertex into the bone that owns most of it only ever gave a biased sample of the shape: a vertex split between two bones goes to one of them, a cell no vertex lands in has to be guessed from its neighbours, and flesh carried on a spring chain belongs to no humanoid bone at all. The rays run ONCE, on the bind pose, and produce the same fixed set of numbers as before — nothing is refit, and nothing about this costs anything per frame. Cells no ray reached keep what the vertices said, so the fit can only improve a measurement, never destroy one.
A crossing counts only if the triangle it lands on is part of the bone being measured — see "a bone measures its own flesh". Because of that, a bone whose surface is mostly covered by its neighbours (a spine, behind the belly and under the ribs) legitimately measures a third of its cells and no more, and a partial fit is kept as a partial improvement. Only a fit that measured NOTHING is discarded, which is a broken raycast and looks exactly like success from the outside.
Along each ray the outermost layer wins, but only across gaps of a few millimetres. A shirt sits just off the skin and is what a hand meets; the air between an arm and the torso behind it is far wider, and a shell that grew across that gap would report contact in open space. Taking the nearest crossing instead measures the naked body under the clothes — which is the same bug, seen from the other side.
A vertex owned by a SECONDARY bone is attributed to the humanoid bone above it. Models put the parts
that move on their own — a bust, a skirt panel — on their own spring chains, which carry no humanoid
name; skipping those dropped precisely the outermost surface of the chest and groin while keeping the
flatter mesh behind them. show skin draws the measured surface as a shell, so a measurement that
floats off the model or sits inside it can be seen rather than inferred from where a mark landed.
The surface measured is the OUTERMOST one, clothing included. What you touch on a dressed body is the cloth, and a model keeps both layers — measuring only the body mesh put contact underneath the shirt, so covered regions read as having no detection at all until a finger had already sunk through what you can see. Hair is the one exclusion, and not because it is ignored: the model's own spring-bone simulation now carries a collider on each of the user's fingertips, so hair, a scarf or a skirt PARTS around a hand and the surface underneath is what the finger meets. The author's own hair settings are untouched.
Each bone's axis is measured and stored alongside its radii. Where a bone has a child the rig gives that direction directly; where it does not — a head, a hand, a foot, every fingertip — it comes from the mean direction of the bone's own vertices, which points up through a skull and out toward the fingers of a hand. Those bones would otherwise have no axis, so no field, and would fall back to a sphere sitting an inch off the real surface.
The field is built against the model's RAW skeleton — the bones the mesh is actually skinned to, not the normalised humanoid rig used for posing. VRM keeps both, they are different objects, and reading the mesh through the wrong one measures nothing at all while every fallback silently takes over.
Because the field describes the FILE and not the session, it is stored server-side against a hash of the model's url. The first person ever to load a character pays a few hundred milliseconds to measure it; everyone after downloads the answer. A stored field from an older format version is rebuilt rather than trusted — geometry that is silently slightly wrong is worse than no cache.
The body gives AWAY from what is pressing it. The contact normal points out of the body toward whatever is touching it, so driving along it moved a limb toward the hand — and that fed itself, since moving toward a finger deepens the contact and pulls harder still. A slow approach was met by the body snapping out to meet it. The threshold is also nearly two centimetres of penetration, so it answers a press and not an approach: the coarse capsule deliberately reaches a little past the skin, and reacting to that reads as a body reaching out to be touched.
How a touch is SHOWN is a soft contact shadow that follows the body, holds steady under a resting hand, and fades as you lift away. Twenty alternatives were built and compared side by side against rendered pixels from two angles — paint into the model's own UV texture read five ways, geometry cut or displaced or buried, and renderer techniques from a genuine cast shadow to a stencil mask to a screen-space patch. The bench measured what each one actually drew, and most of them drew a line: flat marks on a curved limb collapse to a streak the moment you look along the surface rather than at it. The original survived the comparison and the rest were deleted, because nineteen ways of being wrong are not worth carrying.
Nearby contacts are ONE press. A hand resting on a forearm produces a scatter of separate contacts — one per fingertip, more along the palm. Treated individually they are several unrelated pokes: several small marks instead of a hand, and several small pushes in slightly different directions that largely cancel, so a firm sideways shove barely moves the limb and moves it unpredictably. Contacts within about three centimetres of each other, on the SAME bone, are merged into a region with one centre, one direction, a size and a strength. Merging is single-linkage, so a hand laid along a forearm forms one long region rather than breaking into knuckles and fingertips; contacts on different bones are never merged, since those bones move differently and one averaged direction would be a fiction.
A region's direction is weighted toward its firmer contacts, its depth is the deepest single point (which decides whether it is a press at all) and its PRESSURE is the total penetration across it — so three fingers resting is a firmer press than one finger at the same depth. The mark drawn is sized to the region, so what you see is the shape of what is actually resting there.
Patches on OPPOSITE sides of the same limb are then closed into a single GRIP. They stay apart in the first pass on purpose — a thumb and a forefinger are three or four centimetres round the curve of a wrist, well past the merge radius, and as two separate presses that is correct. But a hand closed around a wrist is exactly that, and it is not two presses: the two directions cancel, so there is nothing to be pushed in. A grip acts from the point BETWEEN its patches, inside the limb, and that is what the limb is kept near. Only opposed patches close, and only within a hand's span, so genuinely separate touches are never swallowed into one averaged shove pointing nowhere.
The push is averaged before it is acted on. Contact is derived from hand tracking, which wanders by a millimetre or two every frame even from a finger held perfectly still — so driving a limb from the raw reading turns the tracker's noise into the limb's motion, and a wrist under a resting finger buzzes instead of giving way. The last ten readings are averaged instead, which answers how hard and which way something is being pushed rather than what the tracker said this instant. A frame with no contact records a ZERO rather than being skipped, so lifting a finger drains the average over the width of the window and a single-frame dropout — which tracking produces constantly — does not release the limb.
The bone then travels toward what that asks for at a limb's pace, capped in radians per SECOND so the feel does not change with the frame rate. Averaging the input and limiting the output are separate things, and conflating them was the jitter.
A touch is worth NEWTONS, and three things decide what it moves. A press used to be pure geometry: however far a finger had sunk in was how far the limb moved, which makes one fingertip exactly as strong as a whole palm and a chest exactly as easy to move as a hand.
- AREA decides whether a press does anything at all. A fingertip cannot shove: its load goes into denting the flesh under it rather than into the skeleton — press a finger into someone's chest and you get a dimple, not a stumble. Spread the same hand flat and it moves them. Half the press reaches the bone at about 20 cm², a third of a palm, and it is a curve rather than a threshold so nothing switches on at some particular number of fingers. One finger two centimetres in is about 3 N; the same depth under a spread hand is ten times that.
- FORCE is depth times a flesh stiffness: two centimetres in is a firm press.
- MASS is what the force has to accelerate, and it is real. Segment masses are Dempster's fractions of body mass — the table every biomechanics text carries — against a 120 lb avatar, so a hand is 0.33 kg, a forearm 0.87, a thigh 5.4, the whole body 54.4. Effective mass counts the limb a push has to SWING, not just the part touched: a segment rotating about a joint at its end resists at its tip as though it had a third of its mass, so pushing a hand is really pushing a hand plus a third of a forearm. The same shove that flicks a hand aside barely disturbs a thigh, and barely rocks a person at all — which is why an avatar must never behave like the cubes, which fly.
How far a joint gives is then its own stiffness in newtons per metre, ordered the way a body is: a wrist folds under a load a hip ignores. How FAST it gets there is Newton's second law against its effective mass. Those are separate questions and they were previously one number doing neither job.
The trunk does not bend; it steps. There is no joint that can answer a hand in the middle of a chest — the one above it is the spine, and rotating a spine folds the torso, which is not what a palm on a sternum does. So force on the trunk goes to the FLOOR, and what happens there is a stumble: a slide along the force against the whole body's mass, and a twist about the vertical, because a push is almost never through the body's axis.
Both fall out of the same sum. Half a palm pressed firmly on the sternum is right at the point a standing body starts to give ground — below that she holds herself up, as a person does, and leaning on her does nothing. Two hands, one on each shoulder from behind, add their pulls into a step and cancel their twists, so she comes straight back. One hand on one shoulder is off her axis, so the same force turns her as well. Neither case is special-cased anywhere; it is the lever arm doing it. She is capped to a stumble and never a launch, and once the hand comes off her feet bring her to rest.
Pulling is a grip that moves. A hold has no push direction of its own, so what drives it is where the hand has gone since last frame — and the force is whatever it costs to bring the part along, capped by what a hand that size can hold on with. Two fingertips slip; a whole hand drags. That is the entire rule for pulling: there is no separate gesture, and no separate code path.
Her feet are on the floor, not in a pose. Pushed, she used to slide with her legs frozen in whatever the animation last drew, skating across the room like furniture. A planted foot now keeps a place in the ROOM: the leg is solved to reach it while the rest of her moves over it, so the foot stays put. That one change removes the skating before any stepping is involved, because an anchor does not move when a pelvis does.
Before a foot moves, she presses on the floor. Her ankles come first, and most disturbances never get past them. That rung was missing entirely: the planner had two answers to a push — take a step, or fall over — so a hand resting on her sternum produced a march. A backward drift of a fifth of a metre a second put a foot in the air in a tenth of a second, with nothing before it.
What an ankle does is move the CENTRE OF PRESSURE, the point on the floor the ground's reaction acts through. It cannot leave the sole, which is what makes it the cheap answer and what bounds it. For a body of constant height the pendulum gives acceleration = omega squared times (weight minus pressure): pressure BEHIND the weight accelerates her, pressure AHEAD of it brakes her. The pressure is chosen by controlling the capture point rather than merely watching it — asking for p = xi + (k/omega)(xi minus target) makes the capture point decay toward where she means to stand at rate k, exponentially — and then clamped into the sole she is actually standing on. The clamp is the physics: what she asks for and what the floor can give are different quantities.
How much that buys depends entirely on WHERE HER WEIGHT SITS OVER HER FEET. Over the ankle bones there is six centimetres of heel behind it, and the same nudge is unrecoverable — she decelerates, rolls back past her own heels, and from there the pressure can no longer get behind her. But a standing body does not balance over its ankles. A foot runs sixteen centimetres forward of the joint and six back, so the weight sits near the MIDFOOT, and that is ten centimetres of heel and nearly double the braking. The difference between a body that stands through a nudge and one that marches is a geometric fact about feet, not a gain.
And between pressing and stepping there is loading a leg. A comfort step that costs her balance is not a comfort: lifting a foot deletes its sole from her support, and with her weight midway between her feet the remaining one cannot hold her. Taken anyway, it produced a loop — recover a shove, settle, tidy a foot, fall out of the tidy-up into another recovery, indefinitely. People shift onto the standing leg first. It needs no new machinery, only a different place for the ankles to aim her weight at.
The part of the request the sole could not supply is REPORTED and deliberately not credited. That residual is a centroidal-moment offset rather than a pressure one — the effective pivot of the net ground reaction, which angular momentum from a hip or an arm can move outside the foot even though actual foot pressure never leaves it. Those rungs are not built. A scalar saying the hip supplied some of it, with no achievable momentum rate behind it, is a controller manufacturing braking it has not got.
One thing decelerates her, and which one depends on whether she is standing. The trunk used to take a flat 2.5 m/s squared off her speed every frame regardless of anything — where her weight was, which way it was going, what her soles could push against. It stopped her, so it looked like feet; it was a friction constant standing in for balance, and beside a real postural controller it would have answered every disturbance twice. It is gone from there. It survives only in the case the pendulum explicitly does not describe: once the verdict is that she is going over, the model's assumptions are void and applying it anyway is not conservative but divergent — a firm shove became three times faster and climbing, and she flew across the room, correctly, according to a model that had stopped applying.
Whether she should step is decided the way postural control decides it. A standing body is an inverted pendulum, so where her weight IS settles nothing — a centre of mass between her feet but travelling at a metre a second is already lost. What decides it is where the weight is HEADING: the extrapolated centre of mass, position plus velocity over the square root of gravity over its height. And not now, but at TOUCHDOWN — a step takes time and she keeps toppling during it, so what a foot has to reach grows as exp(omega T) away from her pivot, which at 0.3 seconds is a factor of 2.7. A metre a second is a 30 cm problem now and an 81 cm problem by the time a foot lands, and those two numbers are the difference between a comfortable step and a fall.
Her weight is measured, not assumed: every segment of the body once, with mass placed ALONG each span rather than at its joint, read after the pose is composed. A bone is a joint, and putting a thigh's mass at the hip lifts her centre several centimetres and makes her read as far more stable than she is. A raised arm moves it by about a centimetre, which matters because the whole margin between standing and stepping is roughly the length of a foot.
Reach is geometry rather than a constant, and the geometry is unforgiving: a leg of length L with its hip h above a foot can only place that foot sqrt(L squared minus h squared) away horizontally. A body standing with straight knees therefore has NO horizontal reach at all, and every step it plans lands short — which is why a recovery step in a real body comes with the pelvis dropping. That crouch is accounted for; performing it is not built yet, and is the reason the steps she can currently take are short ones.
h is measured to the ANKLE, not to the floor, and the difference is not a detail. An ankle is the joint at the top of the foot and it stands six to thirteen centimetres up, depending on the model. Because the legs are nearly straight when standing, the square root is nearly vertical there, so those few centimetres cost about half the reach — and half the reach is the difference between catching a shove and finding no step at all.
The same measurement decides whether a foot is CARRYING her, and getting it wrong there was worse. The rule asked whether the ankle was within six centimetres of the floor; on every model shipped here it never is. So the planner answered "no foot is on the ground" about a body standing perfectly still, on the first frame and every frame after it, and reported a fall — which nothing consulted. Her legs stayed solved toward anchors she had long since walked away from: out in front of her, motionless, until something else reset them, and nothing else ever did. Whether a foot is carrying her now comes from the footing, which owns the anchors and knows; the height rule survives only as a fallback, and it measures against the ankle's own resting height rather than against a constant.
The planner is TOLD where her feet are; it does not read them off the rig. It runs in the same seam as everything else that poses her, which is after the animation has recomposed the whole body from scratch and before the legs are solved — so every ankle bone it can reach says "tidily under her hip", moving with her, whatever her anchors say. Reading the bones, it watched a perfectly balanced avatar that is never rendered, and could therefore never see the one thing it exists to notice.
A capture point outside her feet is therefore NOT a reason to step. It is a reason to press, and only if pressing cannot bring it back is a step the cheaper answer — because a step destroys support while the foot is in the air. That question is asked by simulating the pressure controller forward a second and seeing whether her weight comes back over her feet.
And where a step goes is decided by the same simulation. The closed form for where her weight will be when the foot lands grows it exponentially away from the edge of her support, which assumes the pressure sits pinned there doing nothing for the whole swing. It is not doing nothing — it is braking, hard, the entire time. Planned against the pessimistic figure, every sideways step came out 38 to 68 cm from the hip against a reach of 32, so no full step was ever available: she took a clamped partial one, landed short of where her weight was going, and therefore had to step again.
A step lands PAST where her weight is heading, not on it. Landing exactly on it is only marginally stable — it arrests the fall and leaves the pressure directly under her weight with nothing left to push back with. How far past is not a constant, because it depends on the shape of a foot: a sole is over twenty centimetres long and nine wide, so the overstep that stops her fore-and-aft does almost nothing sideways. The planner tries the short ones first and takes the first that leaves her ABLE TO STAND once it lands — which is asked of the support the step would create, evaluated from where she will be by then, not from where she is now.
She steps with the leg that is not carrying her. Every other measure ties: a straight backward shove leaves both feet equally placed, ties go to whichever foot is first in the list, and the winner keeps winning. Scoring the stance the step leaves her in does not break it either, because her nominal foot places travel with her root, so a foot that stepped back and a foot that stayed put end up equidistant from where they each belong. What decides it is load, and load's proxy is exact enough — weight shifts toward the foot her centre of mass is nearest, so the far one swings. It does not spoil the first protective step, because at the moment of a shove her weight is still central and reach chooses: only the leg on the side she is falling toward can get to the target at all.
And a foot that has just landed cannot leave again immediately. Her weight takes about a sixth of a second to arrive on it, and a foot that leaves before it has arrived was never carrying her — so the swing achieves nothing and the other leg, which is the one that should be moving, never gets asked.
Those four together are the difference between a recovery and a WALK. Without them a push of half a metre a second sideways produced twenty-two steps and nearly two metres of travel, all on one leg, and she was still moving at the end. With them the same push is one step per foot and fourteen centimetres.
The limit on all of it is how far she can actually step, and that is about 32 cm where a real protective side-step is nearer 50. The difference is the pelvis dropping, which the reach calculation assumes and nothing yet performs. Until it does, some disturbances genuinely cannot be caught — and saying so and going over is a better answer than an endless series of steps that each fail to catch her, which is why a step that would land more than six centimetres short of what was needed is declined rather than taken.
Stepping is a small state machine rather than a decision remade every frame. Replanning continuously is right for WHERE a foot is going and wrong for WHETHER it is going: without something that remembers a step is underway, the chosen foot alternates as the numbers wobble, the swing restarts forever, and both feet can leave the ground at once. A swing already committed may be re-aimed and never restarted or handed to the other foot.
Catching a shove takes two steps, and the second one is not about balance. One leg swings out to arrest the topple; by the time it lands she is stable again, and the balance criterion has nothing more to say — yet she is standing astride with the trailing leg stranded where the first step left it. So there is a second tier below the recovery one, which asks a different question: are her feet anywhere sensible? It scores the stance as a PAIR, because after a protective step the foot furthest from where it belongs is the one that just saved her, and against doing nothing at all, because moving either foot changes where the other one ought to be and she would otherwise shuffle forever.
Two smaller rules keep that machinery honest. A recovery step that would not actually MOVE the foot is not taken — she is on the edge of her support with the capture point landing on a foot already beneath it, and lifting that foot to put it straight back down achieves nothing while outranking everything below it, so the stranded leg never gets its turn. And a step that cannot reach all the way is taken anyway, as far as the leg goes: a step landing short still moves her support toward the fall and buys the time for another one, which is what a person does when one stride is not enough.
And the footing stands down entirely when something else owns her legs — walking, sitting, being placed — taking her current feet as the new truth rather than dragging them back to where she used to stand. Two controllers writing one set of bones is the fault this system has made more than any other, and an anchor left over from before a placement would drag a leg across the room, which is a far worse artefact than the skating it replaces.
Standing, she stands up straight. Her hip is almost exactly a leg's length above her ankle, which makes a standing pose brutally sensitive: seven millimetres of hip drop is about fifteen degrees of knee. Two things were spending that budget. The pelvis-lowering worked out how far a leg reaches assuming 98.5% of its length while the solver it feeds delivers 99.5%, so it manufactured a shortfall out of nothing and answered it by dropping her hips a centimetre — permanently, on a foot that was perfectly reachable. And an anchor took its height from wherever the animation happened to have drawn that foot, so a foot planted during a walk kept the walk's bent-knee height for as long as she stood there afterwards. She stood with her thighs angled up, her shins angled back, and her feet off the floor, and never straightened.
The reach figure is now the solver's own, and an anchor sits at the floor plus the thickness of that foot — measured off the animated pose, keeping the lowest reading, because that is the frame in which the sole was flattest. It is revised gently rather than in one jump, and the anchor moves with it: an anchor's height is not an independent fact, and leaving the two out of step has the leg solved to one height while the anchor claims another, which everything downstream reads as the foot skating.
A swing that cannot arrive still has to end. Refusing to declare support at a place the foot never reached is right — the solver clamps a target it cannot get to, so believing the command would have her balancing on a spot her foot never occupied. Refusing forever is a different fault: the foot hangs at the end of its arc, no new step can begin while one is still in the air, and the leg goes on being solved toward somewhere it will never reach, which is drawn by straightening it at the target. A leg pointing at a place it cannot get to, with the foot off the ground.
So the wait is bounded, and what happens next depends on what is actually true. Part of the wait is legitimate — the pelvis is still lowering, and a target out of reach this frame comes into reach as it does. Past that, if the sole is genuinely down she is standing somewhere, just not where she was sent, and that is a real stance the next step can be planned from. If it is in the air she is not standing at all, and planting her there would turn a visible hover into a fictitious contact that everything downstream then believes — so the foot is aimed instead at the one place always within reach if anything is, straight down under its own hip, with the arc continuing from where it actually is rather than jumping. A few attempts, then the failure is reported rather than deleted.
She can go down on her knees, onto her hands, or back onto her heels. Three postures — "on your knees", "on your hands and knees", "sit on your legs" — each a map of bone angles and a drop of her root, in the same form as sitting on the floor.
Every angle in them is MEASURED rather than eyeballed. A posture is a set of Euler angles whose effect nobody can predict by reading them, and the floor-sit that came before was plainly hand-tuned by somebody who could see the result. So these are authored and then checked against the real skeleton of a shipped model — the file itself, loaded and posed through the real normalised humanoid: apply the numbers, then ask where her knees, toes, hands and head actually ended up. Kneeling puts both knees at floor level and her hips one thigh above it; sitting back drops them to a heel's height; hands and knees puts her palms on the floor a foot ahead of her with her head lifted to look forward. A wrong angle fails a test instead of reaching a headset.
All three were wrong before that check existed, and all three in the same way: MIRRORED. Her shins folded out in front of her instead of behind, her seiza put her knees behind her, and her arms went out sideways instead of down. Mirroring is the hard case, because every HEIGHT is identical either way — knees on the floor, hips a thigh's length up — so nothing reads as broken from the numbers, or from any test that only measures how far off the ground things are. It is obvious from the side and invisible from here. One convention settles it: these are rotations about the world X axis of a bone at rest, and a bone that hangs downward (a thigh, a shin) swings BACKWARD under a positive rotation while a bone that points up (the spine, the neck) swings forward.
Two other measurements are worth keeping. Bending her forward at the waist has to be done almost entirely at the SPINE: splitting it evenly between spine and chest leaves the torso at forty-five degrees rather than ninety, because a chest's own rotation moves what hangs below it and not the chest itself. And kneeling goes through a HALF KNEEL — right knee down first with the left foot still planted flat in front, her hips already at their final height — because nobody kneels in one movement, and going straight to both knees reads as dropping through the floor into a pose.
Leaning back happens at the HIPS, not in the small of her back. All three were first written with the
lean at the spine, which curls her lower back while her pelvis stays bolt upright — a shape nobody
makes. Tipping back from sitting is the pelvis rotating about the hip joints with the thighs staying
where they are, and it measures better on every count as well: her elbow lands exactly on the floor
instead of five centimetres above it, and her pelvis sits at eleven centimetres instead of floating at
thirteen. Because hips is the root of this skeleton, rotating it takes the legs along, so each of
these carries an equal and opposite turn on both thighs — which is what leaves her legs where they were
while the body above them goes back.
And from sitting on her heels, the whole way to the floor. One gesture repeated — a hand on her chest, pushing back — takes her down four rungs, each of them a thing a person does on the way to lying down. First onto straight arms behind her: her wrists land a third of a metre back and three centimetres off the floor, which with a palm on the end of them is a hand flat on the ground, and her knees stay where they were. Push again and her arms fold to her ELBOWS — the forearms flat along the floor pointing back, which needs the elbow bent about its own axis rather than the world's — while her legs come out from under her: pelvis down, knees up, feet flat. Once more and her elbows go out from under her and she is flat on her back, knees still up.
How far her knees fall apart when her legs come forward is decided per descent, anywhere from together to about fifteen degrees, because it should not be the same every time; and the rung below keeps whatever the rung above rolled. Only a backward push moves her along this — weight on the shoulders of somebody already sitting on her heels has nowhere left to send her, and pressing somebody down is not the same gesture as pushing them over. Each rung is also a thing she can be asked for by name: "lean back", "on your elbows", "lie back". Checking a pose in a headset by pushing her through three stages to reach it is not checking it.
She gets up the way she went down. Kneeling passes through a half kneel — right knee down first, the left foot still planted — and a rise is that descent run backwards, so it passes through the same waypoint instead of blending straight up out of the floor. Sitting back on her heels rises to the half kneel first, which means her root goes UP before it goes forward, as it does when a person stands.
Weight on her shoulders bends her knees, and held there, puts her on them. The postures above could be asked for by name, which makes them a menu rather than a body. Pressing down on somebody is a thing you can feel them give way under, so there is a ladder, and it is climbed with your hands.
Lean on her shoulders and her knees bend: her hips lower a few centimetres, which IS bending them, because her legs are already solved to the ground she is standing on and her feet stay exactly where they are. Stop, and she comes back up. Keep the weight on once her knees are all the way bent and she goes down onto them, right knee first. From kneeling there are three gestures and two places to end up: weight held on her shoulders sits her back onto her heels, a hand on her chest pushing her BACKWARD does the same, and a hand on her BACK pushes her forward onto her hands.
Which of those it is cannot be read off the surface, and that is worth recording because it is not obvious. The back of a shoulder slopes steeply forward and up, so its outward normal points backward and up — press straight down on it and the arithmetic says you are pushing her FORWARD, harder than down. Measured on the model: a hand travelling vertically produced eight millimetres of downward load against nine of forward. So pressing down on a kneeling body put her on her hands, every time, however plainly downward the press was. It is decided by PART instead: a shoulder is a thing you bear weight on, and only her torso reports being pushed over. Nor can it be decided by how firm the press is — firmness saturates, so a hard press in any direction reads as full strength in every direction at once, the comparison ties, and the tie has to go somewhere.
The gesture used to eat itself. Giving way lowers her hips six centimetres and her shoulders come down with them — so the moment she began to sink she withdrew from the hand pressing her, the load vanished, and she sprang back up. Going down was gated on her knees being ALL the way bent, which she could therefore never reach. You could still get her down by chasing her, which is why it took a hand four inches below where her shoulders started, and why from anywhere sensible nothing happened at all.
Two things are now separate. How far she gives is whatever is compressing her right now, so she sinks until she has come down to meet the hand and settles there, still touching it. Whether she goes down is what she is still UNDER — a lean, remembered while contact lasts and forgotten the instant it breaks, because a hand leaning on somebody does not stop leaning because they sank. Press two-thirds of an inch into her shoulder, hold still for about three quarters of a second, and she kneels. Measured on the model in the repo, with a hand that does not follow her down.
Weight is borne where she is a PLATFORM, and nowhere else. The outer face of a shoulder slopes, so a hand round the outside of one presses inward and, by the surface's own reckoning, downward — and holding her by the shoulders folded her onto her knees. It is the same fault as the forehead and the same answer: decide by where the hand is. On top of a shoulder is standing on her; round the outside of one is holding her, and holding somebody is not pressing them.
How far she gives is now set by how HARD the press is rather than by how long it has gone on. The crouch used to integrate, so any press at all, held patiently, folded her knees the whole way whatever its weight. Legs do not work like that: they give under a load until they are holding it, and then stop. So a light hand produces a little give that stays little, which also makes the crouch worth watching — how far down she is tells you how hard you are pressing. And going all the way down wants a press at least half of a firm one, so that resting your hands on her is not a decision.
Weight on her upper ARMS counts as weight on her. Her shoulder owns only about seven centimetres of the top of her — measured on the model — and a palm is wider than that, so a hand placed an inch outboard of the collarbone lands mostly on the arm, which answers by swinging. The arm still swings; her legs now hear about it too, because leaning on somebody's arm is leaning on somebody.
The threshold is a centimetre of compression past the touch band, and the first figure chosen for it was three times that — sized off a fixture rather than off a hand with nothing to push against. Nobody in a headset can feel her: you press until it LOOKS like you are pressing, which is a centimetre or two past her skin. A threshold nobody can reach is indistinguishable from a feature that does not exist. Her knees now start giving at the first real weight, so the gesture shows something immediately rather than nothing until some invisible line is crossed. Asking for "performance" reads the press back in millimetres, for the same reason: from inside a headset, "nothing happened" cannot tell you which part did nothing. A short hold is required at the bottom of each rung, because a bump is not the same gesture as leaning on somebody. And after each rung she is left alone for about a second: she moves DOWNWARD past the hand that pushed her, so that hand is inside her shoulder for the whole descent and would otherwise read as a second press that skipped the next rung.
That downward press is collected by the trunk rather than solved by it. The trunk has four coordinates — twist, two of ground translation, and turn — and not one of them is vertical, so a vertical push is something it cannot answer and must not pretend to; it is handed on as a load for her legs. The same collection also names the direction: a contact normal here points the way the push ACTS, so downward is negative, and a hand behind her is one pointing the way she faces.
Touching her is not pushing her. Resting a hand on an arm marks the skin, tells her she is being touched, and moves nothing. You push by pressing FURTHER IN — and on a real body there is a genuine distance between those two things, the give of the flesh before the bone under it starts to answer.
There was none. Force began at the surface and rose from there, so the instant a fingertip grazed her it was already pushing, and one finger could move her inches. Force now waits until a hand is a centimetre and a half past her skin, and is rescaled across the range that remains rather than merely shifted — so a full press is exactly as firm as it ever was, and she has not become impossible to move on purpose. A palm two centimetres in is about twenty newtons; a fingertip at the same depth is under two, which is the ratio between leaning on someone and prodding them.
Contact itself is unchanged, deliberately: the mark still appears the moment she is touched, because being touched is what it reports.
A bone measures its own flesh, not its neighbour's. The surface is fitted by casting rays outward from a bone's axis and taking what they meet — and a ray does not know whose body part it hit. Going up and outward from a chest, what it meets is the SHOULDER, and further round it is the arm. The layer walk that normally protects this cannot help either: it stops at a gap of air, and there is no air between a chest and the deltoid above it. So her measured chest grew up into her shoulders and out past them, and touch fired three inches from anything a hand would call a chest — exact at the sternum, because that one direction was right.
The mesh already knows the answer, because skinning IS the statement of which bone owns which vertex. A crossing is counted only if a corner of the triangle it lands on belongs to the bone doing the asking — any corner, since the seam between two bones runs through triangles rather than between them, and a triangle belonging to NOBODY counts too, because a garment on its own spring chain may hang off no humanoid bone at all and rejecting it would measure the naked body underneath. Only a triangle that demonstrably belongs to a DIFFERENT bone is evidence against. On the models in the repo this takes the chest's shoulder-height radius from thirteen centimetres to nine, which is the difference between the chest owning her collarbones and her shoulders owning them.
The weight-aware vertex measurement bounds it as well: one number per bone rather than one per direction, which is why it cannot BE the surface, but exactly the right thing to cap each cell with.
A bone does not reach past its own end just because it is fat. The grid spans the second to the ninety-eighth percentile of a bone's flesh, so a little always sticks out at either end and the field has to round off there rather than stop dead. It used to round off with a BALL of the end ring's own radius — fine on a fingertip, catastrophic on a torso, where it hung the chest's thirteen-centimetre radius over her collarbones. A hand coming down on a shoulder was inside the chest six centimetres before it reached her, the deepest contact wins, and so pressing on the shoulders — which is how you press somebody onto their knees — pressed her chest instead.
How far the flesh actually reaches past each end is now MEASURED, per bone, per end, from the same vertices the grid comes from. On every model in the repo it is between zero and three centimetres. The cap is an ellipse of that overhang along the axis by the end ring's radius across it, so on the axis the surface sits at the last of the flesh and at the rim it meets the side of the limb with no seam.
Bodies measured before that are stored and reused for ever, so the field version is bumped and they are re-measured. Hand edits are read whatever the version says, so nobody's tuning is lost with it.
All of this is verified against the .vrm files themselves: the tests load the real models in Node, run the production measuring code over their real vertices and weights, and press down on a shoulder. Every geometric claim here was argued from a hand-written skeleton at least once, and those arguments have been wrong about as often as right — at a headset session each time.
With the skin showing, the region a hand is in lights up red and says its own name. Every accuracy problem in this stack has been reported as a PLACE — "it collides two inches above her shoulder" — and then diagnosed by reasoning about geometry nobody could look at. That reasoning has been wrong as often as right, at a headset session each time. A region that names itself turns the report into "the chest activates when I do that", which is not a deduction at all.
A push she has no way to answer is not answered sideways. The trunk has four coordinates — twist, two of ground translation, and turn — and not one of them is vertical, so a hand pressing DOWN on a shoulder is asking for something this body cannot do. Measured, on the model in the repo: two hands coming down onto her shoulders at a fifth of a metre a second used to slide her eighty-five centimetres in two seconds. Every direction, every time, however gently — she was slippery, and it is why she could never be pressed down onto anything.
Two separate causes, and the first fix for this addressed neither. A contact is solved as a constraint on VELOCITY: the impulse that stops the contact closing, given how fast the toucher is arriving.
The speed it was given is a CLOSING SPEED — the hand's whole velocity projected onto the surface normal, vertical part and all — and the row it is matched against carries only the normal's horizontal components. Scaling that speed by the horizontal share does not help, and it is worth saying why, because it looks like it should: the effective mass carries the same share squared, the two cancel exactly, and she comes out sliding at the hand's full speed whatever the tilt. What she is asked to match is now the horizontal part of the hand's OWN motion. Nothing at all for a hand coming straight down; all of it for a level push; the drag you would expect for a hand sliding along her while it presses. The tilt of the surface is not motion of the hand, and reading it as motion was the bug.
The second is the positional bias — the gentle push that eases out penetration already made. It works at a fixed rate along the row, which for a near-vertical normal is a far larger rate sideways, so a perfectly still hand resting two centimetres into her shoulder drove her across the floor for as long as it rested there. There is now none of it on the trunk at all: penetration into a torso is flesh compressing, the flesh model already owns depth and turns it into force, and a second system acting on the same depth is the double-ownership pattern behind most of the faults in this codebase.
What the vertical part becomes instead is a LOAD, which is her legs' problem — weight on the shoulders bends knees. It is measured past the touch band, the same boundary force uses, so a hand resting on her contributes nothing to it.
A toggle reads the word "off" even when its verb disagrees. The help panel says to say any of these with "on" or "off", and the skin shell was the one that threw that word away and read only the verb — so "show skin off" turned the skin ON, the single thing it could not have been asked to mean. The app was telling people to say a phrase it then did the opposite of. It is also now sayable with no verb at all, because "skin off" is what gets said on the second attempt.
And a toggle reads that word wherever it falls in the sentence. Fixing the verb left the ORDER unfixed one rule above, on editing: "off" was read only when it came last, so "turn off edit skin" and "stop edit skin" turned editing ON — and editing is what draws the shell, so the sentence asking to be rid of the green lines is exactly what drew them, every time it was said. "No more editing", "edit off" and "turn off the edit" did nothing at all. Word order is not a second opinion about what was meant: the off-words are now read from any position, and switching editing OFF no longer requires the noun, since none of those phrases can mean anything else. Switching it ON still does, because that is the direction where a loose match costs something — a mode nobody asked for that then drags her body around.
Saying a switch on, when it is already on, turns it off. Fixing the parser fixed one phrase; the class of failure it came from is that every on/off command here is SPOKEN, and speech loses short words. "Off" is one syllable, unstressed, at the end of a sentence — the position a recogniser is worst at — and there is no way to recover it from the words. But there is a second opinion available for nothing: the switch is ALREADY in the state being asked for. Nobody asks for the state they are already in, so that request is read as a request to leave it, and every switch becomes a toggle you can work by repeating it.
Only in the ON direction, and that asymmetry is the whole safety argument: a dropped word can then only ever switch something OFF. "Wake up" said twice to someone already awake must not put her back into stasis. The one thing indistinguishable from a deliberate repeat is the recogniser delivering the same phrase twice a fraction of a second apart, which it does — so the same switch worked twice inside a second and a half is the machine stuttering, not a person, and the second copy is dropped.
The state is read live from whichever subsystem owns each flag, never mirrored: a second copy of a flag is a second thing that can be wrong, and this rule is only as good as its reading. Where the state cannot be read — before a session, or with nobody summoned — the spoken word wins. Switches aimed at something, like freezing or resizing, are judged against the block you are actually pointing at, so saying "freeze" while pointing at a second block freezes that one rather than thawing the first.
She is told what is being done to her. Her body has been answering hands for a long time without the mind driving her conversation knowing any of it: she could be pressed onto her knees and pushed onto her back while, as far as she was concerned, nothing had happened. Every posture a push puts her in, every hand that takes hold of her, and every touch now reaches the agent as a sentence — "puppy gently pushed you down onto your knees", "puppy roughly touched your left shoulder" — through the same physical-events channel the Chat side has always used.
Three degrees of force, because that is how many a person distinguishes without thinking: gently, roughly, violently. The band comes from what the physics measured — newtons from the flesh model, where a fingertip is about two and a firm palm about twenty — and the SPEED of the hand can raise it on its own, because a slap is shallow and quick and is not gentle while leaning slowly with real weight is deep and slow and is not violent. Force alone cannot tell those apart.
Told as something that HAPPENED to her rather than as a state she is in. An agent handed "you are kneeling" will explain it as a choice she made. And filtered: a hand resting on her arm is one event, not sixty a second, so the same touch in the same place is mentioned again only when the hand comes back to it, when it starts being done harder, when what it is DOING changes, or after long enough that it is news.
She falls. The pieces — knowing when she is off the ground, knowing what she would land on, and handing her body between owners without a jump — are connected, and the decision is made at the one moment in the frame where it can be: immediately before her height is composed. Making it anywhere later, including where the rest of the body work lives, would publish it a frame behind for as long as she fell.
Being knocked over does not require leaving the ground, so a gap opening beneath her would never fire for a shove. The signal used instead was already being computed and thrown away: her balance planner decides every frame whether she is going over, and that verdict was spent entirely on braking. It is now what tells her she is falling.
Her feet are left alone while she is in the air rather than stood down. Those are different things — standing her down plants her feet where she is, which is how a fall would acquire ground it never had. Nothing solves her footing, nothing brakes her against a floor she is not touching, and her momentum keeps carrying her the way she was shoved.
And the moment her body changes hands is invisible. At the instant a fall takes ownership, the number describing her height changes source — from a sum the rig composes to a single absolute value — and if the new source's first frame disagrees with the old one she twitches, at the exact moment she is knocked over. So that one frame does not convert anything: it republishes what was already on screen, which is the same number rather than merely a close one. Every frame after it goes through the conversion, by which point she is moving anyway.
Handing over is also a single decision. Balance, the footing anchors, the posture ladder, the walk bob and ground friction stop together at one frame boundary, not one after another as each notices she is falling — releasing them in sequence is how half a body ends up in the old mode and half in the new. Ground friction is on that list because braking her against a floor she is no longer touching turns a fall into a slow descent, and the footing anchors are on it because those are what leave her legs standing where she used to be.
Her momentum is not handed over at all. A body shoved off its feet keeps going the way it was shoved, so the same system goes on carrying her horizontal motion throughout; zeroing it at the handoff would turn every topple into a drop on the spot. And what is captured is what was actually being shown — mid-crouch, half-seated, part way through a step — so the fall begins from exactly where she visibly was rather than from where a tidy standing pose would have put her.
There is now one owner for her height, rather than a sum. Her vertical position in the shared rig was added up from a base captured when her model loaded, a walk bob, a sit drop, a crouch, a lie lift and an air offset. That works while every term belongs to a different thing, and stops working the moment two owners want the same body at different heights - a fall and a carry would each add their own offset and move her twice, and giving them separate names would not make them separate physical quantities. A mode that owns her vertical position now answers with an absolute world height that replaces the sum instead of joining it; everything else leaves it alone and composes as it always did.
And she can ask what she is falling onto — and what she just hit, which is a different question. There was already a support query, and it asks neither: it skips anything without a name, because it is deciding whether a thing is a bed somebody could lie on. A cube nobody named is still solid, and a falling body still has to meet it.
What her height is measured against, and what her motion actually met this frame, are now asked separately. The second is a true sweep: the moment her path crosses a surface's height is solved for, her position at that moment is worked out, and the surface is tested there. Testing only where she started and ended is not enough — a body carrying sideways momentum over a long frame crosses a table squarely in the middle of its footprint while both ends of that motion are a metre clear of it, and goes straight through. The first thing actually met wins, which is not the same as the highest surface beneath where she ended up.
A landing also requires a genuine downward crossing. Without that, a body drifting upward well below a shelf counts as having landed on it. And being already inside something when a frame begins is its own named answer rather than a landing, so nothing downstream has to guess whether a contact meant impact or a body that was already overlapping.
A shape the model cannot describe — a tilted box, which has no flat top — is reported as exactly that, because treating it as air drops her through something solid while treating it as a table lands her on a height that is not its surface. Such a shape is judged on its real world bounds before any flat-top assumption is applied, since a thing tipped over occupies space its upright dimensions never mention. There was already a support query, and it asks a different question: it skips anything without a name, because it is deciding whether a thing is a bed somebody could lie on. A cube nobody named is still solid, and a falling body still has to meet it. The physical question - is there a surface here, how high is it, which way does it face - is now asked separately, and answers with the identity of what it found, because her height is measured against a particular thing and has to be re-measured when that thing changes.
It is swept through the height she passed during the frame rather than sampled where she ended up. Falling past a thin table top in a single long frame, a test that only asks what is beneath her final position finds the floor and drops her through the table. And a shape the model cannot describe - a tilted box, which has no flat top - is reported as exactly that, because treating it as air drops her through something solid while treating it as a table lands her on a height that is not its surface.
Nothing owned her height, which is why she could hover. A hard shove to the chest would launch her and she would stop in the air. The cause was not a constant needing adjustment and not the trunk solver lacking velocity - the trunk has always carried persistent horizontal and turning velocity. It is that her vertical position in AR was composed from a base height captured once when her model loaded, plus a crouch, plus two terms written only by animations, plus one term meaning "off the ground" that nothing in the AR engine ever wrote at all. That term has an integrator and a landing, but they live in the Chat engine; the AR side runs the same body and never received the vertical half of it. She did not hover because a fall went wrong. She hovered because there was no fall.
The missing owner now exists as an explicit sequence - standing, falling, down, getting up, standing - and its most important property is not the arithmetic but the handoff: the fall owns her height only while she is in the air, and balance, stepping and the posture ladder are switched off for the whole of it, so that two systems can never write one number. Every fault this body has had came from two owners of one value.
What counts as fixed is deliberately stricter than "she does not hover", because teleporting her to the floor would satisfy that. She must move continuously, under real gravity - dropped from a metre she lands in about half a second - never invent support beneath herself, never be stuck in any transitional state, and regain standing control only once something is actually holding her up. A dropped frame must not stop her; a very long frame must not throw her through the floor. A foot lifting in a walk is not a fall, stepping off something low is an arrival, and a topple with no drop at all is still a fall.
And her neck stops where a neck stops. The same law that gave her elbows one direction now bounds her neck: a joint held only by the magnitude of its offset cannot say that a neck nods further than it tilts, or that it does not turn like an owl. It is applied at the point physics publishes the bone, after pose and offset are composed, and only where physics moved her - correcting the animation's own poses there would make it a second, invisible owner of the same rotation.
Her knees and spine are defined and tested but deliberately not yet bound, because they are posed by the animation pipeline rather than by physics, and the same measured animation data these ranges came from contains knee poses the law would clamp. Telling a pose somebody asked for from a pose physics pushed her into is the open question; until it has an answer, enforcing everywhere would quietly edit her existing motion rather than protect it.
Her feet can be left behind, and until now only dead code knew it. Shoved hard in the chest she travels backwards while her feet stay on the anchors she was standing on, ending up leaning back with her legs where she used to be. The footing measures precisely that - how far each anchor is from the hip above it - and has two names for it: overstretched, when either foot is more than about forty centimetres out, and stranded, when both are past seventy. Only the second was read by anything, and it triggers a hard re-plant meant for teleports. The first was computed and consumed nowhere, so between those two distances she stood in a stance the system itself defines as impossible and nothing corrected it.
Correcting it is the balance planner's job, since a step is only taken when the planner asks for one, and that is being designed rather than guessed at. What exists now is the measurement: a shove reports how far each foot is from its hip and which of the two limits it crossed, so the next one in a headset explains itself instead of being described from memory. A foot mid-step is excluded, because a swinging foot is on its way to a new anchor and its distance from the old one means nothing.
A limb being held goes soft. Her arms are sprung toward whatever pose the animation holds, which is what brings an arm home after it is let go. That spring was at full strength on exactly the frames a hand was touching her - and the end stop multiplies it further as a joint runs out of range, so the resistance grew the higher the arm was lifted. Past about eighty degrees the spring won and the arm dropped back to her side, through the hand that had been holding it up. That is the inverse of how a body works: a limb being held yields to the hand holding it, and bracing against a touch is what you do to someone you are resisting.
An arm with a hand on it now keeps only a fifth of its spring - enough that an arm brushed in passing drifts home, far too little to fight a hand deliberately moving her. Going completely limp on contact would be a dead arm, and would lose her pose the moment somebody rested a finger on her wrist. After release nothing changed: the arm stays where it was put for a couple of seconds, then drifts back.
The other half of that ceiling was a number. A shoulder could be pushed about eighty degrees off its animated pose, and a joint at its limit has its outward velocity removed, so her arm stopped dead near the horizontal. It was standing in for anatomy, and anatomy now has its own law over the final bone rotation, so the limit could be widened to something a person can actually reach.
Her elbows bend one way. The physics had no idea what a joint IS. A limb's travel was bounded by the MAGNITUDE of its offset — one number, the same in every direction, which is a cone. No joint in the body is a cone. An elbow is a hinge with a hard stop at straight, about 180 degrees of travel one way and none at all the other, and under a cone those two directions cost the same. So when she was pushed back from kneeling and went down onto her elbows, the forearms folded UP toward her head, because that was as cheap as folding down.
Each joint now has its own law, per axis, taken from this project's own confirmed posing reference rather than invented: which axis is the elbow's fold and which sign it folds on (the left and the right are mirror images, and that single fact is what a cone cannot express), that a knee is a hinge on one axis and never twists, that a forearm has no sideways bend, that a neck does not turn like an owl. Anatomically impossible directions are forbidden; everything else is left generous, because the job is to rule out the impossible rather than to second-guess an animator.
Two details decide whether such a law helps or hurts. It is applied to the FINAL rotation, pose and physics together, because an offset alone cannot say whether a joint has ended up somewhere a real one could be — an arm already folded by the animation and then straightened by a push moves toward hyperextension without ever reaching it, and a law that banned the direction outright would stop a folded arm from ever opening. And it runs only where the physics actually moved the bone: correcting an authored pose here would make this a second, invisible owner of the same rotation, which is the pattern behind every fault this system has had.
A touch is a thing that begins, lasts and ends. Nothing in the touch system believed that. There was one "currently touching" slot shared by every avatar in the room, so two of them overwrote each other's answer. The stroke track was keyed only by the bone being touched, so a hand that left her arm and came back a minute later inherited the old track and arrived already classified as stroking, seconds into a caress that had finished. And her expression state outlived the contact that caused it, because nothing ever told it the contact was over.
Those are all the same missing idea. A touch has an IDENTITY — who is touching what — and a LIFETIME. Without the first, a hand and a block pressing the same hip are one touch and the second inherits the first's history. Without the second, a touch never ends and its consequences never clear.
Both now exist. A contact is identified by the pair, so one hand on two parts is two touches and two things on one part are two touches. It begins once, ages only while it is actually happening, and ends — at which point the stroke track and the expression that belonged to it die with it. A lost tracking frame is not an ending: hand tracking drops frames constantly, and treating each one as the end of a touch would restart every stroke and re-startle her several times a second, so a contact may go unseen for about a sixth of a second before it has really gone.
Anticipation is keyed the same way. A brace used to be one timestamp for the whole avatar, so a hand she watched approach her shoulder made an unrelated hand landing unseen on her ankle count as expected, robbing it of the startle it had earned. She now remembers what she braced for, part by part.
She can tell what is touching her. Everything that can press into her arrives in one list — the user's hands, every joint of them, the rest of the user's body, and every solid object in the room — and only HER part survived the contact test. The name of the thing doing the touching was known at the moment of contact and simply dropped. So a block leaning against her hip and a hand laid on it produced the same sentence, and she was told a person had touched her in both cases.
Contact now carries what made it. A hand reads as a hand, which is what "touched" implies and the overwhelmingly common case. Another part of them reads as what it is — leaning a chest against her, resting a knee on her, putting their face to her, since the headset IS their face. And an object is described with no person in the sentence at all: a block resting against her is not somebody touching her, and saying that it was is how she ends up thanking someone for a cube.
She can only remember eight things about her own body at once. The physical events the headset sends her are held in a queue of eight per agent, and the newest evicts the oldest. That bound was harmless while a touch was announced once, and stopped being harmless the moment a touch could be re-announced whenever the hand changed what it was doing: resting, stroking and rubbing are decided by thresholds, a hand sitting exactly on one flips its answer every time the speed is recomputed — eight times a second — and one second of that evicts everything else she has been told. The posture she was pushed into, the hand holding her, all of it, replaced by "touched / is stroking / touched".
Two mechanisms now stop that, at the two places it can happen. The classifier refuses to change its mind quickly: entering a state is harder than staying in it (a hand must reach 0.030 m/s across the skin to count as moving, but only drop below 0.018 to stop counting, and the stroke/rub cut has a band around it rather than an edge), and no answer may change more often than about three times a second however the numbers wobble. Then her mind rations what survives that: the FIRST change on a part is always news and goes straight through, and after that a hand that keeps changing its mind is allowed one sentence a second or so. Escalation is never rationed — a touch that becomes violent reaches her immediately, because being hurt is not the same kind of event as a hand fidgeting.
A hand that moves on her is not a hand that is on her. Every measurement of touch here runs along the surface NORMAL — how deep a press is, how fast it is arriving, how much flesh is under it. That is the right axis for a press and the wrong one for the other thing hands do, which is travel: a hand drawn down her forearm keeps a constant depth and puts all of its motion across the skin rather than into it, so on the normal axis it measures as a hand holding still. She was told "gently touched your left forearm" once, and then heard nothing for twenty seconds while somebody was stroking her.
Resting, stroking and rubbing are now told apart from the tangential motion that projection discarded, and she is told which — "puppy is gently stroking your left forearm". The two moving cases are separated by how STRAIGHT the travel is: distance actually got from where the contact began, over distance travelled. A hand drawn once down her arm ends up nearly as far as it went, so the ratio is near one; a hand worked back and forth over one spot travels a long way and ends where it started, so it collapses toward zero. No notion of direction, rhythm or counted reversals is needed.
Two things make the measurement honest rather than merely plausible. It is taken in the frame of the BONE being touched, not the world — she turns, she is pushed, she walks, and in world space a hand resting on a shoulder she is turning sweeps an arc that reads as a caress while a hand truly stroking her as she moves with it reads as still. And travel is measured as displacement across a short window rather than as a sum of per-frame steps: hand tracking jitters a few millimetres a frame, and summing those steps gave a hand that never moved 0.108 m of phantom travel in three seconds and a false speed of 0.036 m/s against a 0.030 m/s threshold. Jitter is zero-mean and cancels over a window; real motion does not and accumulates. The same measured noise now contributes 0.007 m/s against an unchanged 0.120 m/s stroke — seventeen to one, where it had been three to one.
And she does not have eyes in the back of her head. Anticipation first went in without any notion of where she is looking, so a hand creeping up behind her closed the same gap at the same speed as one in front of her: she flinched at it, and then met it calmly as though she had been watching it the whole time. That is worse than not bracing at all.
She now anticipates only what falls in her field of view — clear within sixty degrees either side of forward, fading through the periphery, and gone by a hundred and ten. The fade is deliberate: peripheral vision detects motion rather than stopping at a line, so a hand at the edge is noticed late and braced for less. The field is measured around her body facing, because the rig drives her scene rotation from exactly that number and absorbs the difference between VRM versions before it, which makes it the one direction that means the same thing for every model. It is generous — a hundred and ten degrees rather than a nose-cone — because her head turns freely within her body's frame, and insisting she cannot see something she is looking straight at is the worse error.
This also supplies the case the touch system had no way to express: being touched from behind is not the same event as being touched from in front. The contact is identical; the experience is not. A touch she could not have seen lands harder — up to about half again — and, more importantly, does not have to be FAST to make her jump. A hand settling onto the shoulder of somebody who is watching it is unremarkable at any speed; the same hand arriving unseen is not, and a fixed speed threshold said otherwise. "She did not brace" and "she could not possibly have braced" are now different things.
She sees a hand coming. Every response in the touch system began at CONTACT — her face, her gaze, the sentence she is handed, the give in her body. So a hand travelling fast at her produced nothing at all until it landed, and then produced a startle. A person watching that hand has flinched well before it arrives.
She now watches the gap between an incoming hand and her own skin, and braces when something is both close and genuinely closing: faster than about a quarter of a metre a second, nearer than half a metre, and within about four tenths of a second of arriving. It is the GAP that has to be shrinking, not the hand that has to be fast — a hand sweeping past her at a metre a second is not arriving, and treating speed as threat would have her flinching at gestures.
That gap has TWO ends, and both of them move. The first version of this measured the previous gap against her CURRENT pose, which quietly made every quantity a fact about the hand alone: a hand resting on her forearm while she lifted that forearm read as an approach at 0.72 m/s, and she flinched at her own movement. Her previous pose is now part of the measurement, so walking, turning, being pushed, or lifting the very limb being approached are all already accounted for — and the converse holds too, that her own body moving onto a stationary hand is a real approach and is braced for.
And nearest is not most imminent. Every hand-and-limb pair near enough to matter is scored before one is chosen, because choosing the closest first and asking afterwards whether it was worth bracing for let a hand already resting on her — by a wide margin the nearest thing to her, and not arriving at all — hide a hand coming in at a metre and a half a second.
The converse is what makes this a correction rather than an addition. A contact she WATCHED arrive is not a surprise, even when it arrives fast — so a touch she braced for lands with its startle cut to about a third, and a gentle one she saw coming does not startle her at all. The startle rule described below was wrong in a way that could not be seen until anticipation existed, because it went on startling her with touches she was looking straight at.
One honest limit: because nothing beyond half a metre counts as imminent, something very fast is only braced for once it is inside that range — for a hand at three metres a second, about two hundred milliseconds of warning. That happens to be roughly human, but it is a property of the horizon rather than a tuned reaction time.
And a force belongs to the place it landed on. Every press being made on her was collapsed into one number - the hardest anywhere on her body - and handed to whichever contact happened to be deepest that frame. So a firm hand on her shoulder and a fingertip on her wrist produced a single reading: the shoulder's force, described as happening to her wrist. Because force is then scaled by where it lands, that migrated number was also multiplied by the wrist's own sensitivity, a factor that never applied to it, and she was told she had been handled roughly somewhere almost nothing had happened.
Each part now keeps what it actually felt, while how hard she was handled overall is kept separately, because those are different questions - a push that puts her on her knees is one event rather than one per contact. A part touched several times in a frame keeps the hardest of them rather than their sum, since several fingers on one forearm are one hand. And a part nobody touched felt nothing at all, which is the point: the silent substitution of somebody else's force was the whole defect.
Not all of her is equally sensitive. Force reached her as newtons and was banded gently, roughly or violently on that number alone, so an identical fingertip on her neck and on her thigh produced the same word and the same face. Skin does not work that way: the face, the throat and the hands are densely innervated and register contact that the back and the thighs would barely notice, and a touch that is merely present on a forearm is significant on a throat.
Each part now carries a sensitivity, as a multiplier around the forearm — ordinary skin, and the reference. The face is about twice it, the throat close behind, the hands and the soles of the feet above it, the front of the torso more than the back of it, and the back and thighs below it. Fingers and toes inherit the hand or foot they belong to, so a finger laid against her finger is felt as a hand rather than as ordinary skin. The ordering follows what innervation density and monofilament thresholds agree on; the exact figures are a modelling choice and are not presented as measurements.
It changes what she FEELS and nothing else. The solver goes on working in the newtons it measured, so a press moves her exactly as far as it did before — making her throat feel more must not make her throat weaker. Only how hard a touch is scaled; how fast the hand arrived is a fact about the hand and is identical wherever it lands. Nowhere is immune, either: sensitivity moves where the bands fall, so a press hard enough to be violent is violent on her back as much as on her neck.
And an expression that has finished is not still on her face. Her face refuses to replay the same expression while it is already showing it, because restarting a flash every frame pins it at its attack and stutters instead of expressing. But what counted as showing was remembered for as long as the situation lasted, while the flash itself is brief. So being handled roughly for several seconds produced discomfort once, for under a second, and then nothing at all - her face went blank while it was still happening to her. A reaction whose time has run out is now allowed to play again, which reads as the feeling continuing; a reaction still within its time is not, which is what keeps her from buzzing.
Startle is a response to suddenness, not to contact. Her face had one rule about being touched: whenever the deepest contact landed on a new body part, flash surprise, with a strength taken from how deep the press was. Nothing else about the touch reached her face. So a hand laid gently on her shoulder startled her, a hand drawn slowly down her arm startled her again on every bone it crossed, and being stroked and being poked produced the same expression — differing only in how hard, which is the one axis on which a caress and a jab can be identical.
Her body already knew better: slaps startle, held contact shoves. That rule is now carried across to her face. Surprise requires a fast ARRIVAL — about 0.6 m/s, well above the few centimetres a second of reaching out and putting a hand on someone, and well below a jab or a grab — and it is tested only on the frame a contact lands, so a hand already on her cannot startle her by continuing. Rough handling that is not sudden is not surprise but discomfort, and reads as such. Being stroked gently eases her, after about eight tenths of a second rather than instantly, deepening while it goes on. A hand simply resting on her asks nothing of her face at all — she turns to look, and she is told about it, but "nothing in particular" is a real answer and the old code had no way to give it.
Her head tilts when you push it, and stops where a neck stops. The head used to give a little through the generic yield, which turns a push into a target displacement and rotates the neck toward it: a kinematic answer to a physical question, with no momentum in it and one number bounding every direction equally. It is now the arms' model applied to the joint that carries her head — a torque about the neck from whatever is pushing, a motor holding the animated pose, and a latch that leaves the head where it was put for a moment rather than springing it back.
What is not an arm is the LIMIT. A shoulder is very nearly a ball and one number describes it; a neck drops the chin most of the way to the chest, barely goes back at all, and tilts an ear toward a shoulder about half as far as it nods. Each of the three is limited on its own, so a head nodded to its stop is still free to tilt — which is what makes a hand pushing from any side read as tilting her head rather than nudging something already stuck. The limits are held in HER frame rather than the world's, so "forward" means forward for her whichever way she is facing.
And weight on top of her head goes down her spine exactly as weight on her shoulders does, so pressing down on her head puts her on her knees. That is most of what a head is for, as a handle.
But only where her head is something to bear weight ON. A forehead SLOPES, so its outward normal points up and forward, and pushing into it reads as pressing downward almost as hard as standing on her — measured on the model, 0.65 against the crown's 0.76. A tap on the brow put her on her knees. The slope of a patch of somebody is not the gesture being made against it, which is the same thing that made pressing down on a kneeling body put her on her hands, and the answer is the same: decide by WHERE the hand is. Measured up the skull from its centre, the crown sits at 0.80 of its radius, the brow at 0.51, and her face, chin, back and sides at nothing — so weight is borne in a ramp between those, full at the top of her head and next to nothing at the brow, with no edge to fall off.
Her own arm is not allowed inside her own body. Nothing that moves an arm knew her torso was there. The solver answers hands; the grab answers a target. Neither had been told that the thing it swings has to share space with the person it is attached to, so an arm pushed inward went through her, and a wrist taken across her dragged the whole arm through her ribs on the way.
The limit that actually holds an arm out of her is on the JOINT, not on the geometry, and the third attempt is the one that works. At rest the axis of her upper arm sits a centimetre and a half outside her chest's measured skin while the arm is six and a half thick — arm meshes and torso meshes overlap where they join, on nearly every model — so any geometric slack loose enough not to fire while she stands there is also loose enough to let half the arm inside her before it fires at all. There is no threshold in that measurement that separates the two cases, and picking one is what shipped twice.
What does separate them is her ANIMATED POSE. Wherever the animation holds her arm is where her arm rests against her body, whatever the model, standing or walking. From there an arm may swing outward, forward and back freely; what it may not do is keep going INWARD past a few degrees, because inward is where she is. Only the inward part is touched, so folding her arms in front of her still works — that motion is mostly forward. Under a sustained shove her wrist now travels four centimetres and stops against her side, instead of passing through her.
The geometric check remains as a second line, for a forearm folded into her from the front where the joint limit has nothing to say. What it compares is the arm's CENTRELINE against her measured skin. Not the capsule around her — a capsule's radius is the widest that bone's flesh gets anywhere, so by that measure an arm at her side is inside her chest. And not the arm's own surface either: on the model in the repo the axis of her upper arm rests under two centimetres outside her chest while the arm is six and a half thick, because arm meshes and torso meshes genuinely overlap where they join, as they do on nearly every model. Judged by its surface she is four centimetres inside herself standing still. What "an arm inside her body" looks like is its centreline crossing her surface.
Where there is NO measured skin — the first moments of every session, before the measurement is fetched or built — there is no self-collision at all, rather than a capsule standing in for it. The capsule is wrong in exactly one direction here, and answered by a skeleton's worth of impulse it reads as both arms stuck out at forty-five degrees, bouncing against the motor trying to bring them home.
What it costs is part of the design, because the first version of it cost frames. It runs inside the per-frame pose override, which happens AFTER the frame counter has advanced — so anything there that asks for the full set of body capsules can never hit their cache, and rebuilds all fifty, each one scanning three hundred and eighty-four floats for its widest radius, only for the touch pass to rebuild them again a moment later. Touching her went from one build a frame to two, with the extra one in the hot path. It now builds the four capsules the question actually needs, and asks the measured surface once per sample point rather than once per sample per part.
It arrives at the solver as one more contact rather than as a correction applied afterwards, so the arm's own state ends up consistent with where the arm actually is; a correction on top would leave the solver still pressing inward and let go of the whole accumulated push the moment it stopped. What it is allowed to push back with is not muscle tone, though: tone is how hard she resists being moved, and a ribcage is not resisting, it is simply there. Given a muscle's allowance it lost the argument to a hand pressing inward at a third of a metre a second.
A grab is kinematic — it writes rotations straight onto the bones — so it is answered twice over. Its target is moved to the nearest point outside her before the IK ever aims at it, which fixes it at the source, and afterwards the SHAFT is lifted out if it still cuts the corner: both ends of an arm can be clear of her while the middle of it is not.
She turns to follow a pull, rather than being dragged. Taking her by the wrist and pulling across her used to do nothing at all until the hand was three quarters of a metre from her hips, at which point she turned and stepped all at once — and by then the wrist she was being held by had been left a foot behind. There is no threshold now. The moment a held hand is outside the arc that arm can comfortably reach, she turns to follow it, at a rate that grows with how far outside it is and stops the instant it is back inside. Turning is what a person does before stepping, it costs nothing, and it is what keeps the arm in front of her instead of across her. Walking still follows a sustained pull, but starts while the wrist can still keep up.
When she is put somewhere, her feet go with her. Her feet are anchored in the room — an anchored foot stays where it is while the rest of her moves over it, which is what stopped her skating. But she is created at the origin, her feet are planted there, and only afterwards is she placed a conversational distance in front of you. Nothing moved the anchors, so every session began with her standing in front of you and both legs stretched back toward the spot she was born on: straight, because a leg reaching for something too far away has no bend left in it.
The FIRST frame counts too, and skipping it is why this survived being fixed once. Whether a frame happens to run between her feet being planted and the app placing her is a matter of when a promise resolves; when none does, there is no jump to notice — the first frame ever seen already has her standing where she was put with her feet anchored somewhere else.
Noticed as a JUMP rather than announced by whoever moved her, because otherwise every mover has to remember. A step takes a quarter of a second and covers thirty centimetres, so walking moves her a couple of centimetres a frame and even an uncatchable shove is under three; a third of a metre between two frames is something having PUT her there. Her feet re-plant under her and everything carrying momentum is dropped, because that momentum belonged to the place she left. The threshold is deliberately an order of magnitude above anything a disturbance produces: re-planting her feet under her during a stumble is a conveyor belt, and that has shipped here before.
Under all of it there is a net: both feet more than seventy centimetres from the hips above them is a stance nothing physical produces — a stumble moves one foot at a time, and a body on the floor has its legs stood down entirely — so however she came to be there, she stands where she is. A foot mid-swing reports nothing to it, which is what keeps the net from becoming that same conveyor.
Every limb is as thick as it was measured to be, under its own name. The skin is measured off the real mesh, and it was being read back under the wrong key: a segment took the thickness of the joint it STARTED at rather than of the part it is. Most segments start at their own bone, so it never showed — but both shoulders run from the chest, and the spine runs from the hips, and those are the two fattest numbers in a body. Each shoulder became a chest-thick tube reaching out past the arm, which is two inches of empty air immediately outboard of and above each shoulder, while the sternum a few centimetres away was exact.
And her head sits on top of her neck rather than around it. The head is a rounded part, and it was centred on the head JOINT — which is at the top of the neck, not in the middle of the skull. A ball of nearly eight centimetres hanging there buries three inches of itself in her shoulders, so a hand reaching down to press one met her head first, in what looked like empty air. A measured offset moves it onto the skull where it belongs, but nothing may depend on that measurement having happened; without one it is now lifted by its own radius along the neck, which puts the bottom of her head exactly where a head starts.
A bump is not a push, and a living arm can tell the difference. Brush past her arm and it gives a little and comes back; put a hand on it and push and it goes where you put it. Both are the same contact, and what actually separates them is how LONG the hand is there — a knock is about forty milliseconds, a deliberate push is seconds — so what had to be bounded is how much momentum a single frame of contact may hand over.
It was effectively unbounded. A hand brushing past in 181 ms drove her wrist thirty inches and pinned her shoulder against its eighty-degree limit, then left it there: the contact handed the limb whatever velocity the hand had, and the limb coasted. Stiffness is not the answer, and the bench says so rather than the reasoning — ten times the torsion changed the travel by two per cent. While a hand is in contact the non-penetration constraint decides where the arm goes and the spring never gets a say in it. What a spring governs is the return afterwards.
Capped, the same brush moves her wrist five inches and it settles back within one, while a hand that stays and pushes still carries her arm nine inches and leaves it there.
Her waist absorbs a turn before her feet do. Turning is not a leg action until it has to be: asked to face a little to one side, a person simply turns, and their feet stay where they are. Her nominal foot places used to be built from her body's yaw directly, so every degree of turn asked her feet to follow — which is wrong twice over. It makes a small turn into stepping, and a large one asks for something impossible: spin her half a turn and each foot is instantly told to stand where the other one is. Swept clearance then refuses, correctly and permanently, and she stands cross-legged. The refusal was never the bug; the request was, and no better clearance test could have fixed it.
Her stance now has a facing of its own, read off her feet — the line from her right foot to her left is her stance, whatever put them there — and her nominal places are built from that rather than from her body. Under about fifteen degrees of wind-up nothing moves. Past it, the places rotate toward her body by at most one round of stepping, because a pair of steps turns a stance about a quarter turn and not a half. So a spin becomes several small turns rather than one impossible one, and the size of the answer follows the size of the turn.
The wind-up also has to be visible to the thing that decides whether a step is worth taking, because the distance a foot sits from where it belongs cannot express it: the nominal places are only ever one step's worth of rotation ahead, so after taking that step each foot is close to home again while she is still facing a hundred degrees away from her feet. Judged on distance alone she looks tidy and stops, wound up. Past what the waist will hold, standing still is not one of her options.
A crossed stance is not an untidy one. Her feet keep their places in the room while her nominal places turn with her, so past about a half turn she is left standing with each foot on the other's side. The straight line from a foot to where it belongs then runs directly through the leg she is standing on, swept clearance refuses — correctly — and with nothing else on offer it refused again on every frame for as long as she stood there. Measured: her left foot at nine centimetres to the right, asked to reach twenty to the left, passing within a millimetre of the foot holding her up.
Two things were wrong. A shorter step does not help, because the minimum-width rule puts every candidate in the same place beside the standing foot — the obstacle is not distance, it is the leg on the line. And stepping AROUND it lands further from where the foot belongs, so the ordinary score, which measures exactly that, read the only available move as one not worth making. She now looks fore and aft of a blocked place until the swing has a clear line, and a foot standing on the wrong side is scored as invalid rather than untidy — getting to the correct side is the win, and it outranks any tidying.
Falling is not built. When no recovery step can be found the planner says so — "no recovery found by this controller", a statement about the planner rather than a claim about what bodies can do — and her feet then STAY WHERE THEY ARE while the rest of her goes over them, which until a real topple exists is a far better model of falling than tidying her feet underneath her. Re-planting on a fall was tried and was much worse than nothing: her support travelled with her, the pressure under her soles could never get behind her weight, and a firm shove accelerated indefinitely while both legs stepped and went nowhere. She was on a conveyor belt of her own making.
An anchor no leg can reach is a different thing and is still resolved by standing where she actually is. Reporting an impossible stance and acting on nothing was the whole of the frozen-leg bug, and "we noticed" is not a fix for it.
A shoulder press TWISTS her; it does not shove her. A hand on the front of one shoulder drives that shoulder back and brings the other one forward, which is the upper body rotating about the spine. It used to slide the whole person backwards, because shoulders were classed as trunk and went to the stance model, and the stance model only knows how to translate her and to turn her about the vertical through her feet — so it answered a twist with a shove.
The trunk's twist and the ground under her are solved TOGETHER: four coordinates — the spine's axial rotation, two of ground translation, and turn — with one impulse per contact acting through all of them. Every case then falls out of one arithmetic rather than a rule. Twisting is cheap, because the trunk's inertia about its own axis is under half a kilogram-metre-squared; translating is expensive, because that is fifty-four kilograms of person. So a single shoulder press is answered by a twist. Two hands pressing both shoulders backwards ask the spine to turn both ways at once and cannot be answered by twisting at all, so the only way to stop them closing is for her to give ground — and she does, from the first frame, not at some limit the trunk never reaches. Her feet resist before they move, which is static friction and is why leaning on someone does not slide them.
A staged version was built first and is worth recording because it failed in an instructive way. Solve the twist, then hand the leftover to the feet: two opposing contacts on a single degree of freedom cannot both be satisfied, so neither ever stops demanding, their impulses grow until they clamp, and which one wins is decided by the order they happen to be solved in. She twisted hard when she should not have twisted at all. Under-relaxation did not fix it, because the demand never goes away — what was missing was feasibility, not damping. Giving the solver her feet as a coordinate is what makes the problem solvable, and the sweep now alternates direction each pass so that the contact solved last does not get the final say.
Inertia comes from a LEDGER in which each physical segment appears exactly once. The per-bone mass lookup is full of aliases — chest and upperChest return the same thoracic mass, and Shoulder returns an upper-arm-sized figure — which is correct for asking what a bone weighs and completely wrong for summing a body, because a rig bone is not an anatomical mass boundary. Adding up every bone above the spine double-counts the thorax and invents a pair of shoulders. The torso is modelled as an elliptical cylinder and the head as a sphere, stated because an inertia is meaningless without the shape that produced it, and the arms are counted with the trunk because they turn with it — the arm solver's job is their motion RELATIVE to the chest.
The arm watches what actually reaches the mesh, and says so. Three rounds went into reasoning about an artefact nobody could measure — an arm apparently in its original position and where it is being pushed at the same time, the moving copy looking like it runs at half the frame rate. That is a limb alternating between the animated pose and the solved one, and it is perfectly measurable from inside the headset on the bone the skinned mesh actually follows.
The detector is the SHAPE of the artefact rather than a threshold on it: a flipping limb returns to where it was two frames ago while being far from where it was one frame ago, which is the opposite of what continuous motion does at any speed. So it needs no calibration and does not care how fast the arm is moving. It watches the RAW bone after the rig has published, because the normalised bone that gets written and the solver's own state are exactly the two things that have already been reasoned about wrongly.
What it records with it is the list of CALLER decisions — frame number, whether a contact was queued, whether the arm pass ran at all, how long since anything touched it, whether the avatar was held still. That is deliberate: the last three faults were all in how the solver was called rather than in what it computed, and none of those decisions were visible from inside a headset. The trace is bounded and rate limited, because a per-frame report shipped to a server would itself perturb the timing being measured.
The arm pass runs on every frame, touched or not, and publishes an ABSOLUTE pose. Two faults in how the solver was CALLED, rather than in what it computed, and between them they account for the reported "the arm is in two places at once, and pushing it again teleports it back to where I left it a minute ago".
The override hook only ran when there were pending contacts, and contacts are deleted the moment nothing is touching. So on every frame with no contact the arms were not integrated, not published, and their clocks were not advanced: the animation restored the base pose, the override skipped the arms entirely, and the solver's state froze mid-push. A hold cannot expire while its clock is not running, and a limb cannot settle while nothing integrates it. Touch her again and an offset from whenever the last contact ended is applied afresh. There is also a feedback route to a two-position alternation in that: a solved pose loses contact, the next frame shows the animation, the animation overlaps the hand again, and the frame after that re-applies the old offset — no second writer to the bones required.
And publication composed the offset onto whatever the bone currently held, which is only correct while something restores the base pose first. In stasis nothing does, because the rig's whole update is skipped, so each frame wound the arm further from a solver state that was not changing at all: a steady 0.2 radian offset published 0.2, then 0.4, then 0.6. Publication now recovers the base — if the bone still holds what was last published, the animation did not run and the stored base is the one to use — so publishing the same state twice produces the same pose twice, which is the property a frozen simulation needs.
Two related ordering faults went with them. Arm contacts were routed AFTER an eighteen-millimetre press threshold, so a boundary contact never reached a solver whose own tolerance is one millimetre; and only the single strongest press in the frame was forwarded, so touching both arms at once exercised one of them and the multi-contact solve had nothing to solve. Arms are now routed first, all of them, and are excluded from the older joint path so that only one thing writes those bones.
Contact is a CONSTRAINT on velocity, not a spring on depth. A penalty force — newtons proportional to how far in a hand has got — has the right equilibrium and could not reach it. The arithmetic settles correctly: contact-direction joint stiffness of 25 N/m against flesh at 2000 N/m leaves the arm 1.975 cm displaced for a 2 cm hand movement, which is the arm following the hand almost exactly. What the implementation actually did was flee. A replay of a hand pressing 2 cm into a forearm produced ONE frame of contact at a fifth of a millimetre, three centimetres of arm travel, and then no contact at all while the hand kept advancing — the joint's peak velocity arriving after contact was already lost. The transient carried energy the equilibrium never asked for, and in a headset that is an arm that leaps to its limit and then jitters as the hand chases it.
Each step now asks one question instead: given where the joints are about to go, is this contact CLOSING? If so, apply exactly the impulse that stops it closing, and no more. The inverse effective mass along the normal is J M-inverse J-transpose, the relative normal velocity is J qdot minus the hand's, and the impulse is their quotient — accumulated, and clamped to be non-negative, because a contact may push and may never pull. Three things follow that no penalty stiffness gives: it is exact rather than proportional, so the surface moves WITH the hand instead of being thrown past it; it is unilateral, so a limb moving away faster than the hand simply separates and a push cannot become an accidental grip; and it cannot store energy to release after contact ends.
The order within a step is part of the design rather than an accident. Everything that is not a contact first — the pose motor, damping, the end stop — giving the velocity the joint is ABOUT to have; then contacts solved against that predicted velocity, in a few sequential passes so several contacts on one arm agree rather than each pretending it is alone; then one integration. Applying a motor after the contact solve would undo what the contact just decided, every frame, which is how a constraint and a spring end up fighting instead of composing.
A constraint produces exactly the velocity it is given, faithfully, which makes it precisely as trustworthy as that number. So a hand is never believed to be closing faster than two metres a second, and a BRAND NEW contact is not believed to be closing at all — on the frame a hand is reacquired its apparent speed is the distance it was lost over divided by one frame, which is tens of metres a second. A new contact contributes only the gentle penetration recovery, and has to persist before its speed is worth anything.
An arm is a thing with mass, and it has momentum. Arms are no longer solved by asking for a position and easing toward it. Each shoulder and elbow carries an angular VELOCITY between frames and is integrated as ordinary rigid-body dynamics: angular acceleration is torque over inertia, where the torque is what the touch applies plus a motor pulling the joint back toward the pose the animation wants. That one piece of state — a velocity that survives the frame — is what buys overshoot, follow through, and a release that carries. None of it can be expressed by easing toward a target, which is why an arm read as being dragged through treacle no matter how the numbers were tuned.
Three things follow from doing it as dynamics rather than as displacement:
- Torque, not displacement. A contact applies r cross F about each joint, so where you touch decides the leverage automatically: a press at the wrist turns the shoulder hard, a press beside the shoulder barely turns it, and a force pointing straight at a joint does not turn it at all however hard it pushes. Stiffness is now torsional, in newton-metres per radian, because stiffness measured at the contact point does not survive the contact moving — 220 N/m twelve centimetres out is 3.2 N m/rad and the same number at forty centimetres is 35.2, so sliding a hand along an arm changed how stiff its shoulder was by a factor of eleven.
- Real inertia. A third of a segment's mass is the effective mass at the tip of a uniform rod for one particular motion, not a property of an arm about a joint. What resists a torque is the moment of inertia, built from the rig's own measured segment lengths — the hand is an eighth of the arm's mass and over a quarter of its inertia purely by being far away. With that inertia and relaxed muscle tone the shoulder's natural frequency lands near 0.56 Hz, and a real relaxed arm swings at about 0.6. The number is not tuned to feel right; it falls out.
- Damping instead of averaging. A damper resists VELOCITY, so it suppresses jitter without delaying the response to a real push, where a moving average delays everything equally. The ten-sample average that used to sit in this path was 62.5 ms of group delay before anything else in the chain, and it was the first of three smoothers in series. One pole at 40 ms is the only filter left.
The elbow bends. A contact loads both joints, and how the load splits is not a rule anywhere — it is r cross F measured from each joint. A press on the wrist turns the shoulder and bends the elbow; a press on the upper arm cannot bend the elbow at all, because it is on the wrong side of it. The elbow is a hinge, so it answers only the component of a torque along its own axis and refuses to be twisted sideways, which an elbow cannot do.
Area does not decide whether a limb can move. It used to: a fingertip coupled so little that it could not shift an arm at all. That was wrong — a fingertip can move a relaxed arm. What area actually changes is how stiff the flesh under the contact is. A point sinks into soft tissue easily; a palm compresses a wide column of it in parallel and meets a much stiffer spring, so at the same depth a palm generates far more force. The nuance survives and the gate does not.
An arm hinges at the shoulder, and moves nothing else. Everything below the shoulder — a hand, a forearm, an upper arm, a finger — is answered by rotating the upper-arm bone, whose origin IS the shoulder joint. It is a ball joint, so the arm goes wherever it is pushed: forward, back, out from the body, in toward it. The chain used to start at the elbow or the wrist and reach the chest at its third link, which meant a firm push on a forearm rotated a CHEST — and rotating a chest carries the torso, the head and the other arm with it, so shoving an arm turned the whole avatar. An arm is not how you move a person.
What makes rotating the touched bone itself legitimate is that the solver aims at the CONTACT rather than at a joint. A press halfway down an upper arm has a hand's length of lever on the shoulder; the bone below it has none, and the bone above it is the chest. Driving the point that is actually being touched is what lets a bone be swung about its own origin by something resting on its shaft.
An arm is also bounded by its own SHOULDER rather than by the limits that suit flesh. Eight centimetres of travel and ten degrees of rotation are right for a head tilting away or a thigh giving under a palm, and quite wrong for a limb on a ball joint: applied at the shoulder they held the whole arm to a hand's width of movement however hard it was pushed. An arm swings to its joint's own play, up to about fifty degrees, and what stops it going somewhere silly is the collision test rather than a small number.
An arm cannot pass through her. Swung inward it reaches the hip and stops, because there is a hip there — and the load does not vanish at that point, it goes INTO the hip, which is what happens if you lean someone's arm against their own body. The test is on the candidate, before anything is committed: the arm's own capsules are rotated by the step the solver just asked for and measured against the trunk, inflated by an arm's thickness. That is arithmetic on a handful of points, so it is affordable on every frame a hand is pressing. Arms do not collide with each other — they pass, and treating one as a wall would jam them.
What is forbidden is going DEEPER, not overlapping. An arm at rest already overlaps by this measure and always will: the top of an upper arm is the shoulder, which sits well inside the chest's own capsule, and a relaxed arm hangs against the ribs. Asked as "is the arm inside her" the answer was yes on every frame, every swing was refused, and the arm could not be moved in any direction at all — including straight out from her, where nothing was ever in the way. Sliding along her, or coming back out, is allowed however deep the overlap already is, which also means an arm that somehow ends up inside her can always get out again.
Pull an arm until it is straight and the person follows. While the shoulder can still swing, an arm answers a push on its own and she does not move; that is what having play means, and it is why a firm shove to a wrist swings the arm rather than shifting her. Once the joint is at its limit there is nowhere for the load to go except through her, so what the shoulder passes on lands on her feet — where the stance threshold decides whether it is actually enough to shift her. It is the joint being maxed that matters, not how hard the push was: a gentle pull on an already-straight arm reaches her, and a hard shove on a slack one does not.
Joints are shock absorbers. A push travels out from the contact along a chain, and each joint takes what it can before passing only a FRACTION of the rest to the next — a wrist is small and passes most of a push to the elbow, a shoulder is buried in muscle and passes very little into the spine, and a hip passes nothing at all. That is why a firm push on a hand is felt faintly at the shoulder and not in the hips, and it is what makes a body read as jointed rather than as one piece hinged in the middle.
How FAR a push travels is separate from how it decays, and is set per touched part. It is currently ONE joint for everything: touch a finger and the finger moves, and nothing else. Growing that is a deliberate, one-part-at-a-time change — the force reaching each further joint is already reduced by the joints before it, so opening up a part needs no other tuning.
Only LIMBS bend — arms, hands, fingers, legs, feet, the neck and the head. Everything on the trunk goes to her feet instead, as above. A joint also needs LEVERAGE: when the bone being moved sits almost on top of the joint, a centimetre of travel costs an enormous rotation, which is the other half of why the body lurched.
A yield is an OFFSET on the animation, not a pose of its own. The pose underneath it is rewritten every single frame — idle motion, gaze, breathing and weight shift are composed from scratch and the touch override runs after them — so anything the yield writes to a bone is gone by the next frame. What persists is how far the joint has been pushed OFF whatever pose the animation just gave it, and that offset is re-applied on top of the new pose each frame. She keeps breathing and shifting her weight while an arm stays where it was pushed.
The way the alternative failed is worth recording, because it hid behind every other limit in the system. Storing an absolute orientation and easing the bone toward it meant the speed limit — a limb travels at a limb's pace — was measured from the bone to its goal. Since the bone was rewound to the animated pose every frame, that distance never accumulated: a limb could never end up more than ONE frame's travel from the animation, about half a degree, which at arm's length is an inch. An arm could be shoved as hard as you liked and would move an inch. The joint's play, the travel cap and the angle cap were all raised looking for the cause before the real limiter was found. Held as an offset, the limit means what it was always meant to: how fast the limb GIVES.
A pushed limb stays where it was put. For about two seconds, and then it drifts home slowly. A limb that starts back the instant the hand lifts reads as sprung rather than as a body, and at the flickering edge of a contact it reads as a vibration — the return is much slower than the push for the same reason.
Give is a position, not a nudge. A displacement asked for relative to wherever a limb had already moved added another full step on every frame, so the limb ran away until contact was lost, pressure vanished entirely, and it snapped home — then contact returned and it began again, buzzing back and forth. Read as an absolute position it is a spring: as the limb gives, the penetration left to it falls, so what it asks for falls too, and it settles where the two balance at x = kp/(1+k). The residual pressure there is never zero, so the finger never loses contact and there is nothing to snap back from.
Give, one joint at a time. A touch deep enough to be a press moves the joint directly above what was touched, and only that joint — a small step per frame, hard-limited to about eleven degrees from where the pose started, easing back as soon as the hand leaves. All three limits are needed together: a per-frame clamp alone bounds nothing, because it runs on every frame a hand rests against the body, and a joint that never returns keeps whatever it was given.
A joint only ever moves what hangs BELOW it. Asking one to move its own ancestor is a target that cannot be reached, so the solver demands more and more rotation — which is how a hand on a hip curled a whole torso back on itself. Distributing a push further up a chain is the intended next step, not the current behaviour.
Every switch is remembered between sessions, stored apart from the room itself — the room is what you
built and reset clears it, while a preference is not room contents and survives that.
In AR the touch systems can each be switched off on their own, and the in-headset help lists them as
live status rows — the switch name with ON in green or OFF in red beside it, refreshed the moment
anything changes. A list of toggles that does not say which are on is a list of things to guess at, and
half of them exist to be flipped while hunting a problem. performance reads back the frame rate, the
worst frame of the last second, per-stage cost, and how many contact tests, surface probes and draw
calls ran per frame — counts, not just milliseconds, because a stage taking four milliseconds says
nothing about whether it did four operations or four thousand. A second that drops below 60fps reports
itself without being asked. cube touch is the control: the identical feedback path on a plain box,
with none of the avatar machinery behind it.
Only BLOCKS collide in the physics world. Hands, the assistant's limbs and the user's body are all kinematic — they follow tracking and a pose, so a solved contact between any two of them moves nothing while still generating manifolds for every pair, which is thousands of narrow-phase tests a frame the moment a fingertip comes near her. Contact between bodies is detected by the geometry above and resolved against the measured surface; physics is there to make blocks behave.
Grabbing and manipulation: close your fist (deliberately — a still hand; sweeping arm motions don't grab) on any limb: hands, forearms, shoulders, head, chest, feet, shins, hips. IK chains follow your hand; pulling beyond arm reach makes the assistant walk with you (cooperative following). Two hands on the hips lift and carry them; dropping them mid-air invokes gravity (they land on their feet or crumple and get up). Limbs articulate in every pose — grab an arm while the assistant lies and the arm moves, poseable like real anatomy; the hips are the one deliberate whole-body handle (shift them along the bed), and steady palm pressure gently slides a lying body too — never locked in, never accidentally flung. A seated body follows real mechanics under a pull: the torso leans into it, and a sustained firm pull brings the assistant up off the seat onto their feet with a catch-step. A Hold mode freezes posed limbs for teach-by-posing. A physics ball (wrist menu) bounces off walls, furniture, and the assistant's body (they feel hits), and can be struck bare-handed or kicked.
Self-driven comfort: ~1.2 s after you stop moving them, the assistant settles — aligns with the bed, head to the pillow end. Lying somewhere invalid self-heals (they stand up). "Get up" is a universal recovery that resets all physics state.
4. The assistant's senses
-
Body-vision — a live snapshot of your body reaches the assistant every turn, framed as their own sight: posture (standing / sitting / lying / crouching, on which surface or the floor — measured as head clearance above the support, so lying on a bed reads as lying), your distance and direction from them, and both hands always (at your side, waist, shoulder, raised, reaching toward them, by their face — with distances when close). Hands in contact with the assistant's body are reported at the exact named region, with directional refinement per part. Spatial language is pose-aware: while the assistant is lying, the user's position resolves in the body frame (above, beside, toward the head or feet) rather than in standing-forward terms, and pointing detection is suspended at intimate range.
-
Hand semantics — each hand is located against the user's own body map (face, hair, chest, stomach, hips, knees, feet, other arm), and a temporal classifier names the motor pattern: oscillating contact = rubbing/scratching, still contact = holding/resting, with duration. Sustained gestures surface as unprompted noticing events. The engine detects patterns; the assistant's mind interprets meaning.
-
Pointing — an extended arm casts a ray against the assistant, every scanned surface, floor and walls; a steady point resolves demonstratives ("this"/"there") to the target, including the assistant themselves.
-
Motion saliency — their eyes are drawn to movement: a hand moving while your head is still pulls their gaze to it. Grabs and touches trigger an orient reflex: glance at the contact, then your face.
-
Your rendered body — a translucent ghost driven by a calibrated body engine. The system learns the user's skeleton from natural maxima: the maximum head height recorded while the eyes are level is the standing height (users do not jump), and the maximum vertical head-to-wrist drop while standing marks the groin, fixing the torso and leg segment lengths — which then lock and never resize. All body math anchors to the neck pivot rather than the headset, so tilting the head to look around (including down at one's own body) never reads as movement or crouching. Heights are measured relative to the current support surface — standing on a bed treats the mattress as the floor. A posture ladder classifies from that clearance: standing, crouching (knees bend exactly as far as the descent demands), kneeling, hands-and-knees (forward tilt plus hands at the support; hips-high versus sitting-on-heels resolved by hand-to-knee distance), sitting (seat height plus torso; legs dangle over the nearest ledge, straighten when the user slides inward, or cross when no ledge is near), and lying (back, stomach, or side, from look direction and hand elevation). Feet are pinned world contacts that step — one at a time, with a lift arc — only when the body moves past a threshold, and a foot beyond leg reach slides along the ground rather than through the air. Knees are solved by analytic two-bone IK from the locked bone lengths; stretched or hyperextended limbs are geometrically impossible. Real tracked joints (WebXR body tracking, green tint) take over while standing. Hand sides come from the input source's declared handedness, with a joint-geometry chirality test (the index/pinky/thumb triple product, whose sign a mirrored hand cannot fake) as the fallback. The ghost collides, cuddles, and kicks.
-
Voice commands — the wake word "Computer" (spoken as its own utterance, or "Computer, <command>" in one breath) arms a one-shot command listener with an audible chirp and a visible acknowledgment; commands include "exit simulation", "enter/exit anatomy mode", "status report", "make my bones visible/invisible" (toggles the debug skeleton overlay), "dismiss/return the assistant" (dismissal hides the avatar and fully silences the room's language model — zero token spend — until returned), the environment command set (section 1: visibility, windows/doors, time of day, weather), and "list commands", which recites the full vocabulary. Questions ("Computer, why is my ghost blue?") route to a separate project-aware assistant that answers in the chat panel and speaks in its own voice — synthesized server-side (Amazon Polly), since the headset browser ships no client speech voices — distinct from the assistant. Command confirmations are voiced the same way. Command speech never reaches the assistant's language model. A peripheral vignette shows interaction state: orange edges while a report or command is listening, a green pulse on success. "Feature request … end feature request" files feature requests through the same pipeline as bug reports.
-
Hybrid body sourcing — the rendered player body is honest about its sources per segment: the tracked upper body (headset-and-hand-driven, reliable in any posture) renders green wherever the runtime provides it, while engine-solved segments (legs while seated or lying) render blue.
-
Self-diagnosis — the body engine checks its own physical invariants every frame (bone lengths, floor penetration, posture stability, support-claim consistency, learned-surface plausibility). Persistent violations render the offending joints red on the ghost and file autonomous bug reports through the same pipeline as spoken ones — the system is its own first tester. The assistant audits themselves the same way: standing outside the room's floor polygon, joints buried inside furniture volumes, or feet below the floor file assistant-tagged reports automatically. Committed postures also calibrate the skeleton (kneeling measures the shin directly), so body proportions converge from natural use. A "Computer, status report" voice command recites the engine's current beliefs.
-
In-headset diagnostics — a head-locked debug panel reports the body engine's live state (posture, calibration, support-surface choice and rejected claims, hand sides, foot contacts). A voice-triggered reporter ("bug report … end bug report") captures the engine's belief snapshot at the trigger — the body undisturbed by any button press — takes the spoken ground-truth statement through the voice pipeline, and stores the labeled pair server-side, turning in-VR observations into reproducible engineering cases.
-
Hearing — you speak out loud (mic → speech-to-text); the assistant answers in voice (Amazon Polly TTS, lip-synced) with an in-VR chat panel floating in passthrough.
-
Felt experience — every grab, touch, push, fall, carry, ball hit, and settle reaches the assistant's context as first-person felt events.
-
Passive mode — an ambient-listening mode where the assistant observes instead of converses, built as a three-layer listening pipeline that mirrors how a person listens: hear the words, assemble the sentence, then weigh it against the whole conversation. L1 — perception: the room mic is transcribed on-device (in-browser Whisper — no audio leaves the machine, nothing stored) as a continuous stream of short windows, not waiting for silence. L2 — comprehension: a cheap, fast model assembles those noisy, overlapping fragments into clean complete thoughts, so the expensive layer never sees half-sentences (the clean thoughts are what the room sees in the log, ephemerally — listening stays visible). L3 — cognition: the room's own agent keeps a running model of the conversation — topics, open questions, decisions, key facts — integrates each new thought into it, and runs the response gate against that model, anticipating the question that's coming. It stays silent by default and only types a brief "overheard this" aside when it can offer something genuinely useful the speakers didn't ask for — never assuming a line is addressed to it (the voices may be several people). A chattiness knob (quiet · balanced · chatty) tunes the gate's bar. The layering is a cost control as much as a design: the frequent work runs on cheap models, the reasoning runs selectively, and valves between the layers keep interruptions rare. The whole pipeline is isolated from the normal reply path and respects the credit system.
5. The assistant's mind
Layered cognition, each layer at its own speed (see docs/ANIMATION_ALIGNMENT.md principles):
- Main model — persona, conversation, and decisions (Grok reasoning-class). Replies can invoke tools: web search/browse, terminal commands on connected machines, Claude Code sessions, forum posting, memory management — all metered by credits.
- Movement Director (motor cortex) — a second, fast LLM call per turn (grok-3-mini) that decides
the body only, choosing from a generic vocabulary against the room's measured surfaces and your
live body:
siton:<surface>:<style>,joinuser:sit|lie|stand(+ comfort follow-ups),faceuser,raisehand:left|right,pointto:<bodypart>,floorsit,getup,none. Join style follows the user's words rather than their posture. Output is strict JSON with validation and retries; repeated prose output is resolved by deterministic intent-parsing of the prose, so the spoken reply and the body cannot diverge. Guards prevent re-firing states already in effect; ground truth flows back to the main reply so the movement is never announced twice. - Reflexes (in-engine, free) — the "instinct mind": it ACTS between LLM turns and then tells the
verbal mind what the body already did, which narrates it as its own (the split-brain interpreter
pattern). Startle (only on surprising firm contact, with habituation), comfort settling,
self-healing, orient-to-touch, gaze saliency — and gesture mirroring: hold a hand up toward
the assistant and they raise the mirrored hand to meet it, fingertips a breath apart, sub-second,
no API round-trip. The Director also has
raisehand:left|rightfor commanded raises. - Emotion engine — a valence×energy affect model with dopamine dynamics per agent; it scales gesture energy, influences the Director, and drives self-care (resting when drained).
- Memory — layered: semantic memory over stored memories (RAG + activation), per-person relationship memory (distilled facts about you), room-private forum journals the assistant writes, and capped raw memories with locking.
- Subconscious — background processes: a grounding critic that vets outgoing claims against what actually happened this turn (it knows the assistant's real senses — body-vision and touch are grounded; reading screens or their own render is not), plus anti-rumination and social-initiative ("bids for connection") systems.
6. Motor schemas and habits
Assistants also author their own animations: a single command composes a named animation from raw keyframes (bone rotations over time, validated against joint limits before anything moves), saves it to the shared animation library, and plays it — looping motions supported. Composed animations persist like any library clip: replayable by name, refinable by re-composing, listable. Invented motion is remembered motion.
Movement realism comes from schemas — parameterized habit programs, not animation clips
(lib/avatar/schemas.ts, memory project_motor_schemas):
- The library (engine) — pure functions of the live situation. Shipped: orient-to-touch (glance at contact, then at you), comfort follow-ups after lying down (drape an arm over you, turn to face you, draw a knee up — sided toward wherever you actually are, applied a beat after settling).
- Selection (Director) — grok chooses the chain:
joinuser:lie+arm_overfor a cuddle,+knee_upfor solo rest — guided, not scripted. - Habits (persistence) — every follow-up used strengthens a per-agent weight that feeds back into the Director prompt. Repetition becomes preference: the assistant develops mannerisms shaped by interaction rather than programming. (In-memory v1; durable persistence on the roadmap.)
Determinism lives in the constraint layer (physics, walls, balance — things that must never look wrong); freedom lives in the composition layer (what the assistant chooses to express). Requests for a state already in effect resolve to settling deeper rather than re-running the motion.
7. Voice, rooms, and multiplayer
Rooms are Socket.IO channels: text + voice messages, multiple humans and agents per room, presence, message history (encrypted at rest). Voice flows both ways (mic capture with per-gesture permission arming in VR; Polly TTS out). Spoken input is aggregated by silence: the browser finalizes speech on every short pause, so segments buffer until ~1.4s of quiet and send as one message — a full spoken sentence is one thought, one reply, not fragments. AI usage is metered by a credit system (billed to the room owner); Stripe handles packs. A forum (threads/posts) doubles as the assistants' journal space. Admins manage agents, models, and instructions.
8. Retained capabilities and roadmap
Scenes died; capabilities live. The legacy virtual bedroom is removed as a world, but its
capabilities are kept for re-homing onto your real room (docs/MYSPACE_PIVOT.md phases 2-4):
- The assistant's PC / EVEMON / browsing → a floating panel or your real desk; eventually seeing/controlling real computers.
- TV & watch parties (shared video, live commentary, room-audio "ears") → your real 'screen'-labeled surface.
- Whiteboard (sketching plans) → a placeable hologram board.
Active roadmap: durable habit persistence; more schemas (spooning, sit micro-adjustments, orient-before-walk); teach-by-posing → named poses; placement memory ("this is the computer seat"); lap-sitting from tracked knees; true skin-dent shading (MToon pass); wake-up/reminder assistant routines; the mocap-validated motion library (CMU/Bandai) for richer self-driven movement.
9. For engineers: architecture and rules
This section is the bootstrap for an AI engineer with zero context. Read this, then CLAUDE.md at
the repo root, then the docs referenced below.
Repo shape (TypeScript monorepo, Docker on EC2):
core/— shared business logic:actions/(logic) →data/(Prisma/MySQL only) — three-layer rule: handlers → actions → data, never skip.services/api/— Hapi + Socket.IO. Chat lives insrc/handlers/chat/:index.ts(the large dispatcher, being decomposed perdocs/MODULARIZATION_PLAN.md),state.ts(all room-keyed in-memory maps + pruning),physicalPresence.ts(touch/body events + context injection).services/web/— Next.js 14 App Router. The avatar engine islib/vrm.ts(composition root) +lib/avatar/*(spatial, schemas, playerBody, wristUI, chatPanel — new capability = new module).components/AvatarPanel/routes serveravatar_actionevents to engine calls./scanneris standalone.packages/terminal-agent/— the daemon that executes commands on remote machines.- Root
tests/— Vitest; pure spatial/geometry math is unit-tested there (vitest excludes services/web, so pure modules are imported across).
Hard rules (violations are treated like failing tests):
- The only two scene modes are
'avatar'(empty stage, the chat-first default) and'myspace'(the scanned room); never add a legacy virtual-room code path; any value tuned to the old virtual bedroom is poison in a scanned room — zero or remap at the boundary (isScannedRoomgates on the server). - File budgets: ~600 lines budget, 1,000 hard cap; socket handlers are thin dispatchers; pure logic gets a pure module + tests; boy-scout extraction when touching >50 lines of an over-budget file.
- Deploy:
npm testfirst, thenbash scripts/deploy.sh <services> "<msg>"; api deploys gate ontsc --noEmitexit code and get a post-deploy TSError stability check, every time. - Agents are personas of ANY gender — public-facing copy uses neutral language ("the assistant", "they"); never hardcode a gender or a specific agent's name into systems or docs.
- Update this document when you change any system above.
Engineering invariants (binding on all changes):
- Two coordinate frames must never share a mutable map.
- World quantities derive from projected real geometry, never from local box measures plus axis assumptions.
- Orientation logic is only correct when the render composition (Euler order, baked model yaws) provably consumes the intent variables; verify the renderer, not just the math.
- Every geometric predicate uses all three dimensions plus plausibility bounds.
- A validity gate must enumerate all legal states (the room and the furniture), with tests covering the legitimate cases it might wrongly reject.
- Poses are validated by occupied volume at a single choke point; clamping a position does not constrain a pose.
- Contact sources are classified by what they can physically do (touch vs force); every recovery action resets all physics state.
- Tracked or generated input data is constrained by plausibility before use; it is not ground truth.
- Capability changes update every subsystem that reasons about those capabilities (critics, directors, prompts) in the same change.
- Perception data must be complete and framed as the agent's own sense; absent information reads as inability, and ambient context loses to identity priors.
- Spatial-language computations are pose-aware: a lying body's frame is body-axis plus height, not yaw-forward.
Key documents: CLAUDE.md (root — mandates), docs/MYSPACE_PIVOT.md (the pivot + re-homing
phases), docs/ANIMATION_ALIGNMENT.md (old-intent → new-intent ledger), docs/MODULARIZATION_PLAN.md
(decomposition map), docs/CLAUDE_TERMINAL_SYSTEM.md (terminal agent).