Builtin Library
README.md
Humanoid
Marker component for entities carrying a skeleton conforming to the
standard humanoid bone layout (Synty / Unreal-Mannequin convention).
Content reads a humanoid body's bones and attachment sockets through this
component instead of re-walking the descendant tree, and seats items on
those sockets with :attach.
Bone naming convention
Hips
Spine_01 → Spine_02 → Spine_03 → Neck → Head
└ Eyes, Eyebrows, Jaw
UpperLeg_R / UpperLeg_L
LowerLeg_R / LowerLeg_L
Ankle_R / Ankle_L
Ball_R / Ball_L → Toes_R / Toes_L
Clavicle_R / Clavicle_L
Shoulder_R / Shoulder_L
Elbow_R / Elbow_L
Hand_R / Hand_L
IndexFinger_01..04 / Thumb_01..04 / Finger_01..04
Mixamo / Unity-Humanoid imports go through a bone-rename pass at import time (tracked separately).
Fields
| Field | Type | Notes |
|---|---|---|
height | number | Foot-to-head height in T-pose, metres. Default 1.8. |
eye_height | number | Foot-to-eyes height, metres. Default 1.65. |
bones | { [string]: entity } | Computed; bone-name → entity-proxy map. Re-walks on read. |
sockets | { [string]: entity } | Computed; role (righthand, head, …) → the bone filling it on this body, through the body's RetargetProfile. |
Methods
| Method | Returns | Notes |
|---|---|---|
:bone(name) | entity | nil | Nil-safe single-bone lookup; same as self.bones[name]. |
:socket(point) | entity | nil | The bone at a role, or at an exact bone name. |
:attach(point, childId, opts?) | entity | nil | Seats childId on the socket bone at the socket's frame, moved by opts.position / opts.rotation / opts.scale. Position and scale are metres in the humanoid's own space, whatever bone units the rig was authored in; rotation is relative to the bone, as a quaternion { x, y, z, w } or Euler degrees { pitch, yaw, roll }. An option outside those three, or a value in none of those forms, raises with the item left as it was. Returns the socket bone. |
:attachments() | { { id, point, position, rotation, scale } } | Every item seated with attach, with the point and transform it was seated with. An avatar body swap re-seats each on the new body. |
The sockets are slots of the Slot family: an Assembly on a humanoid lists
each role socket as a slot of that kind (righthand, head, ...) and fills it
with a part whose Part.fits names the role, seated the way :attach seats an
item (guides { path: "topics/assemblies" }).
Usage
-- Read a specific bone
local h = entity(playerId).component.get("Humanoid")
local head = h.bones.Head -- entity proxy
local handR = h:bone("Hand_R") -- nil-safe lookup
-- Seat a hat 12 cm above the head, on any humanoid body
local hat = entity.spawn("hat")
h:attach("head", hat.id, { position = { 0, 0.12, 0 } })
-- Read height for camera mounting
local cam = entity.spawn("eye_cam", { parent = playerId })
cam.localPosition = { 0, h.eye_height, 0 }
Ragdolling a humanoid
animation.ragdoll(playerId) makes the body a ragdoll: bodies sized per body
part, hinged knees and elbows, cones at the shoulders, hips and neck. A
description names bones by the same roles as sockets (head, leftarm,
rightleg, ...), so it fits every humanoid body. The physics guide's
"Ragdolls" section (guides { path: "topics/physics" }) has the rest.
animation.ragdoll(playerId) -- collapse
animation.ragdoll(playerId, { limp = { "rightarm" } }) -- one arm hangs, the rest animates
animation.ragdoll(playerId, false) -- back to the animation
Tag convention
Bundles carrying a humanoid skeleton tag themselves with both
playerVisual AND humanoid in their .metadata. Tooling can filter
to humanoid-conforming visuals via
asset.list("bundle", nil, { fields = { tags = { "playerVisual", "humanoid" } } }).