link target image

TSW maps | .ini files | .scr files | the macro-language

TSW maps

To make a map for The Strogg War work properly, you need to make some modifications to the start points.
A start point in TSW can be defined in two different ways. If you have a "info_player_deathmatch", you can give this entity the "spawnflags" field with a value from "1" to "4", each number representing a unique team (red, blue, green, yellow). You can also use the TSW-specific entity "info_teamX_start", where X is a number from 1 to 4, one for each team. You have to have at least two team startpoints in a map, you don't need to start with 1 or use two numbers in a row.

.ini files

.ini-files are used to override default map-settings or map-specific settings for TSW-maps. This feature can be used in any game modes, but is required for the TSW:Mission-mode. For more information, see the Keys and Cvars.
The .ini-file has usually the same name as the map (e.g. e1m1.bsp and e1m1.ini). The following listing explains the structure and the fields of an .ini-file.

[game]
This block of the ini file is the general block. The following items are the ones you should place at the [game]-block.

rules=mode
defines which rules apply to the game
mode
war - TSW:War doesn't load .scr-files, simple one against all other
mission - TSW:Mission, reads the .scr-file to define win/loose conditions

teams=count
how many teams will be playing on the map
count - number of teams

script=file
which script file to load, if the game-mode allows that
mode - filename of the .scr-file without the extension

cvar=value
set a special cvar for the game
cvar - name of the cvar, you can only use cvars that start with 'g_'
value - value to assign to the cvar
this doesn't work with all cvars, but with all cvars that are designed to be changed during the game or during the lounge
(e.g. g_modelscale=50, g_limitvis=0, g_doWarmup=1, ...)


[teamnum]
This block defines a special team.
num - the team-number (1=red, 2=blue,...)
You need exactly as many [team]-blocks as you defined in the [game]-block.

name=nametext
how the team should be called
nametext - name of the team

start_origin=x y z
where the team should be placed when the game starts
x y z - x,y,z-coordinates of the startpoint

start_yaw=angle
in which direction the player will face when the game starts
angle - numeric value (e.g. 90)

credits=amount
how many credits the team will get when the game starts
amount - amount of credits


.scr files

.scr-files are plain-text script-files that are read by the game at the start of the server. The functions in the script can be used to create win/loose-conditions, AI controlled events and automated sequences.
The .scr-file that shall be read at the start of the game has to be specified by an
.ini-file
Each script has three basic components: waypoints, triggers and events. Each component has to be enclosed by these braces: { }. The detailed definitions follow here.

waypoint name
{
This line is the waypoint header. The waypoint header is immediately followed by the opening brace.
waypoint is the keyword to start the waypoint-block
name is the name you want to give this waypoint-block
point ( number, (x y z), (pitch yaw roll), time );
point defines a new point in the waypoint section. The point can be used as target for a unit or as point to place a camera or an effect. You may add several points to create a path.
number - the n'th point of your path, starting with zero; if a point-command has no direct successor (e.g. 3 and 5) the chain will end
x y z - the coordinates of the waypoint
pitch yaw roll - the orientation of the waypoint, this can be used to give your view or a unit an orientation if it's placed at the waypoint
time - time in msecs it takes to move from this point to the next point, used for aumotated movement along a path
chain ( value );
Define the type of the path, single line or looped. If it is looped, the path's end and start are tied together. This is useful for patrol routes or a looping flight path.
value - set to 1, to tie start and end, 0 to leave it open
The total number of points (create by a 'point'-command) in the waypoints of your script is limited to 128.
The waypoint-block ends with the closing brace.
}

