This guide builds one thing over five short pages: a block floating above a floor, which grows into a garden lantern that lights up at dusk. Each page changes the script from the page before and shows what the change does. This first page is the smallest whole world: one shape, one surface, one light, a floor, and a place to stand.
The whole world
part hello // the world
part materials
part slate: plain(srgb(70, 110, 160)) // a matte blue
part stone: plain(srgb(140, 140, 135)) // a matte gray
part floor: box(x: -5 ..= 5, y: -0.1 ..= 0, z: -5 ..= 5), material: materials.stone, at: (0, 0, 0)
solid(self, derived) // you can stand on it
part block: box(x: -0.3 ..= 0.3, y: 0.4 ..= 1, z: -0.3 ..= 0.3), material: materials.slate,
at: (0, 0, 0), rotation: rotation(30 deg)
part sun: sunLight(direction: (0.4, 1, 0.3), color: color(1, 0.96, 0.9), lux: 80000 lux,
castsShadow: true)
part arrivals
part start, at: (0, 0, 3), facing: (0, 0, -1) // where you stand, looking at the block
That is all of it. The rest of this page goes through it a line at a time.
A world is a tree of parts
Every named thing in a world is a part: the block, the floor, the sun, even the place where you arrive. A part can hold other parts, and the indentation shows which holds which: slate and stone are inside materials, and everything is inside hello. The part at the top is the world itself.
A part inside another is reached by its part path, the names from the outside in, joined by dots: materials.slate is the slate inside the materials. A part holding others can be a thing with a place in the world, like a lantern holding its glass, or just a container for things that belong together, like materials here.
A shape is a recipe, not a mesh
A graphics card draws a solid object as a mesh: a surface made of triangles. A modeling program would save the block as its triangles. The line for block holds no triangles at all. It says how to make them: a box from here to there. This is procedural generation: the world describes the steps that make each surface, and the browser runs those steps to hydrate the description into the mesh it draws.
box(x: -0.3 ..= 0.3, y: 0.4 ..= 1, z: -0.3 ..= 0.3)
Each range says where the box starts and ends along one direction. The numbers are meters. x runs left to right, y runs up, and z runs toward you. So this is a 60 cm cube whose underside is 40 cm above the floor. at: (0, 0, 0) places the part at the middle of the world; the box's own numbers say where the cube sits from there. Nothing holds it up, and nothing needs to: a shape stays where it is put unless something moves it. rotation: rotation(30 deg) turns it 30 degrees about the upright axis, so you see two of its sides rather than one flat face.
A box is a recipe with a single step. Later pages add more steps until the block becomes a lantern. The recipe stays small however detailed the shape gets, and the browser can hydrate it finer for something close to you and coarser for something far away.
The floor is a box too, 10 m square and 10 cm thick, with its top at height 0. The line under it, solid(self, derived), tells the physics engine that walkers cannot pass through it, and that its solid outline is its own shape. Without that line you would fall through the floor.
A material says how a surface takes light
A shape gives only the form. Its material says what the surface is like when light falls on it: its color, and whether it is matte or shiny. plain(...) is the simplest material, a matte surface with no highlight. The color srgb(70, 110, 160) uses the 0 to 255 numbers a paint program shows. Each shaped part names its material with material:, by its part path.
The materials are held in their own part so that several shapes can share one. Change slate, and everything painted with it changes.
A light, so there is something to see
With no light the world would be black. sunLight is light that arrives from a direction rather than from a place, as sunlight does: it falls on everything at the same angle however far you walk. direction: (0.4, 1, 0.3) points toward the sun: mostly up, a little to the right and a little toward you, so the sun is high behind your right shoulder. lux is how much light falls on a surface facing the sun; 80,000 is a bright clear day. castsShadow: true asks for the light's shadows, so the block's shadow falls on the floor beneath it.
Where you arrive
A world says where a person entering it may arrive. Its arrivals part holds those places, and here there is one, start, on the floor 3 m in front of the block. An arrival gives a place and a facing, the direction you look when you arrive: (0, 0, -1) is away from you along z, straight at the block. You arrive as a body standing there, and you see the world from that body's eyes.
What happens when the world opens
When the browser opens this file it does two things in order. First it builds: it runs each shape's recipe once to hydrate the meshes, and sets up the materials, the light and the solid floor. Then it starts the world, and you are placed at the arrival. Nothing in this world changes, so once it has started there is nothing more to run. Later pages add things that move and respond.
Try changing it
- Change the slate's three numbers to repaint the block.
- Make the cube larger by widening its ranges, or lift it higher by raising both
ynumbers. - Change
30 degand the block turns to face you differently. - Move the sun:
(0, 1, 0)is straight overhead and puts the shadow directly under the block.
What you have now
Four ideas, which the rest of the guide builds on. A world is a tree of parts. A shape is a recipe that the browser hydrates into a mesh. A material says how a surface takes light. A light makes the world visible. The next page brings the block to life: it turns, it responds when you come near or click it, and it gets a surface that looks like wood or metal.
Still open
- What is drawn behind everything when a world has no sky. There is no background color in the design; the sky arrives on a later page.