Wooscript Language Reference

Wooscript is a state-based language which allows you to generate procedural 3d objects. Objects are made using “rules”, and each rule can call a number of functions to change the state.

All scripts must contain a rule called main, as this is the starting point for all 3d scenes. To specify the main rule use curly braces {,} like this…

rule main {
// main rule goes here

Note that comments are supported in Wooscript and they’re a good idea to keep track of what you’re doing when building 3d objects.

General Language Syntax

There are two types in Wooscript, floating point numbers, and vectors. Floating point numbers can be specified in a number of ways. Outright numbers (0.1, 0.7, -1.3), random ranges (0.5:1.0) and alternates (0.5|1|1.5). In the case of random ranges, a value between the specified limits will be created at runtime. With alternates, the different values will be selected randomly at runtime. Simple arithmetic operators are supported (+, -, *, /) but operator precedence is not currently supported. Make sure you use brackets (,) to specify precedence manually.

Vectors can be created from floating point numbers using vec(num1, num2, num3). Vectors are used to specify positions, directions *and* colours. To modify only one value within a vector you can use vec.x, vec.y, vec.z and also vec.r, vec.g and vec.b.

All colours in Wooscript are currently specifed using r,g,b triplets, where the values are in the range 0->1. Except in the case of lightsources where colours can be >1. Colours cannot be negative.

All angles are specified in degrees, rather than radians. The reason for this is that degrees are more widely understood than radians, and despite being a mathematician myself, I’m still happier working in degrees!

Inbuilt rules

The only rules that come “out-of-the-box” are the basic solid primitives supported by Wooscript. Currently these primitives are:

box – Create a cube
sphere – Create a sphere
circle – Create a circle
cylinder – Create a cylinder
sphereLight – Create a spherical light (used as light source)

To call a rule simply enter the name of the rule in a script.


Note that primitive rules will create an object at the current position (specified by the vector pos), with the current rotation (set up using rx,ry,rz), with the current material (set up using diff, spec, power, etc.).

Basic Language constructs

Calling Rules

There are a few key language constructs that allow you to control program flow and the state of the program. To call a rule you simply enter the name of the subrule in the script.

Controlling State

This rule may then modify the global state (position, orientation, material) in a way which you would like to reset following the rule. To do this enclose the name of the rule in curly braces, limiting the “scope” of any sideeffects.

{ rulename }

Repeating Rules

You can also repeat a rule a number of times using the repeat statement.

repeat(10) { rulename }

The syntax is straightforwards and the repeat number is re-evaluated each time the enclosing statements are executed. For example repeat(v0.x) { v0.x += 1 } will execute until you reach the limit of floating point numbers to support increments. This will take a long time, NOT RECOMMENDED!

Conditional statements

Finally you can also use the if function to do conditional logic within a procedural rule. For example

if (0:1<0.5)
else if (0:1<0.5)

Will call r1 50% of the time, r2 25% of the time and r3 the rest of the time.

You can also use boolean expressions within if statements, i.e.

if (pos.y>0.0 && pos.z>1.0) r1

Controlling Recursion

If you create rules that call themselves you can limit the recursion depth by setting the recursions floating point value. This number will be rounded and decremented by one each time a function is entered, while being incremented when a function is left. The following program would create a stack of eight boxes.

rule main {
recursions = 8

rule r1 {
pos.y += 1.1

Lighting Functions

Lights are typically added to the Light Script rather than the main Scene Script. This is so that it's easy to light your main models in different lighting environments. These functions are all fairly standalone and have a variety of settings. They don't rely on the state of Wooscript, so no need to move the pos vector etc.


Creates a directional light facing in the direction, using the specified colour (non-clamped). The noise value can be used to add a small random offset to the direction, giving softer shadows. i.e. 0.01 is roughly equivalent to sunlight. The samples parameter is not current used, but I may hook it up one day...

directionalLight(direction, colour, noise, samples)


Create a light at a specific position, of a specific colour. The light value attenuates over distance using the 1/r2 rule, so lights in the middle of the scene will have dramatic fall-off.

pointLight(position, colour)


This is very similar to ambient occlusion as seen in some products. Light rays are randomly sent into the scene and light accumulates over the scene. The quality of the light will improve as the final renderer continues to sample the scene, but you can rush the process by getting the world light to send more than one ray into the scene per iteration.

worldLight(colour, samples)


Hacky old ambient light. This colour is added to all lighting equations as a constant. Provides flat boring lighting, but can be used as an extremely cheap hacky way to achieve global illumination. I included this for completeness...



Sets the background colour. This is particularly useful when using the path tracer. i.e. try turning off your worldlight, then setting the background colour to the same value and using path tracing.



There are a small number of utility functions available for doing useful bits and bobs. Over time I'll be adding more and more methods to this section of the scripting language. Let me know in the reply section if you've got any requests.


Constructs a vector out of three floating point values.

v0 = vec(1,0,1);


Returns a normalised vector from the argument vector

v0 = normalise(diff)


Calculates the cosine of a floating point value

v0.x = cosf(v0.x)

Woostate Variables

The variables are typically used when adding objects to the scene etc. There are plenty of articles on the site talking about the various types of state you can tweak.


pos - vector - Position of the object cursor
scale - vector - Scale of object's added, and pos modifications made
rx - float - rotation around the x axis (right)
ry - float - rotation around the y axis (up
rz - float - rotation around the z axis (into the screen)


diff - vector - diffuse colour of the surface
refl - vector - Reflection amount and colour
emi - vector - Light emission amount. (Added to lighting calculation)
spec - vector - Specular amount and colour
power - float - Size of specular highlight
gloss - float - Perfectness of reflection vector (1.0 = perfect, 0.0 = highly imperfect)


recursions - float - Number of recursive calls before the system returns (rounded to nearest integer)
v0 - vector - temporary vector storage
v1 - vector - temporary vector storage
v2 - vector - temporary vector storage
v3 - vector - temporary vector storage

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *

Spam Protection *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>