trigger name
{
The trigger header opens a new trigger. Triggers are checked regularly if they match certain conditions, if so, the included actions are executed. You can say they are the 'if'-part of the script. The trigger-constructs can be pretty complex, so pay attention on what you create.
trigger is the keyword to start the trigger-block
name is the name you want to give this trigger-block
condition = !~[level]checkfunction;
The condition-line adds a new condition to the trigger.
! - invert the condition, from 'wait until is met' to 'wait until is no longer met', this is optional
~ - update the condition, reinitializes the parameters basing on the changed situation and makes it possible to re-use the condition, this is optional, primary use in a repeated trigger, see below for more informations
[level] - on which level the condition is checked, all conditions on a lower level (e.g. 0) have to be fulfilled, before a condition on a higher level (e.g. 1) is checked, this is optional, primary use with updated conditions, see below for more informations
level - level of the condition, expects a number; levelled triggers will re recognized as long as there is no gap between to succeeding levels (e.g. 0 and 2)
checkfunction - which condition you want to check for, see the following listing
time ( secs )
Check if a certain amount of time has passed.
secs - amount of time in seconds
If the trigger is repeated, the time-condition will be re-initialized to check the same interval of time again after the whole trigger has been true. This is useful to create regular repeating events like sending in reinforcements. If the time-condition runs on a higher level than zero, the condition will be updated basing on it's level, which means you can create a repetitive event that starts at a later time.
trigger doubletime
{
	condition = time(120);
	condition = ~[1]time(10);

	action = reinforce1;

	repeat;
}
This sample uses two time-conditions. The second is repeated again and again as soon as the first condition is met, this means, after 120 + 10 seconds, every 10 seconds 'reinforce1' is called.
field ( "target", "name" =<> "value" )
Check a field of an object or of the global environment for a certain value. This is similar to variables you can set and compare. The quotation-marks are necessary, so please include them always.
target - the object where the field is saved, the target is described by a macro-language
name - name of the field, for global fields you can choose your own names; for fields that are saved at an entity (unit/object) you may only read special fields, here is the list
classname
origin
model
model2
spawnflags
speed
target
targetname
message
team
wait
random
count
health
light
dmg
angles
angle
tsw_target
tswteam_num
tsw_class_str
then follows the relation, equal, smaller or bigger than...
value - the value you want to check against, you may enter strings, integer, floating point, IP-adresses (AAA.BBB.CCC.DDD) and vectors(X Y Z)
for numbers and vectors all relations are available, for non-numeric fields (strings), only the equal relation will produce reasonable results
timer ( "teamname", secs )
Check if the mission-timer of a team has passed a certain time-value, i.e. is equal or lower than the value you check against.
teamname - name of the team/party that has this timer assigned, the name of the team is defined in the .ini-file
secs - time the timer shall have passed in seconds
exists ( "targetname", count )
Counts the existence of certain objects or units in the game. If the counted number is above or equal to the defined value, the function will be true.
targetname - name of the target, defined in the macro-language
count - how many targets you want to find, to return true
You may add as many conditions as you want to the trigger, all conditions have to be true, to allow the execution of the trigger. So you can create complex and interesting constructs for very flexible mission-scripts.
repeat;
This command enables a repeating trigger. Normally any trigger that has been valid and executed will be removed from the list and won't appear again. If you make a repetive trigger it will be checked again and be executed as long as it's conditions are valid.
atLeastOne;
Instead of waiting for all conditions to be met, the trigger will be executed as soon as one condition is met, no matter if there are more conditions that are valid or invalid.
action = event;
This is the execution-part of a trigger. As soon as the conditions of the trigger are valid, the actions that are defined for execution will be run.
event - the name of the event you want to execute, the event has to be defined before the trigger in the script, else it won't be recognized
You may execute as many events as you want by adding more 'action'-lines to the trigger.
The number of triggers you can use in a script has been limited to 64.
The trigger also ends with a closing brace.
}

