Wax Template Guide

A wax template is a recipe that turns a short form into several map lines at once. The built-in ones are Table, Box, Chair, Stairs, Shelf, Bed, Arch and Pit. You can write your own. Yours appear in the Wax Template Builder (Shift+B) after the built-in ones, and they open as a form just like they do.

Where templates live
Put a plain text file ending in .gcw in your Stash folder, the same folder your saved reverb and occlusion presets are kept in. The file name is the template's name unless you set one inside. The list is rescanned every time you open the Wax Template Builder, so you can edit a file and reopen the builder without restarting the game.

Your first template
Save this as Pillar.gcw.

template name="Pillar";
ask id=x; kind=coord; axis=x;
ask id=y; kind=coord; axis=y;
ask id=z; kind=coord; axis=z;
ask id=height; kind=number; label="Height"; default=5; min=1;
ask id=material; kind=wall; label="Material"; default=stone;
wall minx={x}; maxx={x}; miny={y}; maxy={y}; minz={z}; maxz={z+height-1}; type={material};

Open the Wax Template Builder, pick Pillar, and you get a form with X, Y and Z boxes, a Height box that starts at 5, and a Material box with a Browse button. When you press OK, the one wall line at the bottom is sent to the map with every {name} replaced by what you entered.

The three kinds of line
Every non-blank line in a template file is one of these.
1. A comment. It starts with // and is ignored.
2. A statement. It starts with one of the keywords template, ask, set, repeat, if, else, end or say.
3. A map line. Anything else is a normal map line, written exactly as you would in the line editor, that the template will build.

Map lines can use any element the map format supports, not only wall and platform. Put {something} anywhere in a map line to fill in a value.

The template line (optional)
template name="Pillar"; maps=any; flags=yes; description="A square column";

name is what shows in the list. If you leave it out, the file name is used.
maps says which maps the template is for. any (the default) is for both, 3d hides it on 2D maps, and 2d hides it on 3D maps. See "2D maps" below.
flags=yes (the default) adds the Wall Flag and Surface Flag boxes that the built-in templates have. Every wall line then gets the wall flag and every platform line gets the surface flag, unless the line already has its own flag=. Platforms of type air are never flagged. Use flags=no to leave the boxes out.
description is a note for yourself. It is not shown anywhere.

Questions: the ask line
Each ask line adds one box or list to the form.
ask id=height; kind=number; label="Height"; default=5; min=1; max=50;

id (required) is the name you use to refer to the answer, letters, numbers and underscores only. It is not case sensitive.
kind (required) is one of the kinds below.
label is what the form calls it. It is optional, and the id is used if you leave it out.
default is the value the box starts with. Leaving a box blank uses the default. A box with no default cannot be left blank unless you also say optional=yes.
optional=yes lets the box be blank, in which case its value is empty.

The kinds
coord is a map coordinate. It also needs axis=x, axis=y or axis=z. It can have role=min, role=max or role=point (the default), which only changes the label to Minimum X, Maximum X or just X. Coordinate boxes fill themselves in from your camera markers (hold G) exactly like the built-in templates do.
number is a whole number. It can have min= and max= limits.
text is anything you type.
wall is a wall type, with a Browse button that opens the wall browser.
platform is a platform type, with a Browse button that opens the platform browser.
yesno is a No/Yes list. Its value is 1 for yes and 0 for no. Use default=yes to start on Yes.
choice is a list. Give it options="north, south, east, west" and optionally a default that is one of them. Its value is the option's text.

Filling in values: {name} and {math}
Anything inside curly braces in a map line is worked out before the line is sent. A lone name gives back its value as is. Anything else is treated as whole number math.
{x} gives whatever was entered for x.
{z+height-1} adds and subtracts.
{width*2} multiplies. / divides and drops any remainder. % gives the remainder.
{(x+width)/2} uses brackets.
{min(a, b)}, {max(a, b)} and {abs(a)} are available.
Numbers are always whole. Names of types, like a material, can be used as they are, but cannot go in math.
A built-in value called is2d is 1 on a 2D map and 0 on a 3D map.

Working things out: set
set top=z+height;
set mid=top/2; half=width/2;

set makes a new value you can use afterwards in {braces} or in other statements. It can take several name=value pairs on one line, and they are worked out in order. Setting a name that already exists replaces it.

Doing something several times: repeat
repeat steps as i
platform minx={x}; maxx={x+width-1}; miny={y+i}; maxy={y+i}; minz={z+i}; maxz={z+i}; type={material};
end

