{ version: "3,0", // see note 1 - v4 frames still report "3,0" fps: 60, scene: { timestamp: 0, // seconds, floating point actors: [], // always emitted; empty when streaming JSON v4 newtons: [ { name: "Newton 01", color: [r, g, b], // integer array, 0-255 meta: { hasHands: true, hasLeftHand: true, hasRightHand: true, hasBody: true, hasFace: false }, dimensions: { totalHeight: 1.75, // metres hipHeight: 0.94 // metres }, joints: [ // flat list, world space, order not guaranteed { name: "Hips", parent: -1, // index into this array; -1 = no parent position: {x: 0, y: 0.94, z: 0}, rotation: {x: 0, y: 0, z: 0, w: 1} }, { name: "Spine1", parent: 0, position: {x: 0, y: 1.04, z: 0}, rotation: {x: 0, y: 0, z: 0, w: 1} }, {...} // see note 3 for the full Newton joint list ], face: { // omitted entirely when there are no blendshapes leftEyeBlink: 0, ... } }, {...} ], props: [], // always emitted; currently always empty characters: [] // reserved; empty unless a character is streamed } } NOTES 1. Version field JSON v4 frames carry version "3,0", the same value JSON v3 frames carry. The field cannot be used to tell the two formats apart. Detect the format from the payload instead: a v3 frame fills scene.actors and leaves scene.newtons empty; a v4 frame fills scene.newtons and leaves scene.actors empty. Both keys are always present. 2. Coordinate system and units Left-handed, Y up, Z forward - the same convention as JSON v3. Positions are in metres. Rotations are quaternions, ordered x, y, z, w. Every joint transform is in WORLD space, even though the joint carries a parent index. The parent index describes the skeleton hierarchy; it does not mean the transform is parent-relative. Do not compose parent transforms into children - you will double-transform the pose. 3. Joint list The joints array is the Newton skeleton, enumerated from the streamed entity's root downwards. The shipped Newton rig has 76 bones: two container nodes (Newton, Root), a four-segment spine (Spine1..Spine4), HeadTip, five joints per finger (four for the thumbs, which have no Medial), and toe tips. Newton, Root, Hips, Spine1, Spine2, Spine3, Spine4, Neck, Head, HeadTip, LeftShoulder, LeftArm, LeftForeArm, LeftHand, RightShoulder, RightArm, RightForeArm, RightHand, LeftThigh, LeftShin, LeftFoot, LeftToe, LeftToeTip, RightThigh, RightShin, RightFoot, RightToe, RightToeTip, and, for each hand, per finger N = 1..5 (1 = thumb, 2 = index, 3 = middle, 4 = ring, 5 = little): {Left|Right}FingerN{Metacarpal, Proximal, Medial, Distal, Tip} The thumb (Finger1) has no Medial joint, so it contributes four names instead of five. Match joints by name and build the hierarchy from the parent index. Do not hardcode array positions - the enumeration starts at the streamed entity's root and the ordering is not part of the contract. 4. Compression Both formats are offered plain and LZ4-framed: "JSON v3", "JSON v3 (LZ4)", "JSON v4", "JSON v4 (LZ4)". An LZ4 payload starts with the LZ4 frame magic 04 22 4D 18. The JSON itself is ASCII encoded, one complete frame per UDP datagram, with no length prefix or header of any kind. 5. Differences from JSON v3 - Joints arrive as a flat array with explicit parent indices instead of a fixed-key body object. - Joint names are the native Newton skeleton names (Hips, Spine1, LeftFinger2Proximal) instead of the v3 humanoid names (hip, spine, leftIndexProximal). - Spine2 and Spine3, HeadTip, the finger Tip joints and the toe tips have no JSON v3 equivalent. - meta uses hasHands / hasLeftHand / hasRightHand where v3 uses hasGloves / hasLeftGlove / hasRightGlove.