Every solid thing a world shows (a lantern, a wall, a boat) is drawn from a mesh: a surface of triangles a graphics card can draw. (Lights, sounds and on-screen panels are drawn in other ways; this page is only about surfaces.) A 3-D modeling program usually saves each surface as its finished mesh. A ConeScript world does not ship the mesh. It describes how to make it: a procedural generation pipeline, a series of steps such as "draw the post's cross-section, then turn it on a lathe". The visitor's 3-D browser downloads that description and runs the pipeline, which hydrates it into the mesh that is drawn.
This page follows one object, a garden lantern, from its first block to its finished form, and introduces each kind of step at the point the lantern needs it. The lantern uses most of the tools; the few it has no need for (rounding edges, for one) are shown on other small objects along the way. By the end you will know the four things a pipeline does (start from a solid, shape from paths, combine pieces, refine the surface) and which tool to reach for at each. Every tool's exact options are in the Shape tools appendix, which this page links to rather than repeats.
Why a recipe instead of a mesh
A mesh lists every point of every triangle; the lantern's recipe is a few dozen numbers. Sending the recipe has three payoffs:
- It is small. A world arrives quickly, however detailed its objects.
- It hydrates at any level of detail. The same recipe can make a fine mesh for a lantern at your feet and a coarse one for a lantern across the lawn.
- It stays editable. Change one number (the roof a little steeper) and the mesh is made again. Nothing is lost to a frozen export.
Every machine runs the same recipe and gets exactly the same mesh, so every visitor sees the same lantern.
The first steps: a ready-made solid
The simplest pipeline is a single step that makes a ready-made solid: a box, a cylinder, a sphere or a cone. The lantern's head sits on a plinth, a flat block 14 cm square:
box(x: -0.07 ..= 0.07, y: 0.24 ..= 0.26, z: -0.07 ..= 0.07) // 14 cm square, 2 cm thick
Sizes are in meters, and y is up. A range such as 0.24 ..= 0.26 says where the box starts and ends on that axis, so this one sits 24 cm above the ground. The four corner posts of the head are boxes too, tall and thin. A surprising amount of any world starts this way.
But most things aren't boxes: start from a path
The lantern stands on a stake: a thin round post that tapers to a point where it goes into the ground. No box makes that. What an artist would do is draw the post's side view, half of it, and spin it round. ConeScript does the same.
The half side view is a profile path: a line of points drawn flat, like a curve on paper. Each point says how far out from the middle the post is, and at what height:
let stake = [(0, -0.22), (0.008, -0.20), (0.018, -0.12), (0.018, 0.244), (0, 0.244)]
// (out from the middle, height): a point in the ground, a 1.8 cm post, a flat top
lathe(profile: stake, steps: 32) // spun round in 32 steps
The lathe turns the profile round the vertical axis, as wood is turned. Posts, vases, bulbs and balloons are all made this way.
A profile path can do three other things, each for a different kind of form:
- Extrude it: push a flat shape straight out to a depth. A rounded rectangle extruded 3 cm becomes a tabletop; the outline of a letter becomes a sign.
- Sweep it along a space path: a space path is a line through 3-D space, like a curve drawn in the air. Sweep a small circle along one and you get a rail, a rope or a handle; sweep an ellipse that shrinks as it goes and you get a horn.
- Loft through several profiles: place a few different cross-sections along a space path, and the loft stretches a skin through them, as a boat's hull is built through its sections.
The lantern's roof is a loft. It is hipped: 19 cm square at the eaves, it rises gently, then more steeply, to a top 10.4 cm square, all in 5 cm of height. Three squares at three heights describe it:
loftAlong(profiles: [profilePath.rectangle(width: 0.19, height: 0.19), // the eaves
profilePath.rectangle(width: 0.14, height: 0.14), // where the pitch changes
profilePath.rectangle(width: 0.104, height: 0.104)], // the top
path: spacePath.line(from: (0, 0.388, 0), to: (0, 0.438, 0)), // 5 cm straight up
stations: [0, 0.28, 1], // where each square sits along the path
caps: false) // open underneath: it sits on the fascia
The stations place the squares: the first at the bottom, the middle one 28% of the way up, the last at the top. Putting the middle square low makes the first band shallow and the second steep.
One piece is rarely the object: combine them
The lantern now has a stake, a plinth, posts and a roof, each made separately and each sitting where its numbers put it. Combining tools gather them into one shape, copy them, and cut them.
- Join puts pieces together as one shape:
join([plinth, posts, roof]). - Copy repeats a piece. The lantern's head has four identical sides of rails and arches, so one side is built and copied four ways round:
arrayRadial(side, count: 4). A fence repeats a post along a line witharrayLinear. - Move, turn and scale put a piece where it belongs. The whole head is scaled by one number, its
size, so a smaller lantern is the same recipe at size 0.8. - Cut one piece out of another (
difference): a box cut out of a wall makes a window opening. - Mirror builds one half and reflects it, for anything symmetrical.
Each piece stays in its own material: the lantern's glass, its bulb and its bronze are separate parts, each drawn in its own material. A shape is one surface in one material, so an object of several materials is several shapes.
It looks machine-made: refine the surface
Pieces made of boxes and lathes have perfectly sharp edges and perfectly flat faces, which real things rarely do. The last group of tools works on the surface of a shape already made. Most of them ask which part of the surface to change, and you say it by description rather than by numbering faces: "the edges sharper than 30 degrees", "the faces facing up". That description is a selection.
- Bevel rounds chosen edges. A tabletop with its hard edges softened:
bevel(top, edges: sharperThan(30 deg), width: 4 mm, segments: 3)
- Inset shrinks chosen faces inside a border: a window frame and its recess. Extrude faces pushes chosen faces out: a chimney from a roof.
- Subdivide smooths a coarse shape into a fine one, as a subdivision surface does in any modeling program.
- Bend, twist and taper reshape a whole piece; displace pushes the surface in and out for detail, such as the ribs on a horn.
The lantern is crisp metalwork, so it keeps its sharp edges and skips this step. A stone, a cushion or a carved handle would not.
Then hand it on
A finished shape still needs to know how a texture wraps it. Each tool leaves sensible texture coordinates as it goes: a lathe wraps round and up the profile, a box wraps each face. The uv tools replace them where you want something else. What the surface is made of is the next subject: Materials and Textures.
The whole lantern
Put together, the lantern's pipeline is the four steps in order: ready-made boxes for the plinth and posts; a lathe for the stake and a loft for the roof; join and copy to assemble the head; no refining, because it is metal. The complete recipe, with every number from the island, is on The lanterns.
Beyond sculpting
Some forms are better made by a specialist than by sculpting: a tree grown from a seed, a rock, a person's body from measurements, cloth draped over it, hair, or grass across a meadow. Each has its own package, which takes a few settings and returns a finished form. They are listed in the Shape tools appendix and described on the pages for Generators and Fitted and grown.
Where to look things up
- Shape tools appendix: every tool, its exact options, units and defaults.
- Construction pipelines: how a pipeline is written as a function, and when it is hydrated.
- The lanterns: the full example.
Narrative draft, 20 Oct 2026, beside the current Sculpting page for comparison. It uses proposed names: profilePath for a flat path (today outline), spacePath and path: for a path through space (today spine). A part's address (a.b) would be its part path.
← Composing the tools | Contents | Generators and scattering →