CubeScript

Introduction

Cubescript is the scripting language used by the FPS Sauerbraten/Eistenstern game engines, it was originally developed by Wouter van Oortmerssen for the Cube game engine. It's main advantage are high execution speed and compact syntax. It's syntax is somewhat unusual and requires a bit of getting used to. If you are completely new to map editing in sauer I suggest reading editing.html in sauer's docs directory to get the basic hang of it. The reference document for cubescript commands is editref.html also in the docs directory.

There are numerous cubecript command most of these are to do with configuring the engine and user interface. This tutorial concentrates on cubescript as a scripting language that enhances the gameplay. Generally I have organises this tutorial in terms of how to archive certain results, however some things are difficult to fit into this scheme so please excuse the occasional oddly places section.

This tutorial contains 6 examples with instructions to build then from scratch, however if you prefer they can be downloaded from here. Unpack the zip file into the sauer root directory. The examples should end up in the packages/base directory.

Why use cubescript
If you enjoyied playing the great map LOST by redon in the latest release then that's the best answer I can give. It alows the game to have much nore depth and allows puzells and chalanges to be presented to player which makes for a much more interesting game.

 

General info about Cubescript

Where does cubescript go
Cubescript can be held in various places. Each map has an associated file with the same name but ending in .cfg This contains specific cubescript associated with just that map. Cube script that is required for every map should go in game_fps.cfg for sauerbraten and game_rpg.cfg for eisenstern. There are also some configuration files used to set up the engine key mappings, defaults, etc

Capabilities
Cubescript has the following capabilities

In addition eisenstern has the following extra capabilities

This tutorial concentrates on standard sauerbraten scripting.

Make sure you are in single player(sp) mode, campaign mode in the latest release or Eisenstern.
For all these demo's you need to be in single player (sp) mode or Eisenstern. The eisest way to do this is to load a non existent sp map with sp aaaa . This reports that no map called aaaa cannot be found but goes to sp mode anyway.  To work with Eisenstern start sauer with the eisenstern.bat file.

Executing commands from the console
You can execute the simpler commands at the console. So if you have sauer running and nothing is currently trying to kill you hit the "`" key (just to the left of the "1" key not the one next to ";"). This should open the command console at the bottom left of the screen and show a "\" at the begging of the line as prompt. Type

echo "hello world"

followed by enter, should result in "hello world" appearing on the message output lines at the top left of the screen.

To retype a command line used in the resent past open the console with "`" then press the up arrow key, each press redisplays the previous line.

All the commands down to the examples can be executed at the console in this way.

All commands and cubescript examples are in italics.

The structure of cubecript
Cudescript consists of a series of statements usually one per line. Statements can be grouped together into block or held as functions that do a specific job.

Curved brackets ()
Anything in curved brackets is evaluated first. So it is usually a good idea to put any calculations in curved brackets as you want the calculation to be completed before the result is used.

Square brackets []
Square brackets are used to enclose a number of script statements that need to be handled together. For example if a map fires a trigger that
needs to execute 7 cubescript statements those statements would be enclosed in square brackets.

Statement seperator
Cubescript uses newline as a statement seperatore or if several statements are on the same line the ";" may be used to separate them.

Comments
Anything after a double slash "//" is treated as a comment and will not be executed. Comments can be on a line by themselves or on the end of a statement that is executed. It's a good idea to put plenty of comments in you code, this makes it much easyer to understand afterwards and also help other who want to figure out how the code works. Comments should describe what section of the script does.

Upper and Lower case
Cubescript is case sensative i.e. echo is not the same as Echo this is common source of confusion. 

Spaces
Cubescript is quite fussy about spaces, I normaly put a space each side of an command or significant code (like a bracket) just to be on the safe side.

 

Variables, Assignments and calculations

Storing information
Variables are used to store information that the script needs to refer to again at a later time. Each variable has a name that is used to refer to it in the script i.e. num_uses or keyfound .

A variable name must start with a letter and cannot contain any spaces or punctuation, they are case sensative. A variable can hold a number or a string of characters.

Variable are assigned values using the =. i.e.

num_uses = 4

or

keyfound = "Yes"

Try this at the console. NOTE you must include the spaces either side of the equals.

