Bone overrides and attachments
Change how a model looks and what it carries from server code, without touching its animation.
Bone overrides
An override changes one property of one bone on top of whatever the animation is doing: hide a hat, tint hair, turn a head. Set from the server, they are synced to every player tracking the entity, so they are the same for everyone and survive a player leaving and returning.
entity.overrides().setHidden("hat", true);
entity.overrides().setColor("hair", new Color(0xFFFF66AA));
entity.overrides().setRotation("head", 0f, (float) Math.toRadians(25), 0f);
entity.overrides().clear("hat", com.sandymandy.strut.animation.override.OverrideProperty.HIDDEN);
Call them on entity.overrides(). The properties are:
| Property | Setter | Effect |
|---|---|---|
HIDDEN | setHidden(bone, hidden) | Hides the bone and its children. |
CHILDREN_HIDDEN | setChildrenHidden(bone, hidden) | Hides the bone's children but not the bone itself. |
POSITION | setPosition(bone, x, y, z) | Offsets the bone. |
ROTATION | setRotation(bone, x, y, z) | Sets the bone's rotation, in radians, in place of what the animation gave it (it does not add to it). |
SCALE | setScale(bone, x, y, z) | Scales the bone. |
COLOR | setColor(bone, color) | Tints the bone (ARGB). |
UV_OFFSET | setUvOffset(bone, u, v) | Scrolls the bone's texture coordinates. |
UV_SIZE | setUvSize(bone, w, h), or setTexture(bone, texture, w, h) | The pixel size the bone's UVs are read against. A model's UVs are fractions of its own texture, so a texture override of another size (a 64 x 64 player skin on a model made for a smaller texture) misses its pixels; with the size set the UVs are rescaled by the model's texture size over this one. Applies to every texture drawn on the bone, an overlay too. |
TEXTURE | setTexture(bone, texture) | Draws the bone with a different texture. |
TRANSLUCENT | setTranslucent(bone, translucent) | Draws the bone blended, after the opaque geometry. See Rendering. |
OVERLAY_0 to OVERLAY_3 | setOverlay(bone, layer, texture), clearOverlay(bone, layer) | Draws a second texture over the bone, translucent, on top of its own. A higher layer draws later. |
clear(bone, property) removes one. Every setter also has a long form taking a scope, a priority, a blend weight and a transition time in ticks. The higher priority wins where two overrides touch the same property, and the blend weight and transition fade an override in and out.
| Scope | Lasts |
|---|---|
PERSISTENT | Until you clear it. |
CONTROLLER, SYNC_GROUP | Reserved for overrides that clear themselves with a controller state or a synchronisation group. Nothing clears them yet, so today they behave like PERSISTENT. |
FRAME | Clears at the end of the client frame that set it: for a per-viewer, per-frame decision such as hiding the local player's own head only in first person. Client-only in practice. |
Note. A texture override on a bone is not redrawn in the shadow pass under shader packs: it changes colour, not the silhouette a shadow needs.
Attachments
An attachment carries an item or a block on a bone: a sword in a hand, a crate on a back. It follows the bone through every animation. Attachments are keyed by a slot name you choose, so you can replace or clear one without touching the others.
entity.attachments().setItem("main_hand", "right_hand", Identifier.of("minecraft", "diamond_sword"));
entity.attachments().setBlock("crate", "back", Identifier.of("minecraft", "barrel"));
entity.attachments().clear("main_hand");
Both setItem and setBlock have longer forms for a stack count and a transform; their rotation is in radians, and setItem draws the item model with no holder (its display transform is not applied). For something a character holds, use setHeldItem(slot, bone, item, count, rightHand, offsetX, offsetY, offsetZ, rotXDegrees, rotYDegrees, rotZDegrees, scale): it draws the item as a player's hand does, with the model's own third-person transform, and takes the same offset (blocks) and turn (degrees) as HandItem does for a player body, so a character and a player body holding the same item look the same. Like overrides, attachments are set on the server and synced.