409 lines
21 KiB
Markdown
409 lines
21 KiB
Markdown
# Building geometry
|
||
|
||
Everything the llama walks on, bumps into or falls through is *geometry*. In the editor you build
|
||
it in two ways:
|
||
|
||
* **Brushes** – editor shapes such as blocks, platforms, ramps, stairs, walls, water and death
|
||
planes. You draw them with the **Brush** tool, resize them with handles and turn them freely.
|
||
When the level is built, every brush is cut into the engine's tiles automatically.
|
||
* **Tiles** – the placed models of the base level's tile set, exactly as the original levels are
|
||
made. The **Tiles** tool paints them onto grid cells.
|
||
|
||
Collision is part of both: the **Collision** tool shows and changes what the llama can stand on,
|
||
where it dies and where the level exit fires.
|
||
|
||

|
||
|
||
## How the engine stores geometry
|
||
|
||
A few engine facts explain most of what follows:
|
||
|
||
* The level is a grid of **cells** (1 cell = one grid square, 4096 game units). The llama is
|
||
about 0.6 cells tall.
|
||
* Geometry is made of **tiles**: a tile is a model placed in one cell, turned about the vertical
|
||
axis. A tile cannot be scaled or mirrored and its collision must stay close to its cell.
|
||
* A tile model may have at most **8000 vertices**.
|
||
* Every collision polygon carries a **material** number. 0 is normal ground, **16** is the exit
|
||
floor the level door needs, **30** is "no floor" (the llama falls and loses a life).
|
||
* Collision is looked up per cell, so geometry outside the level grid has no effect.
|
||
|
||
Brushes hide most of this: they can have any size, position and rotation, and the build splits
|
||
them into 1×1-cell tiles with matching collision for you.
|
||
|
||
## Brush tool (B)
|
||
|
||
Start it with the toolbar button, the key **B** or **Geometry → Brush tool**. The options bar
|
||
shows one button per primitive plus **Height**, **Drag height** and **Work plane**; the
|
||
Inspector shows the same primitives with names (section **Draw**) and the options of the chosen
|
||
primitive below them.
|
||
|
||
### Drawing a brush
|
||
|
||
1. Choose a primitive.
|
||
2. Drag in the viewport. Most primitives start with a **footprint**: press on the ground (or on
|
||
top of other geometry), drag the rectangle and release.
|
||
3. For primitives with a height, now move the mouse **up or down** – the preview grows – and
|
||
**click** to confirm. **Enter** uses the value of the **Height** field instead, **Esc**
|
||
cancels.
|
||
|
||
The new brush is selected and shows its handles. The status bar shows the size while you draw.
|
||
|
||
| Option (options bar) | Meaning |
|
||
|---|---|
|
||
| **Height** | height used for **Enter** and for a click without dragging |
|
||
| **Drag height** | after the footprint, the mouse movement sets the height; off = the **Height** field is used directly |
|
||
| **Work plane** + value | draw on a horizontal plane at this height instead of on the surface under the cursor; the grid moves to that height |
|
||
|
||
Footprints snap to the move step of the snapping settings; hold **Ctrl** while dragging to
|
||
toggle snapping for this drag. **Shift+click** selects an existing brush without drawing.
|
||
|
||
> **Tip:** Drawing on the *surface under the cursor* is the fastest way to stack things: start a
|
||
> drag on top of a block and the new brush stands on it.
|
||
|
||
### Primitives
|
||
|
||
| Primitive | How to draw | Notes |
|
||
|---|---|---|
|
||
| **Block** | footprint, then height | solid box with top, sides and optional bottom |
|
||
| **Platform** | footprint, then the height of the top | floating slab with an edge row, bottom and **Thickness** |
|
||
| **Floor** | footprint only | flat floor, top only |
|
||
| **Ramp** | footprint, then the height of the high end | rises in the main drag direction |
|
||
| **Stairs** | footprint, then the top height | rises in the drag direction; **Steps**, **Walkable (invisible slope)** |
|
||
| **Pillar** | click for the default size or drag its size, then height | square column |
|
||
| **Round** | drag the diameter, then height | cylinder: round platform or column, **Segments** 3–64 |
|
||
| **Wall** | drag along the wall in any direction, then height | a turned block when diagonal; snapped to the angle step; **Thickness** |
|
||
| **Fence** | click the corner points, double-click or **Enter** finishes | posts and rails along a polyline |
|
||
| **Tree** | click | block tree: trunk and two crown cubes |
|
||
| **Water** | footprint only | water surface without collision, with a death plane just above it |
|
||
| **Death plane** | footprint only | invisible no-floor plane (material 30) – falling onto it kills |
|
||
| **Invisible wall** | drag along its length, then height | collision only, nothing is drawn in the game |
|
||
| **Invisible block** | footprint, then height | invisible collision volume: floor, ceiling or blocker |
|
||
|
||
> **Note:** Stairs need **Walkable (invisible slope)**: the engine has no step-up logic, so the
|
||
> llama walks up an invisible slope that lies over the steps. Stairs start at the floor in front
|
||
> of the first step (*Start height (floor in front)*).
|
||
|
||
### Primitive options
|
||
|
||
The options section in the Inspector changes with the primitive. Textures are chosen with a
|
||
swatch button: click it for a searchable grid of all textures of the level (names are the
|
||
village texture names; `#n` is texture number *n* of the base level, see
|
||
[Textures](08-textures.md)). **none** leaves that part out.
|
||
|
||
| Option | Primitives | Meaning |
|
||
|---|---|---|
|
||
| **Top** / **Texture** | all textured ones | texture of the top (Floor and Water: the only texture) |
|
||
| **Sides** | Block, Platform, Ramp, Stairs, Pillar, Round, Wall | side texture |
|
||
| **Top edge** | same | texture of the top row of the sides (e.g. a grass edge), or none |
|
||
| **Bottom** | same | bottom texture, or none (no bottom faces) |
|
||
| **Thickness** | Platform, Wall, Invisible wall | slab or wall thickness in cells |
|
||
| **Steps** | Stairs | number of steps (1–64) |
|
||
| **Walkable (invisible slope)** | Stairs | adds the invisible slope (see above) |
|
||
| **Segments** | Round | number of sides of the cylinder |
|
||
| **Collision** | Block, Round, Wall, Floor, Ramp | off = decoration only, the llama walks through |
|
||
| **Solid sides** | Block, Round, Wall | off = the sides have no collision, so the llama can walk up onto low plinths |
|
||
| **Material** | Block, Platform, Round, Wall, Floor, invisible ones | collision material of the brush |
|
||
|
||
### Handles: resizing
|
||
|
||
A selected brush shows small cubes on its faces – **orange** for the sides, **green** for top and
|
||
bottom. Drag one to resize: the opposite face stays where it is, also for turned brushes. The
|
||
status bar shows the new size.
|
||
|
||