To access the value of a variable prefix the name with the dollar sign "$", so to get the value of num_uses use $num_uses

So

echo $num_uses

At the console displays 4 at the lop left of the screen.

It is usually a good idea to give a variable a name that reflects what it does, this helps make cubescript much more understandable.

 

Integer calculations
Calculation are unusual as they use prefix notation, that is the operation comes first so instead of putting 1 + 2 it uses + 1 2 this needs to go in a set of curved brackets like ( + 1 2 )

To see the result of this try entering the following in the console (see above)

echo ( + 1 2 )

Which should display 3 at the top left of the screen.

cubescript supports the following integer calculations

( + 1 2 )        Add 1 to 2
( - 10 4 )       Subtract 4 from 10
( * 4 5 )        Multiply 4 by 5
( div 11 4 )    Devide 11 by 4 returning the integer result (in this case 2)
( mod 11 4)    Divide 11 by 4 and return the remainder (in this case 3)

To assign the value of the above sum to a variable use

sumres = (+ 1 2 )

if you need to use the value of a variable in a sum use

num1 = 5
numres = (+ $num1 7)

This would add 7 to the 5 held in the variable num1 and store the result in numres, check by using echo to display the contents of numres ( remember to put the $ in front of the variable name).

Min and max
Min and max return the smallest and largest of two parameters e.g.

echo ( min 5 3 )
ech0 ( min 3 5 )

Would both print 3 to the top of the screen because 3 is the smaller of the two parameters.

xPos =  47
ypos = 35
sPos = ( max $xPos $yPos )

Would set sPos to 47 because it is the larger of the two parametrs

Floating point calculations
Cubescript also supports floating point calculations, add a f suffix to the integer operations so +f is floating point add, to multiply 4.73 by 2.21 

echo ( +f 4.73 2.21)

 

Control Structures

IF (making decisions)
The if statement is used to allow cubesript to execute one set of statement over another depending on the result of a logical comparison. For example if the player has the key then tell them they have a key otherwise tell the user they need a key. This would look like

if ( = $key1 1) [ echo "You have the key" ] [ echo "You need to find the key"]

Here the variable key1 is being used as a flag to indicate if the player has the key (Contains 1) or not (contains 0). Test this at the console by setting variable key1 to 1 with

key1 = 1

Then entering the if statements above. Now set key1 to 0 with

key1 = 0

and try the if again.

Multiple statements can be placed inside the square brackets if required.

The following comparisons are available, both things being compared can be in variables.

( = $key1 $cmp1 ) true if the number in variable key1 is equal to 1.

( != $key1 1 ) true if the number in variable key1 is not equal to 1.

( > $key1 1 ) true if the number in variable key1 is greater than 1.

( >= $key1 1 ) true if the number in variable key1 is greater than or equal to 1.

( < $Key1 1 ) true if the number in variable key1 is less than 1.

( <= $Key1 1 ) true if the number in variable key1 is less than or equal to 1.

( strcmp $hasKey "Yes") compares two strings and is true if they contain the same string of characters.

The result of two comparisons (or more) can be combined with the following logical conditions. Cubescripts prefix notation applies here to.

|| or

&& and

^ exclusive or

! Not

So to check if key1 holds 1 and key2 holds 1 use

If (&& ( = $key1 1 ) ( = $key2 1)) [echo "Both hold 1"]

To test this use the consol to set the variables key1 and key2 to various combinations of 1 and 0 and execute the if given above.

 

LOOP Repeating a block of code a known number of times

Loop - Repeats code a given number of times
This is used to execute cubescript statements a number of times.

loop i 10 [ echo (concatword "i holds " $i) ]

This will loop the code in the square brackets 10 times, each time the variable i holds the iteration number. So in this case the numbers 1 to 10 will be printed on the top line. Multiple statements can be placed between the square brackets if required (see examples).

While Repeats a block of code while a condition is true

This is used to repeat a number of cubescript statements and check a condition each time. If the condition evaluates to true then the code is executed and the condition checked again.

while - Repeats code until some condition is true
i = 1
while [(< $i 10 )] [ echo $i ; i = (+ $i 1)]

