# Hierarchy & Relationships ## ChildOf / Children (0.16+ model) - `ChildOf(pub Entity)` lives on the **child** and points at the parent. (`Parent` no longer exists.) - Get the parent via `child_of.parent()` — the old `Deref` was removed. - `ChildOf` implements `Relationship`; `Children` implements `RelationshipTarget`. They auto-sync via hooks: adding `ChildOf(p)` to a child inserts/updates `Children` on `p`; removing it updates the parent. Never maintain `Children` manually. - Despawning a parent despawns all descendants — `despawn()` is recursive by default (`despawn_recursive` is gone). ## Spawning children ```rust // Direct: ChildOf in the spawn tuple commands.spawn((Turret, ChildOf(ship))); // Closure for several children commands.entity(ship).with_children(|spawner| { spawner.spawn(Turret); let ship = spawner.target_entity(); // was parent_entity() }); // Attach existing entities commands.entity(ship).add_child(turret); commands.entity(ship).add_children(&[a, b]); commands.entity(ship).insert_children(index, &[a, b]); ``` ## Querying - `Children` derefs to `[Entity]` and implements `IntoIterator` yielding `Entity`. - Iterate: `for child in &children` — not `children.iter().copied()`. - Methods: `len()`, `is_empty()`, `contains()`, `first()`, `last()`, `sort_by()`. - Relationship-generic query extensions: `query.related::(entity)`, `query.relationship_sources::(entity)`. ## Detach vs despawn (0.18 names) | Method | Effect | |--------|--------| | `detach_child(e)` | unparent one child, keep it alive | | `detach_children(&[..])` | unparent several | | `detach_all_children()` | unparent all | | `despawn_related::()` | despawn the children themselves | The pre-0.18 names (`remove_child`, `remove_children`, `clear_children`) are gone. ## Custom relationships `#[relationship]` / `#[relationship_target]` derive pairs get the same auto-sync as `ChildOf`/`Children`. Do **not** write observers that manually push/remove entities in the target collection — the hooks already do it, and manual sync causes duplicates or desync. ## Transform propagation - Child `Transform` is parent-relative; `GlobalTransform` is computed world-space through the `ChildOf` chain. - Propagation runs in **`PostUpdate`** (`TransformSystem::TransformPropagate`). A system in `Update` reading `GlobalTransform` sees last frame's value. - Options: schedule the reader in `PostUpdate` after propagation; accept the one-frame lag (often fine); or (rarely) walk the `Transform` chain manually. ## Quick corrections | Stale | Correct | |-------|---------| | `Parent` | `ChildOf(entity)` | | `*child_of` | `child_of.parent()` | | `children.iter().copied()` | `for child in &children` | | `despawn_recursive()` | `despawn()` | | `parent_entity()` (in spawner) | `target_entity()` | | `remove_children` / `clear_children` | `detach_children` / `detach_all_children` |