How To Use Nodes
Use concrete node types inside with_node! and with_node_mut! closures, and use SceneNode helper macros for hierarchy metadata operations.
Mutate Concrete Node Data
The typed nodes in the hierarchy are what you pass to runtime access closures. Start with direct Sprite2D data:
with_node_mut!(ctx, Sprite2D, node_id, |sprite| { sprite.texture_id = TextureID::new(42);});Deref Inheritance
Descendant nodes include a base field of their ancestor type and implement Deref/DerefMut. Take Sprite2D and Node2D for example:
pub struct Sprite2D { pub base: Node2D, pub texture_id: TextureID,} impl Deref for Sprite2D { type Target = Node2D; fn deref(&self) -> &Self::Target { &self.base }} impl DerefMut for Sprite2D { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.base }}Deref access is resolved at compile time, so there is no runtime overhead. When you have a Sprite2D, you treat it as also having Node2D fields like position and visibility, so those fields are used as if they are native on the concrete node even though they come through deref.
with_node_mut!(ctx, Sprite2D, node_id, |sprite| { // Sprite2D field sprite.texture_id = TextureID::new(7); // Node2D fields via Deref/DerefMut sprite.position.x += 12.0; sprite.visible = true; sprite.z_index = 3;});SceneNode Metadata Macros
For name/parent/children/reparent operations, use SceneNode helper macros:
let name = get_node_name!(ctx, self_id).unwrap_or_default();let parent_id = get_node_parent_id!(ctx, self_id).unwrap_or(NodeID::nil());let children = get_node_children_ids!(ctx, self_id).unwrap_or_default();set_node_name!(ctx, self_id, "Player");reparent!(ctx, new_parent_id, child_id);