Which does the same thing as the loop statement above. Normally the condition would involve a user 
input or some other event from the map (see below). Note the square brackets around 
the test condition, othewise the logical test is not repeated for each 
lool.

 

Functions

Basic Functions
A function is a number of cubescript statements that together perform a given action. A function is defined by giving a name for the function then the statements enclosed in square brackets. So to define a function that checked if the player has a particular key you could use

checkkey = [ If ( = $greenkey 1 ) [ echo "You have the key"] [echo "Try to find the key"]]

Note the square brackets at the beginning and end of the function. To use the function in you script just give the name i.e.

To test this at the console enter above function (exactly as given) at the console, set the variable greenkey to 1 or 0 with a statement similar to the one we used for key1 above, then enter

checkkey

At the console, you should get one of the messages from the function.

Functions with parameters
The basic function is only of limited use as it always does exactly the same thing. Say we had a map with 4 locked doors it would be much more useful if we could let the function know which key we wanted to check for, then the same function could be used to check all 4 keys. This is possible using parameters. Parameters are variables that can be passed from the main program to the function. Inside the function the variable is accessible via the arg variables, arg1 for the first parameter, arg2 for the second ,etc. Our modified function now looks like

checkkey = [ If ( = $arg1 1 ) [ echo "You have the key"] [echo "Try to find the key"]]

Set a value for the green and red keys

greenkey = 1

redkey = 0

Now to check for the greenkey use

checkkey $greenkey

And to check for the red key use

checkkey $redkey

This can save a lot of repeated code.

 

Linking some cubescript commands to a keypress

bind - Link a key press to some commands
The bind command allows a keypress durring the game play to execute one or more cubescript commands, so.

bind h [ echo "Hello world" ]

Will display "Hello world to left if the h key is pressed durring play mode. Not this can be setup inn edit mode but only works in play mode.

Similarly 

dsp = [ echo "First line of display" ; echo "second" ]
bind n dsp

Will run the dsp function when the n key is pressed. Not you cannot test this is edit mode so switch to play mode for testing.

 

Manipulating strings

concat - Joins to strings together 
The concat command joins the contents of all the arguments together so

fstr = "First part"
sstr = "second part"
res = (concat $fstr $sstr)

Will result in res containing "First part second part". Which you can test with echo $res. Note the extra space added where the two strings join.

concatword does the same thing but does not add the extra space so.

res = (concatword $fstr $sstr)

Sets res to "First partsecond part" which does not contain the extra space.

strstr - Search a sring
This searches a string for a given substring and returns the starting position of the sub string. So for example if

x = "Sauer is a very easy to use FPS game creator"

Then

echo ( strstr $x "easy")

Would return 15 because "easy" starts at position 15 (counting from 0). -1 is returned if the sub string is not found. So

echo ( strstr $x "Easy")

Returns -1, remember sauer is case sensative.

To check if a string contains a sub string anywhere in its lenght use