event name
{
The event header creates a new event. Events contain the commands that interfere with the game-execution.
event is the keyword to create a new event
name is the name you want to give this event
The following functions can be used in an event.
print ( "target", "text" );
Print a line of text to the console. This text also appears in the upper left corner of the screen, similar to chat-messages. The quotation-marks are necessary, so please include them always.
target - the name of target that shall read the text, written in the macro-language
text - the message that shall appear
If the player is in the tactical-mode or in the strategy-mode, the messages won't be displayed on the screen, only on the console, so avoid writing mission-critical informations by this method!
HUD ( "target", x, y, "text" );
Display positioned text on the target's HUD. This avoids that an important information drops by the eyes of the player.
target - the name of target that shall read the text, written in the macro-language
x, y - coordinates, where the text is placed on the HUD, the upper left corner of the HUD is (0|0), the lower right corner is (640|480)
text - the message that shall appear
You may format the text with the color-signs (e.g. ^1) and line breaks (\n).
set_field ( "target", "name", "value" );
Fields are your run-time variables to save different things like status, targetnames, ... . Use this function to assign your fields values.
target - the name of target where the field is saved, written in the macro-language
name - the name of the field, for global fields you have the freedom of choice; entity-bound fields (saved directly at a unit/object) are restricted to these special fields:
classname
origin
model
model2
spawnflags
speed
target
targetname
message
team
wait
random
count
health
light
dmg
angles
angle
targetShaderName
targetShaderNewName
value - the value you want to assign, you may save everything you can write in normal ASCII
The maximum number of global fields allowed is 64.
remove_field ( "target", "name" );
Since the number of fields is limited, you should remove fields you don't need any longer. Removing a field will also make a 'field'-function in a trigger return false.
target - the name of target where the field is saved, written in the macro-language
name - the name of the field, the same name rules as for the 'set_field'-function are applied
end_game ( "target", "status" );
This will end the game for a certain team.
target - the name of the team, the name is specified in the .ini-file
status - there are two options:
win
loose
The game will last until all teams have got the signal to end. Players whose team has ended the game will spectate until the others are done as well. This allows you to create objectives for different teams that aren't opposite to each other. Both teams could win or loose.
control_level ( "target", level );
Changes the level of interaction the players of a team have. This way you can create intro-sequences and cut-scenes.
target - the name of the team, the name is specified in the .ini-file
level - the control-level the players of the team get:
0 - none, auto-set value at the start of the game, avoid to set this again
1 - waiting, no interaction to the game (watch cutscene)
2 - playing, full degree of interaction
3 - won, can still play
4 - lost, can still play
start_timer ( "target", secs );
Start a mission timer for a certain team.
target - the name of target at which the timer shall be assigned to (teams only), written in the macro-language
secs - time at which the timer will start to count down in seconds, if you use '-1', a previously stopped timer will start at the time where it was stopped
end_timer ( "target");
Stop a mission timer for a certain team.
target - the name of target at which the timer is assigned to (teams only), written in the macro-language
A stopped timer can be continued with start_timer (<target>, -1);.
build ( "class", (x y z), (pitch yaw roll), "team", flags );
Request a build-call for a team. The request will be treated like one that has been issued by a player during the game. This means you can only build what you are allowed to and if you have the money for it. This function will be very useful to give an AI-controlled team build-abilites.
class - the classname of the unit/building/equipment you want to build. Corresponding to the current list of Units and Buildings are this namely:
BeamPortal
MgunTurret

Soldier
RocketInfantry
Grenadier
RailInfantry
PlasmaGunner

ammo_bullets
ammo_rockets
ammo_grenades
ammo_slugs
ammo_cells

item_armor_shard
item_health_small
x y z - where the object should be placed, applies only to buildings
pitch yaw roll - how the object should be placed, applies only to buildings
team - the name of the team, the name is specified in the .ini-file
flags - special flags to change or determine the way the object is built, add the numbers of the properties you want to apply together, here is the list:
4 - create for free
8 - create scripted, executes only, if there is no human playing in the team
The things built due to the call of this functions will appear directly where they are built. This means, if you build a unit it will appear at the building where units come out (e.g. teleporter). Buildings are placed by the coordinates in the function-call.
create ( "class", (x y z), (pitch yaw roll), "team", flags, "name" );
In effect, 'create' does the same as 'build', the simple difference is that you are getting the request immediately without cost and no matter if you could build it. This makes this function suitable for pre-mission setups, place enemy units over the map, give the player a pre-built base and so on.
Request a build-call for a team. The request will be treated like one that has been issued by a player during the game. This means you can only build what you are allowed to and if you have the money for it. This function will be very useful to give an AI-controlled team build-abilites.
class - the classname of the unit/building/equipment you want to build. The Units and Buildings you can create are the same as defined in the build-function (see above).
x y z - where the object should be placed, applies only to buildings
pitch yaw roll - how the object should be placed, applies only to buildings
team - the name of the team, the name is specified in the .ini-file
flags - special flags to change or determine the way the object is built, the flags are also the same as for the 'build'-function, although 4 (create for free) is useless here, special flags only working with 'create':
32 - place units/items directly at the x y z-coordinates, turn them to the pitch yaw roll-angles
name - if you want to give the object after it's placement a name, so you could create a mission-critical building that needs to be destroyed
group ( "target", "team", "group", radius, flags );
Group units with this function. A group will be easier to command, than several single units.
target - the name of the object you want to add, written in the macro-language
team - the name of the team where the target belongs to, the name is specified in the .ini-file
group - the name of the group, you're free to choose, you may add a unit to an existing group by using the group's name again
radius - currently not used properly, set to zero
flags - currently not used properly, set to zero
A unit that is in a group can't be added to another group.
un_group ( "group" );
Ungroup, all units are free again. Use this if you need the units of this group in another group.
target - the name of the group you want to ungroup
order ("unit", number, radius, "trgt", (x1 y1 z1), (x2 y2 z2), flags);
Give a command to a unit or a group. This is the only way for an AI-controlled team to get the initiative and attack the enemy. Orders are only executed of there is no human client on the team.
unit - the unit(s) that you want to order, written in the macro-language
number - the order itself, identified by a number, each order requires different parameters that are explained here as well:
11 - attack, the unit will seek a moving enemy and kill him, parameters:
trgt - name of enemy, written in macro-language
12 - move, the unit will move to that position and guard the area around it, parameters:
x1 y1 z1 - destination to move to
13 - destroy, the unit will advance to the standing object (building) and destroy it, parameters:
trgt - name of enemy, written in macro-language
radius - meaning and usage differs, see the orders
x1 y1 z1 - meaning and usage differs, see the orders
x2 y2 z2 - meaning and usage differs, see the orders
flags - influence the way the order is executed, add the numbers of the properties you want to apply together, here is the list:
65536 - execute the order also if there is a human playing in the team
'attack' and 'destroy' are pretty similar in their effect, but the AI works differently in the chasing and destroying of the target.
jump ( "target", "jump_target", (x y z), (pitch yaw roll), flags );
Re-position a client in tactical mode or sattelite-mode to a special position and in certain angles. The main use will be the cutscene arrangement.
target - the name of the client you want to reposition, written in the macro-language
jump_target - name of a special target to teleport to
x y z - coordinates to teleport to, if there is no 'jump_target' specified
pitch yaw roll - angles the teleported object should have after the jump
flags - influence the way the jump is executed, add the numbers of the properties you want to apply together, here is the list:
1 - allows the positioning of any object no matter which state it is in
follow_path ( "target", "path" );
Make a client follow a path. The main use will be the cutscene arrangement. The client will follow the path 'till it's end and wait there until he gets new orders. If the path is a looping path, the client will move go from the last waypoint to the first point of the path and continue his movement until he gets new orders.
target - the name of the client you want to move, written in the macro-language
path - name of the path you defined, plus the number of the waypoint where the movement shall start (e.g. flightpath2 - will start the movement on flightpath at the second waypoint), the path has to be specified before the event else it won't be recognized
The path-movement will only work properly if the player has been set to 'wait' with the 'control_level'-command.
The number of events you may use in a script has been limited to 128.
The event also ends with a closing brace.
}

