---
title: Bone Collections Info & Upgrade Guide
---
[TOC]
# General Notes
- Bone Collections are owned by the Armature, so they are available in all modes. To contrast, bone groups were stored on the object's pose, and thus were not available in armature edit mode.
- Bone Collection names are unique within the Armature.
In the code below, it is assumed that `obj` is an armature object, and `arm` is the armature itself. In other words, `arm = obj.data`.
# Visibility
- Bone visibility is determined by the visibility of its collections, and its own 'hidden' property.
- If the bone itself is marked as 'hidden', it is invisible regardless of the bone collections.
- A bone is visible when it is contained in any visible collection.
- A bone that is not assigned to any bone collection is visible; otherwise it would be impossible to select it & assign it to a collection.
# Upgrading Armature Layers to Bone Collections
## Versioning
- Blender 4.0 will convert armature layers to bone collections.
- The name of the collection will be `Layer N`, where `N` is `1…32`.
- If the armature had layer names set via the [Bone Manager add-on](https://fin.gumroad.com/l/STdb), these names will be appended: `Layer N - Name`. That add-on stores the desired names in custom properties on the armature named `layer_name_M`, with `M` ranging `0…31`.
- Each layer that contains one or more bones will be converted. Empty layers are skipped.
## Changing Visibility
Blender 3.6 and older:
```python
arm.layers = [True, False, True] + 29 * [False]
arm.layers[0] = False
```
Blender 4.0:
```python
for bcoll in arm.collections:
bcoll.is_visible = True
arm.collections['IK Controls'].is_visible = False
arm.collections[0].is_visible = False
```
## Assigning & Unassigning Bones
Blender 3.6 and older:
```python
arm.bones['arm_lower_R'].layers = [True, False, True] + 29 * [False]
arm.bones['arm_lower_R'].layers[1] = True
```
Blender 4.0:
```python
arm.collections['IK Controls'].assign(arm.bones['arm_lower_R'])
arm.collections['IK Controls'].unassign(arm.bones['arm_lower_R'])
arm.collections[2].assign(arm.bones['arm_lower_R'])
arm.collections[2].unassign(arm.bones['arm_lower_R'])
```
## Assigning bone to collections of another Bone:
Blender 3.6 and older:
```python
arm.bones['arm_lower_R'].layers = arm.bones['other_bone'].layers
```
Blender 4.0 (until there is a `bone.collections.set(other_collections)` function):
```python
bone = arm.bones['arm_lower_R']
bone.collections.clear()
for bcoll in arm.bones['other_bone'].collections:
bcoll.assign(bone)
```
## Bones in a Layer / Collection
Blender 3.6 and older:
```python
in_layer_3 = [bone for bone in arm.bones
if bone.layers[3]]
```
Blender 4.0:
```python
# Any mode but armature edit mode:
in_collection = arm.collections['IK Controls'].bones
# Armature edit mode:
in_collection = [ebone for ebone in arm.edit_bones
if 'IK Controls' in ebone.collections]
```
## Custom Properties on Collections
Blender 3.6 and older had to store data on the Armature itself:
```python
arm["custom_layer_data"] = {
0: 'some data for layer 0',
1: 'other data for layer 1',
}
```
Blender 4.0 has custom properties on bone collections:
```python
arm.collections['IK Controls']['custom'] = 'some custom data'
arm.collections[3]['whatever'] = 'you need'
```
# Upgrading Bone Groups to Bone Collections
- Blender 4.0 will convert bone groups to bone collections.
- The name of the collection will be the same as that of the bone group.
- Bone Groups are converted *after* Armature Layers. This means that if you had a bone group named `Layer 1`, and armature layer 1 also was converted into a bone collection, the collection for the bone group will be named `Layer 1.001`.
- The collections for bone groups are initially hidden. This is to ensure the same behavior as Blender 3.6 and older, where the layers determined visibility and the groups did not (see above for the visibility rules of bone collections).
- As bone groups were stored on the Object's pose data, and not on the Armature itself, this only happens when the Object is available. Linking the Armature from a 3.6 file (in contrast to linking the armature Object) will *not* do this conversion, as the data simply is not available.
- All bone groups are converted, so also when they did not contain any bones.
# Bone Color
Blender 3.6 used Bone Groups to color bones. Bone Groups were stored on the object's pose data, and not the armature itself, which had certain implications:
- Bone color was not available in armature edit mode.
- Bone color could not be shared between all users of an armature, but had to be set up and maintained per obj.
- Bone color could be set on a per-object basis, even when they shared the armature. This is useful, for example, to ensure good contrast between bones and each character's colors.
Blender 4.0 stores the bone color directly on the armature bone. The pose bone can override this color. This makes it possible to retain the per-object unique color described above.
## Python code
Blender 3.6 and older. Assumption: the bone is already assigned to the bone group.
```python
# Set theme color:
obj.pose.bone_groups['IK Bones'].color_set = 'THEME09'
# Set custom color:
group = obj.pose.bone_groups['IK Bones']
group.color_set = 'CUSTOM'
group.colors.active = (0.95, 1.0, 0.0)
# Disable display of bone colors on the armature:
arm.show_group_colors = False
```
Blender 4.0:
```python
# On the armature bone:
bone = arm.bones['arm_lower_R']
# Alternatively, set on the pose bone:
bone = obj.pose.bones['arm_lower_R']
# Set theme color:
bone.color.palette = 'THEME09'
# Set custom color:
bone.color.palette = 'CUSTOM'
bone.color.custom.active = (0.95, 1.0, 0.0)
# Disable display of bone colors on the armature:
arm.show_bone_colors = False
```
# Library Overrides
Bone collections can be added using library overrides. For this to work, both the armature Object and the Armature itself need to be overridden.
## Limitations
There are a few limitations when it comes to bone collections & overrides:
- Only bone collections that are local to the current blend file can be edited. Bone collections that already existed on the linked-in Armature are read-only, and only their visibility can be toggled.
- Custom properties of overridden bone collections cannot be edited in the properties panel. Python access is fine; this is just a limitation of Blender's UI code.
## How It Works
Bone collections added via overrides are 'anchored' to the preceeding collection, by name. Here is an example. The *italic* collections are defined on the linked Armature in `armature.blend`. The **bold** ones are added by overrides in `armature_shot_47.blend`.
- *FK Controls*
- *IK Controls*
- **Left Pinky** (anchored to "IK Controls")
- **Right Pinky** (anchored to "Left Pinky")
Now if the Armature in `armature.blend` gets updated with two more collections it might look like this:
- *FK Controls*
- *IK Controls*
- *Face Controls*
- *Face Detail Controls*
After reloading `armature_shot_47.blend`, it will look like this:
- *FK Controls*
- *IK Controls*
- **Left Pinky** (still anchored to "IK Controls")
- **Right Pinky** (still anchored to "Left Pinky")
- *Face Controls*
- *Face Detail Controls*