if ( >= ( strstr ( $x "easy") 0) [echo "found"] [echo "not found"]

substr - Extract a spesific section of a string
Returns part of a string e.g.

x = "This is another short centance"
echo ( substr $x 5 4)

will display "is a" which is the 4 characters starting from the 5th character (the first char is zero), and

q2 = ( substr $x 8 7 )

sets the variable q2 to the stirng "another"

If only one parameter is given then this returns the characters from that point on to the end of the string so.

echo (substr $x 17)

will return "short centance"

If two parameters are give and the first is zero then the second parameter returns that many characters from the begining of the string e.g.

echo ( substr $x 0 4)

returns "This" 

strreplace - Replace part of  astring with another string

This searches a string for substring and replaces it with another substring so

echo ( strreplace "This is a test of the xxxx command." "xxxx" "strreplace" )

prints "This is a test of the strreplace command." top left

Format - Formated a string
The format command provides an easy way to display the value of variables in a string.

maxNoTasks = 7
curTask = 4
echo ( format "You are on task %1 out of %2 tasks" $curTask $maxNoTasks )

would display

"You are on task 4 out of 7 tasks"

The %1 in the string is replased with the value of the first variable, the %2 by the value of the second variable. Up to 9 variables can be includded in this way.

 

Lists

A list is a string containing a number of items seperated by spaces, a sentance can be though of as a list of words. Cubescript supports a couple of list commands.

listlen - Number of items in a list
This returns the number of items in a list so

lst = "item1 item2 item3 item4 item5"
echo ( listlen $lst )

returns 5

at - Extracting one item from a list
This extracts one item from a list.

tstr = "This is a collection of words"
oneword = (at $tstr 4)

Would set oneword to "of", counting from 0.

and

echo ( at "00 10 20 30 40 fifty 60" 5)

returnd "fifty"


Indirect execution

This is about executing cubescript commands that are either held in a string variable or a completely different file

()
If a number of cubescript commands are stored in a variable these can be executed by placing the string in brackets so

lsx = "loop i 10 [ echo (concat holds  $i) ]"

then the command

(lsx)

Will print the numbers 1 to 10 on the screen. Complex programms can use this to constuct bits of code in a string variable and the execute them.

If the last command in the string is "result" then the value of the associated variable will be returned and substituted for the expresion enclossed in (). 

exec - execute the command stored in a file
This allows a cfg file to be called and all the cube script it contains will be executed.

create a file containing

echo "Hello woprld"

Save this in the packages\base folder with the name text_exec.cfg

then entering

exec package\base\test_exec.cfg

which will run the echo command in the file and display "Hello world" on screen. Commonly used routines can be setup in a file and then called for every map. This means that the cfg file for the map only need contain the code spesific to that map.

getalias - usine a variable to hold a reference to another variable
If v1 contains the name of another variable (say v2) then

echo ( getalias $v1 )

Displays the contents of v2. This allows one variable to point to anouther variable. concatword could be used to construct a variable name from several dynamic parameters and then the value of that variable retrieved.

 

Interactions between cubescript and the map

Cubescript can ineract with things in the map like doors, elivators and triggers.

Adding a door to a map
For the next couple of examples you will need a door to control. You could add a door via the menu but you are better of using the console as this give grater flexibility. To add a door via the console.

1) Ensure you are in sp mode.
2) Switch to editing by pressing E (loads of debug stuff appears bottom left), and create a new map with newmap 12  .
3) Select a square on the floor where you want the door to appear
4) open the console and enter newent mapmodel 27 11 4

A door should appear. 27 is the map model of the door, 11 means it's locked and 4 is the tag number. You can move it around in the usual way by selecting it (mouse over it and click) and dragging with the mouse. You can rotate it by selecting it, holding down R on the keyboard and moving the mouse wheel.

Come out of edit mode to test the trigger commands

trigger - Opening or closing a doors
Cubescript uses the trigger statement to open or close doors. When a door is added to a map it is given a tag number. This is then used by cubesript to control the door. So for our door with a tag of 4 then

trigger 4 1

Would open the door (try this at the console) and

trigger 4 0

Would close it.

Adding a platform or ellevator
For the next couple of examples you will need an platform (or elevator) to control. To add a platform at the console.

1) Make sure sauer is in sp mode
2) Switch to editing by pressing E, then create a new map with newmap 12 .
3) Select a square on the flore
4) Open the console and enter newent platform 16 20 30  .

NOTE sometimes you have to go in and out of edit mode to see a change to a platform or elevator.

This adds a platform with a map model 16 tag 20 and speed 30. To add an elevator replace platform with elevator.

Come out off edit mode to test the platform.

platform/elevator - Starting and stopping a platforms and elevators
This is similar to doors. When the platform or elevator is added to the map it is given a tag number. The tag can then be used by cubescript to control the platform. So if the map has a platform with a tag of 20 then

platform 20 1

Would start it moving forward

platform 20 0

Would stop it and

platform 20 -1

Would start it moving backwards.

Elevators work the same way, just replace the word platform with elevator.

 

Adding a trigger to the map
A trigger can be added to the map via the edit menu but it is better to do it via console.

1) Make sure you are in sp mode.
2) Switch to edit mode (press E), then create a new map newmap 12 .
3) Select a square where you want the trigger to appear.
4) Open the console and enter newent mapmodel 24 3 22  .

Executing code from a trigger in the map
To execute a function in cubesript when the player activates a trigger in the map the function must be called level_trigger_n . Where n is the tag associated with the trigger. So if there is a trigger in the map tagged with 22 then to have some code execute when the player activates the trigger use