repeat takes a count, which can be a number, a name or math, and an optional "as name". The name counts up from 0, so with a count of 5 the lines are built for i = 0, 1, 2, 3 and 4. Everything up to the matching end is repeated. A repeat can be limited to 1000 times and a template to 2000 lines, which catches typos like an extra zero.

Choosing what to build: if, else, end
if back
wall minx={x}; maxx={x+length-1}; miny={y+1}; maxy={y+1}; minz={z}; maxz={z+2}; type=wood;
else
platform minx={x}; maxx={x+length-1}; miny={y+1}; maxy={y+1}; minz={z+1}; maxz={z+1}; type=wood;
end

A condition is one of these.
if back is true for a yesno that was answered Yes, for any number other than 0, and for any text other than blank, no, false or off.
if not back is the opposite.
if direction == north compares two things. The operators are ==, !=, <, >, <= and >=. If both sides are numbers they are compared as numbers, otherwise as text. Text is not case sensitive and does not need quotes. < and > only work on numbers.
Both sides can be a name, a number or math, for example if width > 3 or if height-1 >= steps.
else is optional. Every if and every repeat must be closed with its own end. They can be nested inside each other.

Telling yourself what happened: say
say "Built {steps} steps, ending at {bottom}.";

say sets what the game announces when the template is built, in place of the usual "built" message. {braces} work the same as in map lines. If more than one say runs, the last one wins, so a general say followed by more specific ones inside if works well. If the template ends up building nothing, the say is announced and the form stays open so you can change your answers.

2D maps
A 2D map is a side view. X goes across, and Y is how high things are, with Z not used. Templates marked maps=any (the default) are written once as if for a 3D map. On a 2D map the Y axis is dropped. The Y question is not asked, the Z question is labelled Y, and every map line has its Z range turned into its Y range automatically, just like the built-in templates do for themselves.
This works well for things that stand up, like pillars, tables and shelves. It does not work for things that run along the Y axis, like a staircase that climbs northward. For those, use maps=3d to hide the template on 2D maps, or write a separate template with maps=2d.
A maps=2d template is written directly for a 2D map. It asks for coord axes x and y only, and its map lines use miny and maxy for height with minz=0; maxz=0; written by hand. Nothing is converted for it.

A fuller example: stairs with an optional railing
Save this as Railed Stairs.gcw. It only shows on 3D maps.

template name="Railed Stairs"; maps=3d;
ask id=x; kind=coord; axis=x;
ask id=y; kind=coord; axis=y;
ask id=z; kind=coord; axis=z;
ask id=width; kind=number; label="Width"; default=3; min=1;
ask id=steps; kind=number; label="Number of Steps"; default=6; min=1;
ask id=tread; kind=platform; label="Step Type"; default=wood;
ask id=rail; kind=yesno; label="Add A Railing";
ask id=rail_type; kind=wall; label="Railing Type"; default=wood;
repeat steps as i
platform minx={x}; maxx={x+width-1}; miny={y+i}; maxy={y+i}; minz={z+i}; maxz={z+i}; type={tread};
if rail
wall minx={x}; maxx={x}; miny={y+i}; maxy={y+i}; minz={z+i+1}; maxz={z+i+1}; type={rail_type};
wall minx={x+width-1}; maxx={x+width-1}; miny={y+i}; maxy={y+i}; minz={z+i+1}; maxz={z+i+1}; type={rail_type};
end
end

More examples
The documentation/wax_template_examples folder has finished templates you can copy into your Stash folder. Couch.gcw is a good one to read next. It uses minimum and maximum corners, a facing direction, and set with if to work out where the back and arms go. Stairs Down.gcw builds a staircase downward that fits as many steps as it can inside the box you mark and never goes past it, then uses say to tell you how many steps it built and where they end.

When something is wrong
A template with a mistake still shows in the list, with "(has errors)" after its name. Choosing it tells you the first problem and its line number, and how many more there are. Fix the file and reopen the builder. Problems found while building, such as a {name} that does not exist, are announced and the form stays open so you can change your answers. Nothing is sent to the map unless the whole template worked.
Common ones are a misspelled name inside braces, a missing end, and putting a type name inside math.

Quick reference
Statements: template, ask, set, repeat, if, else, end, say.
Ask settings: id, kind, label, default, min, max, options, axis, role, optional.
Template settings: name, maps, flags, description.
Kinds: coord, number, text, wall, platform, yesno, choice.
Math: + - * / % ( ) min() max() abs().
Conditions: name, not name, a == b, a != b, a < b, a > b, a <= b, a >= b.
Built-in value: is2d.
File: any name ending in .gcw, in the Stash folder.
