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.
| Component | Description |
|---|---|
LocalTransform | Position, rotation, and scale relative to the parent |
GlobalTransform | Computed world-space transformation matrix |
LocalTransformDirty | Marker flagging that the transform needs propagation |
Parent | Reference to the parent entity |
IgnoreParentScale | Excludes the parent's scale from the propagated transform |
Rotation | Additional 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.
| Component | Description |
|---|---|
RenderMesh | Names a mesh in the mesh cache |
MaterialRef | Names a material in the material registry |
RenderLayer | Depth and layer used for ordering |
CastsShadow | Marks the entity for shadow-map rendering |
Visibility | Per-entity visibility toggle |
BoundingVolume | Bounding shape used for culling and picking |
InstancedMesh | GPU-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
| Component | Description |
|---|---|
Camera | Projection mode and optional smoothing |
PanOrbitCamera | Pan-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
| Component | Description |
|---|---|
Light | Directional, 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.
| Component | Description |
|---|---|
RigidBodyComponent | Dynamic, fixed, or kinematic body |
ColliderComponent | Collision shape |
CharacterControllerComponent | Kinematic player controller |
PhysicsInterpolation | Smooths the rendered transform across physics ticks |
CollisionListener | Receives 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 aFixedbodyRigidBodyComponent::new_kinematic()builds aKinematicPositionBasedbody
The flag is RIGID_BODY, not RIGID_BODY_COMPONENT. The Component suffix is on the type only.
Animation components
| Component | Description |
|---|---|
AnimationPlayer | Playback state for skeletal and morph animation |
Skin | Skeleton definition |
Joint | A bone in a skeleton |
MorphWeights | Blend-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
| Component | Description |
|---|---|
AudioSource | A playable sound attached to an entity |
AudioListener | The receiver for 3D audio, usually the camera |
Text components
| Component | Description |
|---|---|
Text | 3D world text and screen-space UI text |
TextCharacterColors | Per-character foreground colors |
TextCharacterBackgroundColors | Per-character background colors |
The per-character color components are optional sidecars. Without them, every character uses the Text struct's main color.
Geometry
| Component | Description |
|---|---|
Lines | Debug 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
| Component | Description |
|---|---|
ParticleEmitter | GPU particle system |
GrassRegion | Procedural grass field |
GrassInteractor | Bends grass blades around the entity |
NavMeshAgent | AI pathfinding agent |
Decal | Projected texture on nearby geometry |
PrefabSource | The prefab a spawned instance was built from |
PrefabInstance | An instance node inside a spawned prefab |
Hovered | Marks the entity under the mouse cursor |
Name | String identifier used for entity lookup |