level_trigger_22 = [ echo "You fired the trigger "]

You can enter this at the console. Now switch out of editing (press E) and move over to the trigger. The level should move and the message appear top left.


Delaying an Action

Sleep - doing something after a given amount of time
This command waits a given amount of time then executes the statements in the square brackets.  Create a map with a door in it taged with 4 (see above) and try the following.

sleep 10000 [ trigger 4 1]
echo "finished"

This displays finished at the top of the screen then 10 seconds later opens door 4. The delay is in milliseconds so 60000 gives a 1 minute delay. NOTE the programme execution does not pause, the code in the square brackets is executed after the delay but the statement after sleep is executed immediately.



 

Examples

Editing and the cfg files

These examples all need the cubescript to be in the map's cfg file. There is a cfg editor as the last tab on the edit menu but I have found this to misbehave in unpredictable ways. Not sure if its me or the editor anyway I strongly recommend that you use an external editor i.e. wordpad is ok or notepad. Any text editor will work, I like crimson!

When you save a map with the savemap myname command the map is saved in the file myname.ogz in the packages/base directory. If you add a file with the same name ending in .cfg (in this case myname.cfg) in the same directory then any cubescript command in that file will be loaded when the map is loaded.

Using an external editor means that before any changes to the script are executed by the game the cfg file must be save and the game in sauer re-loaded. So my editing sequence is

1) Save the map from inside sauer
2) Swap to the external editor
3) Edit the cfg file and save to the same name as the map but with the .cfg extension
4) Swap back to sauer
5) Reload the map with the sp command

Example 1 A Door Control

Creating a map with one door that only opens after two levers have been pulled.

Setting up the map

1) Make sure sauer is in sp mode
2) Switch to editing (press E)
3) Create a new map with newmap 12
4) Add a locked door with newent mapmodel 26 11 4
5) Move back from the door a little way and add the first level (trigger) with  newent mapmodel 24 3 7
6) Move sadeways a bit and add the second level (trigger) with newent mapmodel 24 3 8
7) Save map as tt_test1 with savemap tt_test1
8) Swap to the text editor and add the script (see below)
9) Save the script into a file called tt_test1.cfg in the packages/base directory
10) Swap back to sauer
11) reload the map with sp tt_test1
12) test !

Here is the script

lev1 = 0
lev2 = 0

Checkdoor = [
If ( && ( = $lev1 1 ) ( = $lev2 1 ) ) [ trigger 4 1 ; echo "The door has opened" ] [ echo "you need to pull both levers" ]
]

level_trigger_7 = [
lev1 = 1
Checkdoor
]

level_trigger_8 = [
lev2 = 1
Checkdoor
]

How this script works
When the map loads the script runs and first creates the two variables lev1 and lev2 and sets both of them to 0. These variables are used to remember when a lever has been pulled. The two level functions level_trigger_7 and level_trigger_8 are activated from the matching triggers on the map. Both work the same way, first setting the relevant variable to 1 then calling the function Checkdoor. Checkdoor then checks if both variables are set to 1, if they are it opens the door, if not a message is displayed for the user.

Re-Running the map
Going into edit mode and back to run mode re-sets the map, that is the door closses and the levers return to the starting position. It does not re-run the script so both variables lev1 and lev2 remain set to one which means that the door now opens when only one lever has been pulled. To see the map work correctly again re-load the map with sp tt_test1 .

Debuging Cubescript
Cubescript can be a bit trickery to work with. If you do not get the cubescript exactly right strange things happen or sometimes nothing at all. Here are some techniques I have used to help sort out what is going on when a script does not work as expected (The above example took 3 goes before I got it to work!)

1) Try out an individual command at the command line. Sometimes a simplified version of the command can be executed first then work up to the full command.

2) Display the value of a variable with the echo command at the console.

3) Add extra echo commands into the script so you can see if that particular part of the script is being executed. e.g. if we suspected that the triggers where not firing put an echo "trig 7" between the line level_trigger_7 = [ and lev1 = 1 . Now if the trigger is firing the echo command will execute and display "trig 7" at the top of the screen.

4) Start with a very simple script that definitely works then modify it in small stages towards what you actually want, checking it each stage that it still works.

