S2ENGINE HD  1.4.6
Official manual about S2Engine HD editor and programming
Overview

Getting Started

Scripts are used to customize the behavior of objects of the game scene but also programming the logic of the game GUI (widgets). The first script to be executed just when game start is the script that you specify into the .ini file (see also GUI Main widget. To write a script you can use any notepad/wordpad application and save the text file with sc2 extension. To associate a script to an object you must set the script param of the object inside the Editor.

Syntax

S2Engine HD script language has a syntax similar to standard C language. You can declare variables, at start but also in any part of the code, assign or read them, define functions, also with parameters, call functions inside other functions, do arithmetic and logical operations, do loops and if...then...else constructs. Like C language the code statements are separated by ';' simbol.

var float x; /* declaration statement */
var float y; /* declaration statement */
var float a; /* declaration statement */
var float c; /* declaration statement */
var bool b; /* declaration statement */
a=x+y; /* assignment statament */
if(b==false)
{
c=0.0; /* assignment statament */
a=Func1(); /* assignment statement */
Func2(); /* function calling statement */
}

There are only few differences regarding:

  • Variable definition.
  • Function interface definition.
  • Operator ordering.
Attention
About this last point: operators are executed from left to right WITHOUT taking into account any priority order. In other words, for example, the arithmetic formula 5+2*3 is executed first executing 5+2 and then multiply the result for 3, while into standard C language first 2*3 is executed and then the result is summed to 5. In conclusion you have always to specify the order of operations by using parentheses '(' and ')'. In the example we can write 5+(2*3) forcing compiler to executing first 2*3 operation.

Every script is associated to an object or a widget. At certain points of the object/widget code the script code is called through some entry point functions:

  • void init(): called at object/widget initialization time
  • void postInit(): called after initializtion and after an Object has executed the attaching code. Works only for objects.
  • void Update(): called at object/widget Updating time
  • (new from 1.03.07) bool Update(): It is called inside Event/Action scripts. Must return true is event is verified, otherwise return false.
  • void PostUpdate(): called after object Updating. Works only for objects.
  • void Message(): called every time an object/widget receives a message
  • void Destroy(): called at object/widget deleting time

If you want to code script of an object or a widget you have to implement these functions that are the script entry points (just like DllMain(), main() or WinMain() entry point functions in C language). To implement, for example, the init entry point function you must write:

function void init()
{
/* function body */
}

see the Functions for more about function declaration.

Keywords

The following are all the reserved language keywords:

  • bool boolean type identifier
  • camera_distance
  • editor boolean that is true if engine is in Editor Mode, otherwise is false.
  • else
  • false
  • float float type identifier
  • frametime float that contains the duration of a frame in milliseconds.
  • function A command that must be placed before defining a function (see Functions)
  • global
  • this
  • if
  • int integer type identifier
  • message
  • return
  • sender string that contains the name of the sender of a message. Used inside Message() function.
  • then
  • true
  • var A command that must be placed before declaring a variable (see Variables)
  • vec3 3d vector type identifier
  • vec4 4d vector type identifier
  • while

Compiler Directives

Directives are some MACRO that let S2Script compiler to comunicate with S2Sandbox Editor.

  • #message: specify what message the scripted object can receive from editor. See Messages
  • #use: specify what resourse the script use. Must be specified to let editor knowing what are the resources used by the script during publishing operation. See Editor.
  • #scene: Must be specified to let editor knowing what are the scenes used during publishing operation. See Editor.
  • #param (NEW 1.03.01): define a param exposed into the editor. The syntax is #param type name where:
    1. type: the type of param choosen form float,int,vec3,bool,string
    2. name: the name of the param. It will appear inside the editor dialog where you assign the script params.

To change params of an object script you have to access the class tab and select scriptParams object param.

Comments

Comments can be inserted into the script code. A comment must be preceded by simbol

/*

and followed by simbol

*/

. It can be more than one line:

if( condition1 )
{
/* this part of code is a comment
and it is not executed */
statement1;
statement2;
/* this is another comment */
if( condition2 )
{
statement3;
...;
}
}
Attention
Unlike C++ standard '//' inline comments are not yet available.

Data Type Format

Data type format is similar to C language except for some new data type native support. The following are the supported types:

  • float: floating point data type
  • bool: boolean data type, it can assume 'true' or 'flase' values
  • int: integer data type
  • string: string data type
  • vec3: three coordinates vector data type, needed in vector math
  • vec4: four coordinates vector data type, needed in vector math
Attention
NOTES: float number must be specified by the format integer part.fractional part, for example 5.0, 5.5, 100.05,... string values must be eclosed in quotation marks, for example "pippo", "pluto", "paperino". You can access to the single component of a vec3 or a vec4 by using mask operators xyzw. For example a.x access to x coordinate of vector a, b.w access to the w coordinate of vec4 b. You can access to only one component per time. Unlike C, S2 script language is very rigorous about data type formatting and casting. 0.0 is considered as a float value and cannot be used as integer, viceversa 0 is considered as an integer value and cannot be used as float. To use an integer as a float you have to use cast functions.

Variables

Variables are indentifiers that can contain a value of a certain type. Their value can be read or assigned. Before using it a variable must be declared. To declare a variable you must type:

var type varname;

where:

  • type: is the variable type that can be one of the following:
    1. int
    2. float
    3. bool
    4. string
    5. vec3
    6. vec4
  • varname: the name of the variable you want to define.

Variables can be defined:

  • outside all the functions - in this case they are visible in all the script
  • at the beginning of a function - in this case they are visible in all the function boby
  • in a code block - in this case they are visible only in the block they have been declared.

The variable described until now are valid only inside a single script. It is possible to define variable that are visible inside all the scripts of a game, in this case we say they are global. global variables can be defined in the following manner:

global type varname;
  • type: is the variable type that can be one of the following:
    1. int
    2. float
    3. bool
    4. string
    5. vec3
    6. vec4
  • varname: the name of the variable you want to define.
Attention
NOTES: Global variables are destroyed only when game shutdown, so they store their values even if you close the current game scene and open a new one. To assign a value to a vec3 or vec4 variable you can use the vec3 or the vec4 cast operators that converts a tuple of floats into a vec3 or vec4 type:
var vec3 a;
a=vec3(10.0,10.0,10.0);

Assignment statement

Like C language in S2Script variables value are assigned by using the assigment statement:

var int a;
/* assign value 5.0 to variable a */
a=5.0;

The right term of an assignment statement can be also another variable or a function. The important thing is that the type of the variable or the left is the same as the type of the variable, function, data at the right. For example:

var int a;
var string str;
/* this generate a syntax error */
a=5.0;
/* this is correct */
a=5;
/* this is correct */
str="pippo";
/* this is wrong */
str=true;

Arrays

You can define also list of variables which we call arrays. An array is a list that contains variable of the same type. To define an array you have to specify how many elements the list can contain:

var int a[100];
var float b[50];

In the example an it is defined an array 'a' that can contain a maximum of 100 integers, and an array 'b' that can contain a maximum of 100 floats. To access to an element of an array you have to specify the index of the element:

a[i]=10.0;
b=a[i];

In the first line you assign the value 10.0 to the i-th element of the array a. In the second line you assign to variable b the i-th element of array a.

Code Blocks

Just like C language, a code block is a piece of code included into '{' and '}' symbols. Code blocks can be innested. Every variable created in a block could be visible only into the block and its contained blocks. The function body, for example, is a code block that could contain, for example a while construct that is another block:

function void init()
{
/* begin function block */
...
...
...
while(x<10)
{
/* begin while block */
...
...
/* end while block */
}
if(x>10)
{
/* begin if block */
...
...
/* end if block */
}
/* end function block */
}

In this case the init block is the parent of while and if so a variable defined into while block isn't visible into if block, but a variable defined into init block is visible either into while and if blocks.

Logical and arithmetic expressions

S2Script lets you to use logical and arithmetic operators. Single operators can be concatenated forming more complex expressions. Arithmetic expressions are made by arithmetic operators (+, -, *, /, -) which take in input 2 (or 1) numbers (or vectors) and give, as result, a number (or a vector). For example:

/* a,b,c are float numbers */
a = (5.0*b)+3.0+(c/2.0)

is an arithmetic expression.

Logical expressions are made by logical operators (&&, ||, !, <, >, <=, >=, == respectively and, or, not, smaller, greater, smaller equal, greater equal, equal) which take in input 2 (or 1) booleans or numbers and give as result a boolean. For example:

/* a,b,c,d are float nmumbers */
a = (d==0.0 && (b<3.0 || c>10.0))

is an logical expression where b<3.0 returns true if b is smaller then 3.0, c>10.0 returns true if c is greater than 10.0.

When an expression is encoutered compiler executes in series operators from left to right, for example the expression 2+4+5 is solved by executing 2+4 and then summing the result to 5. As said in S2Script, unlike C language, operators haven't a priority order, so, to let compiler solve expression in a particular order you have to use parentheses. For example the expression (3+4)*(4+5) is solved by first summing 3+4 and 4+5 and then multiply the two results, otherwise 3+(4*4)+5 is solved by executing 4*4 and then sum the result to 3 and to 5.

Functions

Functions are code blocks, labelled with a name that identifies them, that execute a sequence of operations and give a result and, mainly, can be executed more than one time in any part of the script by name calling. S2Script lets you to implement your own functions and call them inside other functions or inside the main entry functions. Like in C functions must return a value (if you want function doesn't return a value you have to specify the 'void' return value). To define a function you must write:

function type funcname(paramtype paramname, paramtype paramname, ...)
{
/* function body */
/* ... */
/* value can be a variable or an explicit value: number,vector,bool,string,... */
return value;
}

where:

  • type: is the type of the returning value, it is void if you want function does not return value.
    1. int
    2. float
    3. bool
    4. string
    5. vec3
    6. vec4
  • funcname the name you want to assign to function, it must differs from the name of the standard library functions.
  • paramtype the type of the function param
  • paramname the name of the function param
  • value the value to be returned, could be a variable.

NOTES:

  • To return a value you have to use return keyword.
  • You can return a value in any part of the function body.
  • Function body must be enclosed inside '{' and '}' simbols.
  • Function definition must precede its calling.
  • Function definitions are visible only inside a single script.
    • Like in C language, you cannot define and implement a function inside another function. All function implementation must be made outside all other ones.

The following code is right:

function void func1()
{
/* function body */
/* ... */
}
function void func2()
{
/* function body */
/* ... */
}

While the following code is wrong:

function void func1()
{
/* function body */
/* ... */
function void func2()
{
/* function body */
/* ... */
}
}

After defined a function can be called inside another function or inside an entry point function. Calling a function means executing it. To call a function you must write its name followed by the params values encolsed by '(' and ')' simbols:

/* define function func1 */
function void func1(int p1, float p2)
{
/* ... */
}
function void init()
{
var int i;
var float f;
i=10;
f=0.0;
/* call function func1 */
func1(i,f);
}

Constructs

S2Script lets you to use the main syntax constructs of a programming language: conditions and loops. Conditions can be obtained using the if...then...else construct, the loops can be obtained using the while construct. The syntax is the same of C language.

If then else

This construct lets you to execute a code part only if a condition is satisfied. It has the following form:

if(logical expression)
{
/* executes if logical expression returns true */
}
else
{
/* executes if logical expression returns false */
}

where logical expression is an expression made with logical operators which result is a boolean value "true" or "false".

While

This construct lets you to repeatedly execute a code part until a condition is no more satisfied. It has the following form:

while(logical expression)
{
/* continue executing this code if logical expression continue returning true */
}

where logical expression is an expression made with logical operators which result is a boolean value "true" or "false".