the macro-language

The macro-language in TSW is a simple but very useful tool. It allows you to define targets and file-groups with just some keywords.

keyword:[keyword:[keyword:[...]]]targetname
This is the general syntax. All keywords in the macro-language start with the '$'-sign. The keywords are divided by double-points (':'). Each search-phrase requires one terminating real targetname.
keyword - a specifying keyword, for target searches, the keywords start with $T:
$Tent - search for all entitys (units/buildings/objects)
$Tclient - search for all clients
$Tteam - search for a team, if included after entity-search the targetname will be the team of that entity
$Tgroup - the targetname will be the name of a group
$Tclass - the targetname will be the name of a class
$Tname - the targetname will be the name of the object you are looking for
$Teach - the action that you want to perform on the target will be executed on all targets, not only on the first one

$Tglobal - special keyword, stands alone without targetname, used for global fields
targetname - the real name of the target you are searching, assigned by the map or in the script (e.g. 'create'-function), there is also a special targetname
$Tall - return everything that fit the specified keywords
Examples:
set_field("$Tglobal", "succ_for_blue", "1");
sets the global field 'succ_for_blue' to 1
$Tent:$Tname:teleporter1
searches for an ent that has the targetname 'teleporter1'
$Tent:$Tclient:$Tteam:Humans
searches for all clients that are in the team with the name 'Humans'
$Tteam:$Tname:Humans
searches for the team with the name 'Humans'
follow_path("$Tent:$Tclient:$Tall", "test0");
all clients will follow the path 'test' starting at point 0
order("$Tent:$Tgroup:$Teach:red_2",12,0.0,"",(28.....
each unit of the group 'red_2' will move out to a certain point

The documentation provided here will only give you the basic understanding of the script-language and the macro-language. To learn more, read the .scr-files you find in the .pk3-files and edit and test by yourself.
Don't forget to use the
message-board to talk to other 'modifiers'.

website design : images : screenshots are copyrighted by "shattered wings" © 2000
Quake(tm), Quake 2(tm) and Quake 3: Arena(tm) symbols (the stylized 'Q's) copyright © 1996-99 Id Software, Inc.
Quake(tm), Quake 2(tm) and Quake 3: Arena(tm) are registered trademarks of Id Software, Inc. All rights reserved