The newent mapmodel command and triggers
The console command "newent mapmodel" is a general purpose sauer command that adds a model (not a monster) to the map. It takes 3 parameters, these are

1) The model number - These are defined in the file "default_map_models.cfg" in the data directory. This file links the actual model files to the numbers. DO NOT CHANGE THIS FILE!.

2) The trigger type - These go from 1 to 14. Some interesting ones are 11 locked door, 3 trigger once only when first touched, 5 trigger every time it is touched and 13 trigger once and disappear( to the player this looks like a pickup) For a full list see editref.html in the docs directory.

3) The tag or trigger number, for a door this is used to control it. For a trigger it tells sauer which level trigger to run.

So a lever that operates once on trigger 7 would be created with

newent mapmodel 23 4 7

Because 24 is the model number for the lever model, 3 means trigger once and 7 is the trigger number that we use in the script. A locked door on trigger 4 is created with

newent mapmodel 26 11 4

Because 26 is the model number for a door, 11 means locked, and 4 is the trigger number. In this case the door can be opened and closed by ref to the 4 and also generates a trigger when touched on trigger 4!

Model number -1

Model number -1 creates an invisible trigger which the player cannot see.


Example 2 - A door controlled by a key (pickups)

Creating a map with one door and a key to be picked up

1) Make sure you are in sp mode
2) Switch to editing (press E)
3) Create a new map with newmap 12
4) Add a locked door with newent mapmodel 26 11 4  .  Rotate the door by holding down R and rolling the mouse wheel until it is parallel to the rows of patters on the floor. If you do not do this the collision box will not match the door.
5)
Add the key as a pickup - This is a special trigger that removes the object when it is triggered. Move some distance away from the door add the key with newent mapmodel 68 13 5 . Near the key pull up pillar so that you can find the key again.
6) Save the map with savemap tt_test2
7)
Swap to the external editor and enter the script below.
8) Save the script as tt_test2.cfg in the packages/base directory.
9) Swap back to sauer.
10) Re-load the map with sp tt_test2
11) test

Here is the script

 

key1 = 0

level_trigger_4 = [
if ( = $key1 1 ) [ trigger 4 1 ] [ echo "You do not have the key"]
]

level_trigger_5 = [
key1 = 1
]

How this script works

When the map is loaded the script runs and sets the variable key1 to 0. If the player then touches the door it executes the level_trigger_4 function. This checks the variable key1 and if it equals 1 opens the door, else it tells the player they need a key. When the player touches the key it runs level_trigger_5 which just sets the variable key1 to 1. Now if the player touches the door it opens!

As before to re-run this re-load the map to re-set the variable key1 to 0.


 

Example 3 - Getting a trigger to open a menu

Basic menus
Sauer has a menuing system that can be implemented from the cfg file. These menus can be integrated into a game to help (or hinder) the player, anyway they allow for grater variation in game play.

The basic principle is define a menu in the cfg file then use a trigger from inside the map to display the menu. The options in the menu can then do things to the map.

Setting up the map

1) Make sure you are in sp mode.
2) Swap to editing.
3) Create a new map with newmap 12
5) Add a consol to trigger the menu with newent mapmodel 21 5 4
6) Save the map with savemap tt_test3
7) Swap to the editor and enter the script (see below)
8) Save the script as tt_test3.cfg into the packages/base
9) Swap back to sauer
10) re-load the map with sp tt_test3
11) test

Here is the script

newgui Console1 [
guitext "Hello from the console"
guibutton "Close " [ cleargui ]
]

level_trigger_4 = [ showgui Console1 ]


How this script works

The newgui command declares the menu but does not display it. The showgui command in the level trigger displays the menu. In the map the console is setup as the trigger so when the player touches the console the trigger fires which in turn displays the menu.

 

Example 4 - Using a menu to control a door

This example uses options on the menu to open and close a door. This example is a modification to example 3.

Assuming you have example3 loaded (if not load it with sp tt_test3).

Setting up the map