|
||
|
||
### Keys while the Brush tool is active
|
||
|
||
| Key | Action |
|
||
|---|---|
|
||
| **[** / **]** | turn the selection by 90° left / right |
|
||
| **Page Up** / **Page Down** | raise / lower the selection by the snap step |
|
||
| **Enter** | use the **Height** field (height step) or finish a fence |
|
||
| **Esc** | cancel the current drawing |
|
||
| **Ctrl** (held) | toggle snapping for this drag |
|
||
| **Shift+click** | select instead of drawing |
|
||
|
||
## Brush properties in the Inspector
|
||
|
||
Selecting a single brush shows two Inspector sections: **Brush shape** (below) and the brush's
|
||
own parameters (all of them, as numbers and texture fields). Every parameter can be typed in;
|
||
number fields accept arithmetic such as `2+0.5`.
|
||
|
||
Common parameters:
|
||
|
||
| Parameter | Meaning |
|
||
|---|---|
|
||
| **X0 / Z0 / X1 / Z1** | footprint corners in cells (x east, z = grid row, growing south) |
|
||
| **Bottom / Top**, **Height** | heights in cells |
|
||
| **Top texture**, **Side texture**, **Top row of the sides**, **Bottom texture** | textures (name, `#n`, a flat colour name or `rgbRRGGBB`) |
|
||
| **Sides (n, e, s, w)** | which sides of a block exist |
|
||
| **Collision**, **Side collision**, **Collision material** | collision of the whole brush |
|
||
| **Casts shadows** | the block shadows other geometry when lighting is baked |
|
||
| **Texture rotation (0-3, −1 random)** | turns the texture on every face; −1 picks a random turn per tile |
|
||
| **Tile size** | size of the generated tiles (floors, ramps, water) |
|
||
| **Tint (r, g, b)** | colour multiplier for the brush's vertex colours |
|
||
| **Rises towards** | direction of ramps and stairs: `+x`, `-x`, `+z`, `-z` |
|
||
| **Base height** | ramps and stairs: how far the closed sides reach down (empty = 0.5 below) |
|
||
| **Post size**, **Post spacing**, **Post texture**, **Rail texture** | fences |
|
||
| **Trunk height**, **Crown size**, **Trunk size (0 = auto)** | trees |
|
||
|
||
### Brush shape section
|
||
|
||

