Understanding Compositions
Welcome to Lesson 1.4! In this lesson, you'll master the fundamental building block of HoloScript: the composition. You'll learn how compositions work, their properties, and best practices for defining 3D objects.
What is a Composition?
A composition is HoloScript's primary wrapper for a 3D object or scene in your experience. Think of it as a container that holds:
- Geometry - The shape (cube, sphere, model, etc.)
- Properties - Position, color, scale, material
- Traits - Behaviors like @grabbable or @physics
- Events - Handlers like onGrab or onClick
Basic Composition Syntax
composition myCube {
geometry: "cube"
position: [0, 1, 0]
color: "#ff0000"
}Geometry Types
HoloScript supports many built-in geometry types:
Primitives
composition box {
geometry: "cube"
scale: [1, 1, 1]
}
composition ball {
geometry: "sphere"
radius: 0.5
}
composition tube {
geometry: "cylinder"
radiusTop: 0.3
radiusBottom: 0.3
height: 1.0
}
composition ring {
geometry: "torus"
radius: 0.5
tubeRadius: 0.1
}
composition pill {
geometry: "capsule"
radius: 0.3
height: 1.0
}
composition floor {
geometry: "plane"
width: 10
height: 10
}3D Models
Load external 3D models:
composition character {
geometry: "model/characters/player.glb"
scale: [1, 1, 1]
}
composition furniture {
geometry: "model/props/chair.gltf"
position: [2, 0, 0]
}Supported formats: .glb, .gltf, .obj
Essential Properties
Position
Position uses a 3D vector [x, y, z]:
composition mycomposition {
position: [0, 0, 0] // Origin (center of scene)
position: [1, 0, 0] // 1 meter to the right
position: [0, 2, 0] // 2 meters up
position: [0, 0, -3] // 3 meters in front
}Rotation
Rotation uses Euler angles in degrees:
composition rotated {
rotation: [0, 0, 0] // No rotation
rotation: [45, 0, 0] // Tilted forward 45°
rotation: [0, 90, 0] // Turned right 90°
rotation: [0, 0, 30] // Rolled 30°
}Scale
Scale can be uniform or per-axis:
composition scaled {
scale: 2 // Uniform scale (2x bigger)
scale: [1, 2, 1] // Stretched vertically
scale: [0.5, 0.5, 0.5] // Half size
}Color
Colors use hex codes or named colors:
composition colored {
color: "#ff0000" // Red
color: "#00ff00" // Green
color: "#0000ff" // Blue
color: "red" // Named color
color: "steelblue" // CSS color name
}Opacity
Control transparency (0-1):
composition transparent {
color: "#ffffff"
opacity: 0.5 // 50% transparent
}Materials
For more control, use the material property:
composition metallic {
geometry: "sphere"
material: {
color: "#c0c0c0"
metalness: 1.0
roughness: 0.2
}
}
composition glowing {
geometry: "cube"
material: {
color: "#00ffff"
emissive: "#00ffff"
emissiveIntensity: 0.5
}
}
composition textured {
geometry: "plane"
material: {
map: "textures/wood.jpg"
normalMap: "textures/wood_normal.jpg"
}
}Naming Conventions
Good composition names are:
- Descriptive - Tell what the object represents
- Unique - No duplicate names in the same scope
- CamelCase - For multi-word names
// ✓ Good names
composition playerCharacter { }
composition redButton { }
composition mainDoor { }
composition enemySpawner { }
// ✗ Avoid
composition x { } // Not descriptive
composition my_cube { } // Use camelCase
composition Comp1 { } // Not meaningfulNested Compositions
Compositions can contain other compositions (or children objects), creating parent-child relationships:
composition table {
geometry: "cube"
scale: [1, 0.1, 0.6]
position: [0, 0.75, 0]
object leg1 {
geometry: "cylinder"
scale: [0.05, 0.75, 0.05]
position: [-0.4, -0.4, -0.25]
}
object leg2 {
geometry: "cylinder"
scale: [0.05, 0.75, 0.05]
position: [0.4, -0.4, -0.25]
}
object leg3 {
geometry: "cylinder"
scale: [0.05, 0.75, 0.05]
position: [-0.4, -0.4, 0.25]
}
object leg4 {
geometry: "cylinder"
scale: [0.05, 0.75, 0.05]
position: [0.4, -0.4, 0.25]
}
}Child object positions are relative to the parent.
Using object vs composition
compositionis typically used for top-level scene definitions or complex modular components.objectis used for individual 3D entities within a composition.
composition scene {
object myCube { geometry: "cube" }
}Complete Example
Here's a complete example combining all concepts:
composition scene {
// Floor
object ground {
geometry: "plane"
width: 20
height: 20
rotation: [-90, 0, 0]
material: {
color: "#3a3a3a"
roughness: 0.9
}
}
// Interactive cube
object interactiveCube {
@grabbable
@physics { mass: 1.0 }
geometry: "cube"
position: [0, 1.5, -2]
scale: 0.3
material: {
color: "#ff6600"
metalness: 0.3
roughness: 0.5
}
onGrab: {
this.material.emissive = "#ff6600"
}
onRelease: {
this.material.emissive = "#000000"
}
}
// Light source
object sun {
geometry: "sphere"
scale: 0.1
position: [5, 10, 5]
material: {
color: "#ffffcc"
emissive: "#ffffcc"
emissiveIntensity: 1.0
}
}
}Quiz
Test your understanding:
- What's the difference between
geometry: "cube"andgeometry: "model/box.glb"? - If a child object has position
[1, 0, 0]and parent has[5, 0, 0], where is the child in world space? - How would you make an object 50% transparent?
- What property makes an object glow?
- Can compositions contain other objects?
Answers
"cube"is a built-in primitive,"model/box.glb"loads an external 3D model file- The child is at
[6, 0, 0]- positions are relative to parent opacity: 0.5emissiveandemissiveIntensityin the material- Yes, through nesting
Hands-on Exercise
Create a simple table with a vase on top:
// Create your solution here
composition furnitureSet {
object table {
// Table top and legs
object vase {
// Vase on the table
}
}
}Estimated time: 25 minutes
Difficulty: ⭐ Beginner
Next: Lesson 1.5 - Properties Deep Dive