Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Components

Nightshade ships 55 built-in components. 45 live in the Core sub-world and cover the 3D engine. The remaining 10 live in Ui and are documented in Retained UI. This chapter catalogues the core set by category.

Transform components

The transform components hold each entity's position in the scene graph, both relative to its parent and in world space.

ComponentDescription
LocalTransformPosition, rotation, and scale relative to the parent
GlobalTransformComputed world-space transformation matrix
LocalTransformDirtyMarker flagging that the transform needs propagation
ParentReference to the parent entity
IgnoreParentScaleExcludes the parent's scale from the propagated transform
RotationAdditional rotation component used by spinning props
#![allow(unused)]
fn main() {
pub struct LocalTransform {
    pub translation: Vec3,
    pub rotation: Quat,
    pub scale: Vec3,
}

pub struct GlobalTransform(pub Mat4);

pub struct Parent(pub Option<Entity>);
}

The dirty-marker pattern is the speed trick. Instead of rebuilding every global matrix every frame, the transform system only touches entities that carry LOCAL_TRANSFORM_DIRTY, plus their descendants. After a manual write to a LocalTransform, call mark_local_transform_dirty(world, entity) so the propagation system picks it up.

Rendering components

These are the components the renderer reads when it iterates renderable archetypes.

ComponentDescription
RenderMeshNames a mesh in the mesh cache
MaterialRefNames a material in the material registry
RenderLayerDepth and layer used for ordering
CastsShadowMarks the entity for shadow-map rendering
VisibilityPer-entity visibility toggle
BoundingVolumeBounding shape used for culling and picking
InstancedMeshGPU-instanced mesh data, used for crowds of identical meshes
#![allow(unused)]
fn main() {
pub struct RenderMesh {
    pub name: String,
    pub id: Option<MeshId>,
}

pub struct MaterialRef {
    pub name: String,
    pub id: Option<MaterialId>,
}
}

MaterialRef::new(name) takes impl Into<String>, so the call is the natural one.

#![allow(unused)]
fn main() {
MaterialRef::new("Default")
}

The id fields are resolved lazily. The first access hashes the name to a cache id and caches the result on the component.

Camera components

ComponentDescription
CameraProjection mode and optional smoothing
PanOrbitCameraPan-orbit controller state

There is a single CAMERA flag. The projection mode (perspective or orthographic) is decided by the Projection enum inside the Camera struct, not by a separate component.

#![allow(unused)]
fn main() {
pub struct Camera {
    pub projection: Projection,
    pub smoothing: Option<Smoothing>,
}

pub enum Projection {
    Perspective(PerspectiveCamera),
    Orthographic(OrthographicCamera),
}

pub struct PerspectiveCamera {
    pub aspect_ratio: Option<f32>,
    pub y_fov_rad: f32,
    pub z_far: Option<f32>,
    pub z_near: f32,
}

pub struct OrthographicCamera {
    pub x_mag: f32,
    pub y_mag: f32,
    pub z_far: f32,
    pub z_near: f32,
}
}

aspect_ratio: None means "follow the window aspect." z_far: None means "no far plane," which is what reverse-Z infinite projection wants.

Lighting

ComponentDescription
LightDirectional, point, or spot light
#![allow(unused)]
fn main() {
pub struct Light {
    pub light_type: LightType,
    pub color: Vec3,
    pub intensity: f32,
    pub range: f32,
    pub cast_shadows: bool,
    pub shadow_bias: f32,
    pub inner_cone_angle: f32,
    pub outer_cone_angle: f32,
}

pub enum LightType {
    Directional,
    Point,
    Spot,
}
}

Like cameras, one flag covers all three light types. inner_cone_angle and outer_cone_angle are zero for non-spot lights.

Physics components

Physics is feature-gated. These components only exist with the physics feature enabled.

ComponentDescription
RigidBodyComponentDynamic, fixed, or kinematic body
ColliderComponentCollision shape
CharacterControllerComponentKinematic player controller
PhysicsInterpolationSmooths the rendered transform across physics ticks
CollisionListenerReceives collision events
#![allow(unused)]
fn main() {
pub struct RigidBodyComponent {
    pub handle: Option<RigidBodyHandle>,
    pub body_type: RigidBodyType,
    pub translation: [f32; 3],
    pub rotation: [f32; 4],
    pub linvel: [f32; 3],
    pub angvel: [f32; 3],
    pub mass: f32,
    pub locked_axes: LockedAxes,
}

pub enum RigidBodyType {
    Dynamic,
    Fixed,
    KinematicPositionBased,
    KinematicVelocityBased,
}
}

Constructors cover the common cases.

  • RigidBodyComponent::new_dynamic()
  • RigidBodyComponent::new_static() builds a Fixed body
  • RigidBodyComponent::new_kinematic() builds a KinematicPositionBased body

The flag is RIGID_BODY, not RIGID_BODY_COMPONENT. The Component suffix is on the type only.

Animation components

ComponentDescription
AnimationPlayerPlayback state for skeletal and morph animation
SkinSkeleton definition
JointA bone in a skeleton
MorphWeightsBlend-shape weights
#![allow(unused)]
fn main() {
pub struct AnimationPlayer {
    pub clips: Vec<AnimationClip>,
    pub current_clip: Option<usize>,
    pub blend_from_clip: Option<usize>,
    pub blend_factor: f32,
    pub playing: bool,
    pub speed: f32,
    pub time: f32,
    pub looping: bool,
}
}

blend_from_clip and blend_factor drive crossfades between two clips. When blend_from_clip is Some, the player produces the weighted blend of both clips at the same time index.

Audio components

ComponentDescription
AudioSourceA playable sound attached to an entity
AudioListenerThe receiver for 3D audio, usually the camera

Text components

ComponentDescription
Text3D world text and screen-space UI text
TextCharacterColorsPer-character foreground colors
TextCharacterBackgroundColorsPer-character background colors

The per-character color components are optional sidecars. Without them, every character uses the Text struct's main color.

Geometry

ComponentDescription
LinesDebug line rendering
#![allow(unused)]
fn main() {
pub struct Lines {
    pub lines: Vec<Line>,
}

pub struct Line {
    pub start: Vec3,
    pub end: Vec3,
    pub color: Vec4,
}
}

Lines is rebuilt per frame by gizmo code. It is the cheap way to draw rays, bounding boxes, and navmesh edges without authoring a mesh.

Advanced components

ComponentDescription
ParticleEmitterGPU particle system
GrassRegionProcedural grass field
GrassInteractorBends grass blades around the entity
NavMeshAgentAI pathfinding agent
DecalProjected texture on nearby geometry
PrefabSourceThe prefab a spawned instance was built from
PrefabInstanceAn instance node inside a spawned prefab
HoveredMarks the entity under the mouse cursor
NameString identifier used for entity lookup