Main Page   Modules   Class Hierarchy   Alphabetical List   Compound List   Compound Members   Related Pages  

Script Programming

The X˛-Script Engine

date: 07/05/2002

The script editor gives access to game functionality at a high level. Via ScE (ScriptEngine) calls game Objects can be modified in behaviour and also be created.

Purpose of this document

At the current state this document is supposed to help beta-testers to write scripts. It sets up a framework of how scripts should work together, without going too much in the details, as ScE-call-names mostly speak for themselves. Scripts beginning with a callsign ("!") can not be changed by the player.

Scripts abstract

There are two kinds of scripts:
1) global scripts
If a global script should care about a certain object, it has to retrieve the object and handle the object´s commands/signals by mapping a command/signal to an appropriate script via "connect ship command/signal .. to script .. with prio .." (found in "general commands"). Skripts of this type are called with NULL as the "base object". Also, there is a possibility to call a script from KC code. This might be interesting if a quest/mission wants to maintain a special object (e.g. a ship) with a behaviour that differs from the standard. See example 3 for that.
2) object-bound scripts
Skripts of this type are called from a cetrain object.


A script can be written synchronuously. That means it does not return until certain conditions are true ("while 1..."). Therefore two mechanisms exist to execute another script anyway: -Scripts started with the ScE-command "START .. -> call script ..." replace the current running script. -an interrupt priority can explicitly be set with "set script priority to XX" (normally done by the default mapping). and then the ScE-command "interrupt with script .. and prio YY" is executed if YY >= XX. Afterwards the script executed before is restarted.
Note that an ScE-call can be interruptable (marked with an @ at beginning of the line).

Ship commands and signals

Ship commands and signals (the internal mapping-technology is the same for both) are assigned to certain scripts which handle the further process. The following hierarchy of mappings should be used to assign commands/signals to scripts. The mapping of the next higher level should apply when there is no mapping defined in a level - starting with level 0. The purpose of this is to let different ship types of different races behave individually, making the game more "alive" (hence the name AL-scripts ("artificial life")).
3) "global default"
2) "global for race"
1) "for ship class of race"
0) "for a paricular ship"

localisation of level 3)
When initialising the ScE, the script "!init.ship.globalscriptmap" is executed. From there the script "!init.ship.globalscriptmap.std" is called, which itself calls the ScE-command "global ship map: set:" for all commands/signals. This determines the bahaviour for all ships of all races.

localisation of level 2)
Scripts named "!init.ship.globalscriptmap.XXXX" override level 3 for a particular race (where XXXX stands for the name of the race). This scripts are also called in "!init.ship.globalscriptmap". The naming convention for the lower-level scripts should be "!ship.CS.YYYY.XXXX" where YYYY is the name of the command and CS = "cmd" or "signal".

localisation of level 1)
Scripts named "!init.ship.scriptmap.ZZ.XXXX" should be called from inside scripts of level 2. ZZ stands for the ship class and XXXX for the racename.

localisation of level 0)
This is supposed to be done with global scripts.


A visualisation of the calling hierarchy and the naming conventions could look like this:
!init.ship.globalscriptmap
	!init.ship.globalscriptmap.std		-> !ship.CS.YYYY.std
	!init.ship.globalscriptmap.XXXX		-> !ship.CS.YYYY.XXXX
		!init.ship.scriptmap.ZZ.XXXX	-> !ship.cS.ZZ.YYYY.XXXX

XXXX - name of the race
YYYY - name of the command
ZZ   - name of the shipclass
CS   - either "cmd" or "signal"

[THIS]->set command ...

Some commands need parameters and some don´t. For those that do this parameters can be passed with this call (found in "fly commands"). You can find out about the meaning of the parameters for commands by looking into the scripts named "!ship.cmd.XXX.std".

Stations

Functionality of stations is currently on KC-code level.

Examples

files needed:
!init.ship.globalscriptmap.xml
!init.ship.globalscriptmap.argon.xml
init.dokutest.xml
init.dokutest.spawnships.xml
test.signal.attacked
!init.shipscriptmap.M4.argon.xml
!ship.cmd.idle.argon.xml
!ship.cmd.M4.idle.argon.xml
!ship.cmd.stay.argon.xml
test.createship
test.formation
You can download the script files here.
Example 1
This example shows how the mapping works.

There is a script "!init.globalshipmap.argon" in which
-the COMMAND_IDLE is mapped to "!ship.cmd.idle.argon"
-and COMMAND_STAY is mapped to "!ship.cmd.stay.argon".
Note that in the script "!init.ship.scriptmap.M4.argon" the COMMAND_IDLE is redefined. That means all argon ships with COMMAND_STAY execute "!ship.cmd.stay.argon" and all argon ships with COMMAND_IDLE execute "!ship.cmd.idle.argon", EXCEPT (!!) the argon M4-class ships (the "Argon Buster"), because this mapping is redefined to "!ship.cmd.M4.idle.argon".