|
||
|
||
* The first line shows the kind and size, e.g. **Ramp · 6.25 × 2 × 3.5 cells**.
|
||
* **Rotation°** – three fields for the rotation about x (east), y (up) and z (south) in degrees,
|
||
applied in the order x·y·z. The bottom centre of the brush stays in place.
|
||
* **Left 90°** / **Right 90°** – quarter turns about the vertical axis (**[** / **]**).
|
||
* **Mirror X** / **Mirror Z** – mirror east ↔ west or north ↔ south.
|
||
* **Visible (off = invisible collision volume)** – hides the brush in the game but keeps its
|
||
collision. This is how invisible walls and blocks are made.
|
||
* **Faces (collision and material)** – a table with one row per face: **top**, **bottom**,
|
||
**north**, **east**, **south**, **west**. **Collision** switches the face's collision on or
|
||
off, **Material** gives it its own collision material (for example only the top face 16).
|
||
|
||
Water and death planes are laid out per grid cell: they can be resized and moved but only turned
|
||
by 90°. A collider (a free invisible polygon) is edited through its corner list.
|
||
|
||
> **Note:** Brushes are baked into tiles when the level is built, so any rotation and scale works.
|
||
> Tiles placed with the Tiles tool cannot do that – see [Tiles tool](#tiles-tool).
|
||
|
||
## Rotating, scaling and mirroring
|
||
|
||
The general transform tools are described in [Selection and transforming](05-selection.md).
|
||
On brushes they can do more than on tiles and objects:
|
||
|
||
* **Rotate (E)**: the green ring turns everything about the vertical axis. The **red** and
|
||
**blue** rings turn **brushes freely in 3D** (imported meshes about their origin). Tiles and
|
||
objects only turn about the vertical axis in the engine; the status bar says so and leaves
|
||
them alone.
|
||
* **Scale (R)** on a brush changes the primitive's own sizes – width, depth, height, thickness,
|
||
radius, crown … ; meshes stretch per axis. The bottom centre stays.
|
||
* **Quarter turns and mirrors** of unturned brushes change their parameters instead of adding a
|
||
rotation, so textures stay aligned to the grid and ramp directions, sides and per-face settings
|
||
follow.
|
||
|
||
**Geometry** menu commands for the selection:
|
||
|
||
| Command | Key | What it does |
|
||
|---|---|---|
|
||
| **Turn left 90°** / **Turn right 90°** | **Ctrl+[** / **Ctrl+]** | quarter turn about the vertical axis |
|
||
| **Mirror X (east ↔ west)** / **Mirror Z (north ↔ south)** | | mirror about the centre of the selection; tiles and objects are moved and turned (tile models themselves cannot be mirrored) |
|
||
| **Array duplicate…** | **Ctrl+Shift+D** | see below |
|
||
| **Align ▸** | | see below |
|
||
|
||
### Array duplicate
|
||
|
||
**Geometry → Array duplicate…** (**Ctrl+Shift+D**) makes several copies in one step – a row of
|
||
platforms, a staircase of blocks, a ring of pillars.
|
||
|
||
| Field | Meaning |
|
||
|---|---|
|
||
| **Copies** | number of new copies |
|
||
| **Offset X (cells)**, **Offset Y**, **Offset Z** | offset of each copy from the previous one |
|
||
| **Turn per copy (°)** | each copy is turned once more than the previous one |
|
||
| **Turn about the selection centre (circular array)** | turn around the centre of the selection instead of each item's own position: arranges copies on a circle |
|
||
|
||
Objects in the selection get a copy of their waypoint chain. The whole array is one undo step.
|
||
|
||
### Align and distribute
|
||
|
||
**Geometry → Align** lines up the selection with the **last selected** item (select two or more):
|
||
|
||
* **Align West (min X)**, **Align Centre X**, **Align East (max X)**
|
||
* **Align Bottom**, **Align Middle Y**, **Align Top**
|
||
* **Align North (min Z)**, **Align Centre Z**, **Align South (max Z)**
|
||
* **Distribute along X** / **Distribute along Z** – spaces three or more items evenly between the
|
||
outermost two.
|
||
|
||

|
||
|
||
### Grid and snapping
|
||
|
||
The options bar holds the quick settings: **Snap** (**G**), the move step (1 … 1/16 cell) and
|
||
the angle step (90° … 1°). **Geometry → Grid & snapping…** sets any value:
|
||
|
||
| Field | Meaning |
|
||
|---|---|
|
||
| **Snapping on** | same as **G**; hold **Ctrl** while dragging to invert |
|
||
| **Move step (cells)** | any step from 1/64 to 16 cells |
|
||
| **Angle step (°)** | any angle step |
|
||
| **Scale step** | step of the Scale tool |
|
||
| **Show the grid** | grid display on or off |
|
||
|
||
The engine places tiles on whole cells; brushes and objects can sit anywhere.
|
||
|
||
## Tiles tool
|
||
|
||
The **Tiles** tool paints tile models of the base level onto grid cells – the way the original
|
||
levels are built. Start it with **T**, from the toolbar or **Geometry → Tiles tool**.
|
||
|
||

|
||
|
||
### Tile palette
|
||
|
||
The Inspector shows the **Tile palette**: every tile model of the level with a thumbnail, its
|
||
vertex count and how many tiles use it. **Filter (model number)** narrows the list, **Only models
|
||
used in the level** hides unused ones. Click a model to make it the current one, or
|
||
**Shift+click** a tile in the viewport to pick it.
|
||
|
||
### Modes and options
|
||
|
||
| Mode | What a click (or drag) does |
|
||
|---|---|
|
||
| **Paint** | puts the palette model into the cell under the cursor |
|
||
| **Pick** | takes the model, height and rotation of the clicked tile (also **Shift+click** in any mode) |
|
||
| **Erase** | deletes the clicked tiles |
|
||
| **Raise / lower** | raises a tile by the height step, **Shift+click** lowers |
|
||
| **Swap model** | replaces the model of the clicked tile with the palette model |
|
||
|
||
| Option | Meaning |
|
||
|---|---|
|
||
| **On surface** | paint at the height of the tile or ground under the cursor; off = the fixed **Height** |
|
||
| **Height** | height of painted tiles (**Page Up** / **Page Down**) |
|
||
| **Rotation** | 0°, 90°, 180° or 270° (**[** / **]**) |
|
||
| **Step** | height step for raising, lowering and Page Up/Down |
|
||
|
||
Painting onto a tile at the same height **swaps its model** instead of stacking a second tile.
|
||
New tiles copy the vertex colours of an existing tile with the same model.
|
||
|
||
> **Tip:** Prefer swapping, moving or hiding original tiles over erasing them. Object scripts can
|
||
> address tiles by their number, and erasing a tile shifts the numbers of all later tiles. The
|
||
> status bar warns you when you erase an original tile.
|
||
|
||
### Tile section in the Inspector
|
||
|
||
Selecting tiles shows the **Tile** section:
|
||
|
||
* **Left 90°** / **Right 90°**, **Up** / **Down** (by the snap step).
|
||
* **Use palette model** – gives the selected tiles the Tiles tool's palette model.
|
||
* A reminder that tiles only turn about the vertical axis and cannot be scaled or mirrored (the
|
||
level stores one position and one angle per tile). For free shapes use brushes.
|
||
|
||
### Tile swaps (doors and bridges)
|
||
|
||
Some levels let object scripts switch a tile to another model – an opening door, a bridge that
|
||
appears. This is a **tile swap**. The Tile section shows the swap of the selected tile:
|
||
|
||
* **Swap entry in cell …** with the current and the alternative model,
|
||
* **Alternative = palette** – sets the alternative model from the Tiles tool's palette,
|
||
* **Remove swap** – deletes the swap entry,
|
||
* **Add swap (door / bridge)** – gives the tile an alternative model.
|
||
|
||
The layer **Tile swap alternatives** (View → Layers) draws alternative models in cyan. Tile
|
||
swaps need a base level with the feature flag WFPC 0x10000; on other bases the section says so.
|
||
|
||
## Collision tool
|
||
|
||
The **Collision** tool shows and paints collision materials. Start it from the toolbar or
|
||
**Geometry → Collision tool**. It switches the collision layer on: every collision polygon is
|
||
drawn in the colour of its material.
|
||
|
||

|
||
|
||
Hover over geometry: the polygon (on a brush: the whole face) under the cursor is highlighted and
|
||
the status bar names it and its material. Then:
|
||
|
||
| Mode | Action |
|
||
|---|---|
|
||
| **Paint material** | click or drag over polygons to give them the current material; **Shift+click** picks the material of a polygon |
|
||
| **Toggle collision** | click a brush face to switch its collision on or off |
|
||
|
||
The Inspector shows the list **Collision materials**; **Material** in the options bar does the
|
||
same, and **Other…** accepts any number from 0 to 255.
|
||
|
||
| Material | Name | Effect |
|
||
|---|---|---|
|
||
| **0** | Normal | ordinary ground and walls |
|
||
| **16** | Exit floor (LevelDoor) | the level door only fires while the llama stands on it in the door's cell |
|
||
| **30** | No floor / death | the llama falls through and loses a life |
|
||
| **17** | Selective: only flagged objects | only affects some objects |
|
||
| **18** | Selective: not flagged objects | only affects the other objects |
|
||
| 1–15, 20, 26–28, 33, 255 | special, meaning unknown | read by object scripts of the original levels |
|
||
|
||
**Shared models**: original tile models are often used by many tiles. Choose **Shared models:
|
||
change all tiles** (paint the model, every tile using it changes) or **Shared models: copy for
|
||
this tile** (the painted tile gets its own copy of the model first).
|
||
|
||
Brushes have one material per face class (top, sides, bottom); tile models are painted per
|
||
polygon. Tile collision cannot be switched off – paint it 30 or hide the tile instead.
|
||
|
||
The layer **Invisible collision volumes** draws invisible walls, invisible blocks and colliders
|
||
translucent red so you can see them while editing.
|
||
|
||
## Special floors
|
||
|
||
### Exit floor
|
||
|
||
The level exit is an object, the **LevelDoor**, but it only fires while the llama stands on
|
||
collision material **16** in the door's own cell. The quick setup **Exit** in the Objects panel
|
||
places both at once – the door and a 1×1 floor with material 16 (see
|
||
[Objects](09-objects.md)). To make an existing surface the exit floor, paint its top face 16 with
|
||
the Collision tool or set the face's **Material** in the Brush shape section.
|
||
|
||
### Death floors and the death plane
|
||
|
||
Material **30** means "no floor": the llama falls through and loses a life. Use it for pits,
|
||
lava and the ground under a parkour:
|
||
|
||
* the **Death plane** primitive – an invisible plane of material 30 in every cell of its area
|
||
that is not completely covered by floor,
|
||
* a **Floor** or **Block** with material 30 (a visible deadly floor),
|
||
* **Water** – carries its own death plane just above the water surface.
|
||
|
||
**Geometry → Death plane height…** moves all death planes at once: death-plane brushes and the
|
||
original level's material-30 tiles. It shows how many of each exist; **Add a death plane over the
|
||
whole grid** creates one if there is none. The same height is in
|
||
[Level settings](14-level-settings.md).
|
||
|
||

|
||
|
||
### Invisible walls and blocks
|
||
|
||
**Invisible wall** and **Invisible block** draw boxes that have collision but are not drawn in the
|
||
game – to keep the llama on a path or to give a decoration a simple collision. Any brush becomes
|
||
invisible with **Visible** off in the Brush shape section.
|
||
|
||

|
||
|
||
### Water
|
||
|
||
The **Water** primitive draws a water surface without collision (the llama sinks) and, by
|
||
default, a death plane just above it. Its parameters: **Water height**, **Texture**, **Death
|
||
plane** (`none`, `whole` = under the whole water, `area` = only in **Death plane area**) and
|
||
**Tile size**.
|
||
|
||
## Geometry checks
|
||
|
||
**Level → Check for problems** and every build run these checks (see
|
||
[Building and play-testing](15-build-play.md)):
|
||
|
||
| Problem | What to do |
|
||
|---|---|
|
||
| a tile lies outside the grid | move it in or enlarge the grid in Level settings |
|
||
| a tile model (also one generated from a brush or mesh) has more than **8000 vertices** | simplify or split the shape |
|
||
| two identical tiles overlap exactly (same model, cell, height and rotation) | delete one – it causes flickering and double collision |
|
||
| **no floor collision under the player start** | the llama would fall at once – put floor under it |
|
||
| the player start is far above the floor | lower it |
|
||
| **no exit floor (collision material 16) in the LevelDoor's cell** | add or paint the exit floor |
|
||
| a small **gap** (under 0.2 cells) between neighbouring floors at the same height | close it, the llama can get stuck or fall |
|
||
| brush warnings | messages of the brush compiler |
|
||
|
||
Double-click a problem to select the item.
|
||
|
||

|
||
|
||
## Engine limits
|
||
|
||
> **Engine limit:** at most 8000 vertices per tile model. Brushes are split into 1×1-cell tiles, so
|
||
> only very dense meshes or many brushes overlapping one cell reach it.
|
||
|
||
* Tiles only turn about the vertical axis and cannot be scaled or mirrored; brushes can.
|
||
* Collision materials of brushes are per face class (top, bottom, each side), of tile models per
|
||
polygon.
|
||
* Water and death planes are cell based: they can be moved, resized and turned by 90° only.
|
||
* The gap check looks only at unturned block, platform and floor tops.
|
||
* Geometry outside the level grid has no collision.
|
||
|
||

|