1) Swap to editing
2) Add a locked door with newent mapmodel 26 11 5
3) Save the map with savemap tt_test4
4) Swap to the text editor (if tt_test3 is not already in the editor load it)
5) Modify the script (see below)
6) Save the script with savemap tt_test4.cfg in the packages/base folder.
7) Swap to sauer
8) Re-load the map with sp tt_test4
9) Test

 

Here is the modified menu

newgui Console1 [
guitext "Hello from the console"
guibutton "Open Door " [ trigger 5 1 ]
guibutton "Close Door " [ trigger 5 0 ]
guibutton "Close " [ cleargui ]
]

level_trigger_4 = [ showgui Console1 ]

 

Hopefully this is self explanatory.

Now when the player touches the console the menu open and the player should be able to open and close the door.



Example 5 - A menu with 2 tabs that displays some game info

This is a modification to example 4. This addes two levers and reports in the "current state" tab which one of the levers the player last touched. I will just give outline instructions this time and leave to the user to work out the e
editing sequence.

Modifying the map

Add two lever triggers to the map with

newent mapmodel 24 5 6
newent mapmodel 24 5 7

Save the map as tt_test5

Modify the script to

state = "You have not touched a lever yet"

newgui Console1 [
guitext "Hello from the console"
guibutton "Open Door " [ trigger 5 1 ]
guibutton "Close Door " [ trigger 5 0 ]
guibutton "Close " [ cleargui ]
guitab "Current state"
guitext $state
]

level_trigger_4 = [ showgui Console1 ]

level_trigger_6 = [state = "Last touched lever 6 "]

level_trigger_7 = [state = "Last touched lever 7 "]


Save the script as tt_Test5.cfg

Test in sauer

This adds a second tab to the menu which displays the contents of the variable called state. When the map loads this is set to "You have not touched a lever yet". Which is what the player sees on the state tab when the trigger fires and displays the menu. When the player touches a lever the appropriate trigger is fired and the message in the variable state is changed. Now when the player triggers the menu and looks at state the new message is displayed.



 

Example 6 - A Platform and Teleport Monster Machine

This example shows how to use a platform loaded with monsters and a teleport to drop the monsters into the vicinity of the player, it is quite complex.

1) Make sure you are in sp mode, switch to editing and create a new map with newmap 12
2) Build a wall quite long so when the player arrives on one side of the wall he cannot see what's on the other.
3) On one side a short distance away from the wall create a platform with newent platform 16 20 5 that moves parallel with the wall (select the platform entity, press R and roll the mouse wheel to rotate the platform), test which way it goes by switching to play mode and starting the platform (platform 20 1).
4) Create a second platform with newent platform 16 21 5 a short distance behind the first, exactly in line with the first and moving in the same direction.
5) Put 4 monsters on top of each platform. To create a monster at the console use newent monster 0  (0 is the orge ). Put the monster entity's above the platform slight staggered down it's length. If they are two close together they will displace each other and appear some distance away from the entity. If the monster entity is to low it may displace the platform entity which is bad news! as you have to remove all the monsters from the platform, put the platform back in position and replace the monsters.
6) Put a teleport in front of the platform with newent teleport 10 , so that when the platform starts moving it carries the monsters into the teleport.
7) On the other side of the wall put the matching teledest with newent teledest 10 .
8) A short distance away from the teledest put one monster (just to give the player something to do when the game starts) with newent monster 1
9) Back from the monster a bit put an invisible trigger (this will start the platform via a script) with newent mapmodel -1 3 4 .
10) Just above the trigger put some shells as bait
11) A short distance back from the ammo put a player start,  facing the ammo.  Pick the player start from the edit menu. 
12) Save the map with savemap tt_test6  .
13) Swap to the editor and enter the script below.
14) Save the script as tt_test6.cfg
15) Swap back to sauer and re-load the map with sp tt_test6 .
16) Test


Here is the script

// Platform Monster machine R.Knight 15/9/08

level_trigger_4 = [
sleep 1000 [ platform 20 1 ]
sleep 10000 [ platform 21 1 ]
]


How it works

When the map starts, the play will grab the ammo (which fires the trigger) and goes after the one visible monster. The trigger starts moving the first platform after a one second delay via the script. The platform caries the monsters into the teleport which moves them to the players location. After the 10 second delay the second platform starts moving with the same effect.


Have Fun!