The way this is done can be observed when doing a "reinit script caches" in the script editor menu. Then give the argon buster the command "idle" and the argon cruiser, too (via the debug command console). In their ship menu you see that the script "!ship.cmd.M4.idle.argon" is executed for the buster and "!ship.cmd.idle.argon" for the cruiser.
Giving both ships the command "stay" results in executing "!ship.cmd.stay.argon" for both ships.

The call "[THIS]->set script command ..." found in "general commands" must be called to attach this script to a command. See also "set command".

Example 2
This example shows how to manipulate the bahaviour of one certain ship. In "init.dokutest.spawnships" a Paranid-ship is created and the signal SIGNAL_ATTACKED is mapped to the script "test.signal.attacked".
If you shoot serval times at the ship, "test.signal.attacked" is executed and the ship stays where it is.

Example 3
A script can globally be executed with the following KC-code:
OBJ_SCRIPT_ENGINE.RunScript(OBJ_SCRIPT_ENGINE.FindScript("a_scriptname"), 0, 0, 0);

This script could create a ship and map a certain command/signal to a handling-script or even take over the flight routine for that ship.

Passing arguments to a script works as follows:

1.creating (and allocating) an array that holds the variable-type and the variable-value per parameter.
2.filling the fields with valid data
3.passing the array as parameter nr. 2 of RunScript()

As an example a ship is created in the current sector of the playership. This code could go into Accept().
		array param;
		param = SE_ArrayAlloc(4);
		param[0] = SCRIPT_DATATYP_INT;
		param[1] = OBJ_CLIENT.GetPlayer().GetSectorX();
		param[2] = SCRIPT_DATATYP_INT;
		param[3] = OBJ_CLIENT.GetPlayer().GetSectorY();
		OBJ_SCRIPT_ENGINE.RunScript(OBJ_SCRIPT_ENGINE.FindScript("test.createship"), param, 0, 0);
The script itself takes over two parameters. X and Y position of the sector in the galaxy map. It then retrieves the sectorobject and creates a ship.

here is a serviceable list of script-datatypes:
		SCRIPT_DATATYP_NULL
		SCRIPT_DATATYP_UNKNOWN
		SCRIPT_DATATYP_VAR
		SCRIPT_DATATYP_CONST
		SCRIPT_DATATYP_INT
		SCRIPT_DATATYP_STRING
		SCRIPT_DATATYP_SHIP
		SCRIPT_DATATYP_STATION
		SCRIPT_DATATYP_SECTOR
		SCRIPT_DATATYP_WARE
		SCRIPT_DATATYP_RACE
		SCRIPT_DATATYP_STATIONSERIAL
		SCRIPT_DATATYP_OBJCLASS
		SCRIPT_DATATYP_TRANSPORTCLASS
		SCRIPT_DATATYP_RELATION
		SCRIPT_DATATYP_OP
		SCRIPT_DATATYP_EXPR
		SCRIPT_DATATYP_OBJECT
		SCRIPT_DATATYP_OBJCOMMAND
		SCRIPT_DATATYP_FLRET
		SCRIPT_DATATYP_DATATYP
		SCRIPT_DATATYP_ARRAY
The third argument of the call is an array of return values. Evaluating return values works similar to passing arguments:
		array retval;
		retval = SE_ArrayAlloc(2);
		OBJ_SCRIPT_ENGINE.RunScript(OBJ_SCRIPT_ENGINE.FindScript("somescript"), someparam, retval, 0);
		if(retval[0]==SCRIPT_DATATYP_INT) dosomething;
		if(retval[1]==1) dosomething;


The fourth argument is the priority the script is executed with.
Thus: OBJ_SCRIPT_ENGINE.RunScript(script, arguments, returnArray, priority);
Example 4
Ships flying in formation. 3 TS flying in delta-formation. The two TS following the leader have an escort of 3 M5 in X-formation. See script "test.formation"

Notes on some ScE-calls

attack run on
is used to prepare the ship for shooting at another ship (e.g starting from station, getting close to the other ship etc.). It has one of the following returnvalues:
FLRET_FIREFREE	all clear to fire at target
FLRET_INTERRUPTED	the action was recently interrupted by another script
FLRET_BREAK	target object does not exist or hasn´t the same environment
FLRET_NOCOMMANDS	ship needs new target (target was destroyed)
follow
first parameter : leader (ship object)


Generated on Mon Aug 26 18:26:35 2002 for X˛ KC by doxygen1.2.17