You are on page 1of 90

The Developer's Handbook

Copyright © Penguin Development Team. All rights reserved.
Contents
Contents........................................................................................................................................... 2
Introduction...................................................................................................................................... 3
About This Document.............................................................................................................. 3
File Types................................................................................................................................ 3
TAGAP_Script................................................................................................................ 3
Graphics........................................................................................................................ 3
Audio.............................................................................................................................. 3
General Editing Guidelines......................................................................................................4
Creating Levels................................................................................................................................ 5
Level Editor............................................................................................................................. 5
Linedefs.................................................................................................................................. 6
Entities.................................................................................................................................... 7
Triggers................................................................................................................................... 8
Multitaps.................................................................................................................................. 9
Textures................................................................................................................................ 10
Setting Up Properties............................................................................................................ 12
Importing Textures.................................................................................................................13
Editor Setup.......................................................................................................................... 14
Using Triggers................................................................................................................................ 16
Basics of Scripting.......................................................................................................................... 39
Introduction to scripting......................................................................................................... 39
Weapons scripting.................................................................................................................39
Sprites and animations..........................................................................................................40
Skeletal limb system.............................................................................................................. 41
Entity-within-entity objects.....................................................................................................44
Transformations.................................................................................................................... 45
Sequences............................................................................................................................ 45
Appendices.................................................................................................................................... 48
Appendix A: Editor Controls..................................................................................................48
GUI controls.................................................................................................................48
General editor controls.................................................................................................48
Geometry mode........................................................................................................... 48
Texture mode...............................................................................................................49
Appendix B: TAGAP_Script Syntax.......................................................................................50
Entity commands.........................................................................................................50
Limb commands........................................................................................................... 68
Definition commands....................................................................................................71
Scripting commands.....................................................................................................76
Appendix C: Configuration variables.....................................................................................81
Setup variables............................................................................................................ 81
Editing variables........................................................................................................... 82
Appendix D: Essential Software............................................................................................85
Retail software.............................................................................................................85
Free software...............................................................................................................87
Appendix E: Glossary............................................................................................................ 89

[ 2 / 90 ]
Introduction
About This Document
The name says it all; “The Developer's Handbook”. Origins of this manual go as far as the very first
code snippets of the original TAGAP release in 2007. This isn't so much a user guide to editing,
this was developer's journal about the technology and development progress. However, I realized
quite soon that this thorough journal could be used, with few additions, as complete guide to the
engine and to make lives of Modders a lot easier.

In an essence, this is the same document as the one shipped with the original TAGAP, only
updated according to engine changes. I've tried my best to explain new features as thoroughly as I
can and attempted to point out the most obvious and crucial differences between how things
worked in the past and how they are handled now.

But it's still “The Developer's Handbook”; If you're not going to make any levels or game
modifications for TAGAP 3, you can quit reading now. If you dare to continue, I sincerely hope you
find this documentation at least remotely useful during your quest for fun gameplay.

File Types
While many modern games are made of dozens of formats, we kept TAGAP 3 as simple and
clearly oriented as possible to ease working on it. In case you lack some software to work on the
specified formats, we have listed most most freeware tools used to create TAGAP 3 ( see: Appendix
D: Essential Software).

TAGAP_Script
TAGAP_Script is simple external scripting system created for TAGAP Engine. Everything from
system configurations and entity scripts to levels and even cut-scenes are made of this “language”.
The extensions vary so you can right away see what they are used for; Level files are .map,
configurations .cfg and scripts simply .txt. They are all simple ASCII text, so any Notepad-styled
program works fine for scripting, while for making levels TAGAP 3 features built-in level editor.
Usage of TAGAP_Script is explained more in section Basics of Scripting and you can find complete
list of TAGAP_Script commands from the Appendices section (see: Appendix B: TAGAP_Script
Syntax).

Graphics
Almost all TAGAP graphics are in Targa TGA format (.tga), with either 24bit (solid) or 32bit (with
transparency) colours. Note that OpenGL needs textures and some effects to have “power of two”
dimensions (i.e. 16, 32, 64, 128, 256...), but there isn't such restriction with sprites, particles etc.
TAGAP supports RLE compression and usage of it is strongly recommended; The files are
remarkably smaller and there is no image data loss.

For sequence script images you can also use JPEGs, GIFs, BMPs and PNGs. To keep things
consistent, it is recommended to stick to TGAs for the most part, but for example for bonus content
(art galleries and the like) using JPEGs might be a great idea in order to minimize distribution size.

Audio
TAGAP Engine uses 8 and 16 bit samples of 22050 Hz, ambient and cinematic stereo streams of
22050 Hz and streamed music of 16 bits and 44100 Hz. Samples should be mono as the engine
handles all the stereo panning according to sound source, but global streams (like music and

[ 3 / 90 ]
ambient) can (and should) be stereo. Preferred audio format is OGG Vorbis codec (.ogg) of any
compression rate. Windows Wave (.wav) is also supported, but as it results very large files it's
recommended to use Vorbis instead in your distributions.

You can add loops into music files via id-tags. Tag “START” defines where the loop starts and
“END” defines the endpoint, both in milliseconds. Start of the file is 0 and end of the file is sound
file length in milliseconds minus one milliseconds (i. e. end of 1.5 second sound is 1499, not 1500).

As a new feature in TAGAP 3, we also have a new id tag “AUTO”; This defines how the dynamic
music system handles the audio streams. Automatic streams – the default setting for music –
consider the two streams as 'action' and 'calm', automatically switching to calm music when out of
the game (i.e. watching an in-game cut-scene or reading an InfoCOMP). When automation is
turned off, the only way to affect the music is by using 'ost' triggers ( see: Using Triggers: ost). You
can set automation off by setting “AUTO” to 0. If the audio file has no “AUTO” tag, it is assumed to
behave as 'automatic'.

Audio of TAGAP_Engine is powered by magnificent FMOD Sound Engine from Firelight
Technologies. For more info visit official FMOD site at http://www.fmod.org.

General Editing Guidelines
TAGAP 3 game modifications fall into two categories; Extra levels and Mods. To keep things as
user-friendly as possible, it would be appreciated that you won't do anything in between.

Levels should be strictly that – levels. I know many of level makers would love to add new textures,
but if you do, make it a Mod instead. If every level author out there just slaps their textures into
game's main texture folder, players soon end up with TAGAP 3 loading 1 Gb pile textures only one
or two levels use.

When creating Mods, you can do whatever you wish, just don't alter the files in TAGAP 3 data
folder (i.e. “C:\Games\TAGAP 3\tagap3\”); If you want Pablo to have a “Hello Kitty” tattoo on his
belly, don't add it to the original sprite, but make a duplicate of it into your Mod-folder and edit that
duplicate. This way the original game never gets broken and users can easily add and remove
Mods.

[ 4 / 90 ]
Creating Levels
Level Editor
Level editor of TAGAP 3 is, like with its predecessors, built-in to the engine itself. This means that,
once activated, you can jump between the level and editor by push of a button.

To access the level editor, you'll need to run TAGAP 3 in what is called 'The Developer Mode'. This
mode activates the level editor and associated features and disables achievements and game
stats updating (for obvious reasons). Depending on how you obtained and installed TAGAP 3,
there are three ways toto activate the Developer Mode;

• If you installed the game with the installer (“TAGAP 3 Setup.exe”) and you chose to install
the Start-menu shortcuts, there will be “Run in Developer Mode” option available in the
your Start menu, under “TAGAP 3” folder.

• Also, if you chose not to install shortcuts, didn't use the installer or just want to create a new
shortcut for the Developer Mode, simply create a shortcut to “TAGAP3.exe”. In the
shortcut options, add “+user_developer 1” (without quotes) after “<your
path>\TAGAP3.exe”. Just remember to a space between the command line and the .exe.

Once the Developer Mode is activated, level editor will be available both from main menu and
during the game by pressing F6 . The latter works the other way around as well, taking you to the
game if pressed while in the editor. While testing out the levels and mods, it might be a good idea
to activate the cheats as well. Also, creating additional shortcuts to access in-progress levels is
always recommended. To use all of these just add the related CVars ( see: Appendix C: Configuration
variables) to the command like after “+user_developer 1”, all obeying syntax “+<variable name>
<value>” and separated by a space.

[ 5 / 90 ]
Linedefs

1. Selected linedef appears as bright, thick line with arrows showing the facing and a thin square
highlighting the end you are currently dragging
2. Linedef index
3. Toggles the type of the linedef (floor or ceiling)
4. Style of the linedef
5. Nudge linedef around by one pixel (hold Ctrl to nudge by half a grid unit)
6. Coordinates of the line's starting point
7. Coordinates of the line's end point (show here bright because it's the end point that is being
dragged)
8. Length and vector components of the linedef as both pixels and grid units
9. Parallax guide is shown in the background as thick dashed line

Linedefs, short for “line definitions”, represent the basic physical world; Horizontal linedefs act as
floor or ceiling, while vertical ones are walls. The facing, shown as arrows, tells from which
direction the line is blocking. For example, a horizontal line defined as “Floor” stops movement
from above and as a vertical line it will block anything attempting to pass it from left.

Lines are defined in Geometry; Just point at the starting point and hit Space , then point at the end
point and hit Space again. Once the line is defined you can drag it around as a whole by clicking it
and moving the mouse, or you can move its points independently. Setting the line facing is
important and can be done with selector or by with C .

You can browse the defined linedef styles by the style selection buttons or with , and . . For
more information on creating your own linedef styles, see FLOOR. Note that a couple of linedefs
styles are set to be interactive only with entities tagged as 'non-blocking' ( see: AI_NONBLOCKING of
STAT) for specific kind of scenarios.

The parallax guide defines the y-offset below which the parallax layers and backgrounds ( see:
LAYER, Using triggers: background) no longer obey the camera movement. In-game it's like dropping
beneath the ground level, the structures in the background getting the farther above your head the
further you fall. To relocate the guide, simply point to a desired spot with the mouse and press ~ .

[ 6 / 90 ]
Entities

1. Selected entity is bright and has visible bounding box
2. Description of selected entity (since majority of entities in TAGAP 3 are dynamic, there is no
preview image shown anymore)
3. Green dots are game characters
4. Turquoise dots are items
5. Miscellaneous objects appear as white dots.
6. Player start point appears as yellow dot
7. Name of current entity (click to change the entity)
8. Changes the facing and/or starting angle
9. Entities can start as active or inactive
10. Nudge entity around by one pixel (hold Ctrl to nudge by half a grid unit)
11. Trigger linked to the selected entity (remove link by selecting “Delete”)

Entities represent most characters and objects in the game and range from player character and
enemies to items and decoration. You can also select and edit properties of multiple entities at the
same time. To add an entity, hit the either E (for actor entities), I for items or D for
miscellaneous objects and decoration. The entity appears as red “undefined” entity at first, but you
can select the right from the entity list. The player start point is relocated with Ins . You can also
copy the currently selected entity by pressing G – and use E , I or D to paste. Entities can
start the game either as active or inactive. Inactive entities require a trigger impulse to be awoken.
Solid entity dots represent active entities and hollow dots are the inactive ones.

You can change the type of the entity either by clicking the its name or by with keys , and . . The
latter browses only the common entities available for listing, but if you hold down Shift you can
browse even the entities that are non-listed by default (see: NOLIST of STAT).

You can also link entities to triggers. This becomes important for many reasons. The most common
entity-trigger links are area triggers defining the range of movement – or in case of, say, laser
beams, the actual range of the attack. All other types of triggers will be 'used' on the death of the
entity, so if you want to make something to happen upon death of say, a boss, this is how you'll do

[ 7 / 90 ]
it. If you'll need both restricted movement AND an event on entity's death, use the always trigger.

To link a trigger to an entity, select the right entity, point inside the desired trigger with the cursor
and hit L . To remove the link click the 'Delete' button above the entity link description – this
removes just the link from the entity and not the linked trigger.

Triggers

1. Selected trigger appears as bright and bold
2. Functional triggers are purple
3. Decorative triggers are green
4. Sound related triggers are turquoise
5. Exit trigger appears yellow
6. Water areas are shown blue
7. Map area definitions are shown light blue
8. Navigation system pointers are shown light green
9. Player/entity blocking triggers are shown orange
10. Areas that force player to slide are shown burgundy
11. Name of the trigger and its index number (click to change the trigger type)
12. Coordinates and dimensions of the trigger
13. Normalizes trigger field dimensions to defaults.
14. Nudge trigger around by one pixel (hold Ctrl to nudge by half a grid unit)
15. Each trigger style has it's own, unique set of options to modify their attributes

Triggers form the functional core of TAGAP Engine. Their purpose varies from simply appearing as
decoration to triggering complex scripted events. In this chapter we talk about the basics of
handling trigger fields, for thorough explanation of all trigger types, see Using Triggers. For
TAGAP_Script syntax of triggers see: TRIGGER.

All trigger fields are rectangles, so to define one you need to give it two points, just like with
linedefs, only this time press T to add corners. Also like linedefs, triggers can be dragged around
as whole or resized by dragging the corners. If the trigger in question is a decorative trigger

[ 8 / 90 ]
utilizing entities (i.e. guide), you can browse through entities by clicking the name of the entity in
the trigger options section or with , and . . Like with entities, by holding down Shift you can
browse even the entities that are non-listed (see: NOLIST of STAT).

Some triggers, i.e. trigger or button, will require a target link. To define one for currently selected
trigger, simply point the desired entity or area inside desired trigger and press L . Not all triggers
can be linked, though. Also, in many cases you may have multiple trigger fields overlapping,
meaning the engine may not automatically pick the trigger you want. In such case, use Shift + L .
This goes links the overlapping triggers in order; just keep hitting Shift + L until the one you want
becomes the link target. Most link-using triggers can be linked to multitaps; If so, there is ‘Select
multitap’ option available. Note that triggers that require a link but are yet-to-be-linked appear red.

Some times your trigger scripting can get colossally complex, especially when you are doing a full-
length campaign with a hub you keep returning to. It can lead to your level looking like this;

Figuring out how this kind of mess works seems impossible – especially if either you didn't create
the level or you did do it, but so long a time ago that you can't remember. But you have two helpful
tools for figuring this out; commands “Find target” F and “Find owner” O . These commands find
the owner and/or the target of a selected object (trigger, multitap or an entity).

Multitaps

1. Number of links in current multitap
2. Multitap index and selection
3. Adds a new, empty multitap
4. Deletes current multitap
5. List of linked objects with their indexes
6. Removes link from multitap

[ 9 / 90 ]
Multitaps, named after the retro console accessory of the same function, allow you to connect
multiple objects into one trigger. Each multitap can have up to 12 links and as each linked object
may also be linked to a multitap, you practically add unlimited events for one trigger. To bring up
multitap editor, press M while in Geometry mode. To add a new multitap, click “Add” or browse
through available multitaps to select previously defined one. Linking objects to multitap works just
like with triggers; Point the entity or trigger you want to link and press L . If there are overlapping
trigger fields you may have to link them both first and remove the incorrect one afterwards with
“DEL” button. Triggers that can be linked to multitaps will have “Select multitap” option in their
options.

Textures

1. Thick white border outlines the selected polygon
2. Zoom window helps texture placement
3. Name of current polygon's texture (click to bring up the texture list)
4. Rendering order; Larger the index, more front it is
5. Moves to the back of the rendering list
6. Moves to the front of the rendering list
7. Polygon point used as texture offset
8. Toggles texture shading on/off
9. Flip the texture horizontally (texture only, not the polygon)
10. Polygon texture alignment toggle
11. Polygon texture tag setup
12. Nudge polygon around by one pixel (hold Ctrl to nudge by half a grid unit)
13. Information on all the polygon's points (corners)
Texture polygons are the basic graphical building elements. The shapes can be anything from a
triangle to hexagon and hold any of the texture images found in the game's texture folder. Drawing
shapes is simple; Just point with mouse and press Space to start polygon and hit Space again to
add a polygon point. To close polygon either hit Enter or point at the first point and press Space .
All polygons can naturally be dragged around as a whole or by individual points. The texture is
aligned according to defined offset point. You can use any corner of the polygon ( 1 to 8 ) or the
world offset ( ~ ).

[ 10 / 90 ]
When creating large levels you'll really start to appreciate the quick tools. First is rectangle tool,
with which you can define rectangular polygons just by defining two corners (press T or R two
times). All shapes can also be copied and pasted ( G gets the current polygon and P pastes)
and flipped horizontally ( H ) or vertically ( V ). You can also get the current polygon's texture ( D )
and fill some other shape with it (select polygon to fill and press F ). Like with entities and entity
triggers, you can browse textures with , and . . This way you can access even the engine-
defined textures (entity bases, floors, etc.) that aren't normally shown in the quick selection list.
Finally, you can cycle through polygons with PageUp / PageDown or the mouse wheel – and even
view the wire-frame edges of the polygons by holding down the middle mouse button.

Bigger and more complex the level gets, more you will wrestle with the texture rendering order.
Think about it as a stack of cards; Smaller the number number, lower in the pile the texture is and
everything stacked on it will be rendered over it. You can move the texture in this 'pile' either with
the “Order”, or if you need to move it more than a couple places, hold down Shift and press
PageUp or PageDown (or use mouse wheel) to re-place the texture a lot faster. Finally, you can
always 'cut and paste' the texture into its place. First create the texture polygon, select it, copy it
with G and finally delete it ( Del ). Next select another polygon next to the wanted slot in the pile
(i.e. if you want the polygon to be in slot #98, select polygon #99) and paste the polygon in
memory with P . The polygon is always pasted one slot prior to the one selected – or if no
polygons are selected, to the end and front of the pile.

One of the most important things to observe is usage of shaded textures; Shaded ones should be
used for things in background, while bright ones should represent either the foreground or things of
importance. This gives the scenery certain illusion of depth. Also note that the Overdose effect
uses these values to pick the colours, so not paying attention to balance will definitely make the
scenery look awkward whilst player is in Overdose. You can check the Overdose view in the editor
by holding Ctrl .

There are three special textures you should also familiarise yourself with. First one is called
“(fade)”; Like the name says, it's used to fade scenery from bright to black or just to dimmed.
Easiest way to control fading is to draw a rectangle by starting with the line representing the side
that will be bright, completing the polygon and setting texture offset to “2” (press 2] . Shaded fade
is rendered as “shade” instead of solid gradient and is ideal for making shadows for illusion of
depth. A “(fade)” with world offset ( ~ ) will be rendered as solid black.

The second special texture is called “(shade)” - or it's lighter variant '(shade3)”. Think the shade
texture as an edge outline; it can show up either as a highlight or a shade. For example, you want
to create an illusion of a textured rectangle being embossed, add “(shade)” edges to it – highlight
to the top edge and shades to others. Also, accenting all physical walls with “(shade)” gives them a
more natural and smooth look. This really sounds more complicated that it actually is and after a
couple of experiments you should become comfortable with it.

Third special texture tool, which is new in TAGAP 3, is “(seam)”. It's essentially two shades
opposing each other, creating a pillow emboss effect. This is a very useful tool, allowing you to add
plenty of seam-like details to the levels with half the polygons used; instead of drawing two
“(shade)” polygons next to each other, you can simply add one “(seam)”.

By default, textures are rendered non-aligned – always straight regardless of the polygon's shape.
However, you can also render them aligned according to the first side of the polygon. This way you
can tilt the textures in an angle depending on your needs.

Tagged textures are used to form a bridge between the otherwise-non-connected Geometry and
Texture modes. To do this, we will use a combination of tagged textures and special trigger textag.
To do this, create a texture you want to affect with scripting and turn its tag on. Next, create a
textag trigger with the desired options and ensure that at least one of the polygon corners is inside
the trigger's area. And that's it – to toggle the texture or its overlay effect on/off, just trigger the

[ 11 / 90 ]
textag trigger.

Setting Up Properties
In Properties mode you can edit various global attributes that define how the level looks, sounds
and above all, plays. Always remember that many of these options serve as start-up details and
can be manipulated on the fly during play.

Basically the main window is split into three sections. At the very top is the title of the level shown
in the beginning (use “Untitled” for no title at all). As a new option in TAGAP 3, you can add a level
icon to the title as well; just added the desired 'Pluto department title' at the end of the title (for
example, title “General_HospitalPDOH” appears in the game as a title card 'General Hospital” with
a PDOH icon. You can add your own icons as well, but they have to follow the 'PDO*' format.

Next up is the level file name, file name of the next level (the level loaded by exit on default, or by
editor command F5 ), the default sequence to load between the levels and the file name of the
music to play. You don't need to type these options in manually, use “Browse” buttons to bring up
lists of available files.

Next up are the three first image layers. These are the ones used as default parallax backgrounds
unless they are disabled from them. For each layer, first there is image layer index (which is
referred to by triggers like layer) followed by the image file name (in folder “tagap3/art/layers/”).
Below are the options to manipulate how image will appear; Scroll defines how strictly parallax
image mimics the movement of the view. Offset is pixel interval between the image and the top of
the view. The two move values give the image constant scroll on x and/or y axis. Finally there's
additional rendering flag. These flags don't affect all background rendering options, mind you,
mostly just regular parallaxes, but feel free to experiement. The rendering flags are as follows;

“Normal” (default) normal rendering without customisation
“Additive” uses additive rendering (similar to HARDLIGHT of SPRITEVAR)
“Stretched” an overlay stretched over the whole scene (i.e. a vignette or a static element)
“Disabled” not visible as a parallax or as a sequence layer

Only the three first image layers can have these values, the rest will always be “Disabled”. Simply
click “More layers...” to add and edit the rest of the image layers. It's also important to note that if
you render backgrounds / parallaxes using window triggers with layer offsets, even these 'offset'
layers will refer to the movement information of the first three layers.

Next section has options to edit level theme settings. First button defines background parallax
rendering method;

“None” (default) disables background parallax (parallaxes can still be added with windows)
“Vortex” time vortex / FTL effect of multitextured colours
“Parallax” classic parallax rendering (this is what the layer flags are designed for)

Scheme defines the default level theme used at level start (see: THEME).

Below this there are three utilities. The first one, Center map to origin, re-positions everything
(geometry, entities, textures, the works) using the current player #1 starting point as origin (x 0, y
0). The second, Start from scratch does just that; trashes everything and gives you a clean slate
to work with. And finally, new to TAGAP 3, there is Mirror, which again is self explanatory; It
mirrors the level content on x axis. This is particularly useful when creating scenes seen through
rifts.

Finally, there are the special campaign progression rules. These are the simple strings that makes
the 'pseudo-Metroidvania' progression work. First one is Progress (“NONE” by default). This gives

[ 12 / 90 ]
the level a 'progress tag' which the player will receive once he/she/it completes it. These progress
tags can then be used trigger different things with state triggers. Tags are singular letters, for
example in TAGAP 3, completing the PDOH episode nets you the tag 'H'.

All the tags are permanent for the playthrough. If you want to create a temporary tag – one that is
exists only for the opening of the following level – use numerical tags (i.e. '1'). One tag has a
special meaning for game progression; tag 'T' determines whether you have the PTB hub recall
device or not. If you don't want the level completion to give the player any kinds of tags, use
progress “NONE” (default).

And lastly, there's Recall rule. This defines what progress tags the player needs to have in order
for the PTB hub recall option to become available. For example, TAGAP 3 is structured in a way
that you can't use PTB until you've completed that episode once already – meaning recall rule for
PDOH maps is 'H'. This means the player needs to have at least the tags 'T' and 'H' before they
can use PTB in those maps.

In the bottom window, at default, you can find the entity related global settings. Custom entities
defines the set of custom entities to be used (see: CUSTOMENTS) – in case you need to have
different rewards etc.

Next up are the cannon fodder settings; The first sets the default cannon fodder, next defines the
starting spawning interval and the third defines the direction of spawning. Enemies can be set
to spawn from edges of the screen (default) or to fall from the sky or from all around the player.

At the very bottom there are the options to tweak the selected cannon fodder setup with custom
entities that are spawned when they're called for ( see: CANNONFODDER). Tool fodders will
override FODDER_OPTION1 and FODDER_OPTION2, while the much-less-frequently-used
Powertool fodder overrides FODDER_OPTION3. If you aren't planning to start scripting, all you
need to know is these are the level-specific zombie penguins that appear randomly in the levels –
tool fodders are the regular kind while the powertool variants are those armed with
sledgehammers, eBatons and cleavers.

And very lastly, at the bottom right corner, there is a small preview window. By default it shows a
preview of the default set cannon fodder – listing the entities the chosen fodder will spawn.
Alternatively, you can view the Statistics in this window. Whilst in earlier versions of the engine
keeping track of the amount of objects (textures, linedefs and so on) was important, TAGAP 3
supports levels so huge that you likely won't run into any array size limits any time soon. Still, it's
always good to check out what your level is made of from time to time.

Importing Textures
As a new option in TAGAP 3, you can import whole maps worth of texture polygons to your current
level with a simple push of a button. However, it takes a little explaining to detail how the system
works.

First, the core purpose of the function. If you've played TAGAP 3, you've likely noticed that there
are some room elements that are uniform in design. This isn't laziness, part of the design
language; Pluto is meant to feel like a whole and thus sharing basic functionary room layouts is to
be expected. Most notable example of this are the secured weapon closets, that follow the same,
almost uniform design. Some are longer, some are shorter, but the basics are the same.

In the old TAGAP engines, there were two ways to achieve this. One, less dynamic one would be
to create the assets of the room as a layer or guide – a single art asset that could be dropped into
place. Alternatively, I could simply re-create the room from polygons every time. Neither option was
great. Separate art assets would've been huge (eating a lot of memory and extending the load
times) and likely would stand out in comparison to the texture based surroundings. The manual

[ 13 / 90 ]
recreation of the rooms, on the other hand, would've been time consuming as hell.

So instead we created the option to create separate level snippets which you can then import to
your levels, with full texture set intact and ready to go. So to do this, first create the level snippet
you want to import. In this case of secured storage lockers:

1. I loaded the level such room first appeared in and saved it under a new name (in this
case let's use an example name “_import_sec_room1”).

2. Once the level is saved under a new name, strip the level from EVERYTHING besides
the textures you wish to import. In this case I didn't want to import anything but the
shaded walls inside the room, so I used Ctrl + Shift + Home , Ctrl + Shift + End ,
Alt + Ctrl + Shift + Home and Alt + Ctrl + Shift + End to delete everything around it
– textures, walls, triggers, the lot.

3. Next you need to re-set the level content to the origin (x0 y0). To do this, re-position the
player to a point you want to use as a reference (by using Ins ). For sake of simplicity, I
always place the player to the BOTTOM LEFT corner of the area to be imported. Now,
press F3 and from the settings choose “Center map to origin”.

4. Save – and you should have yourself a ready importable level snippet in polygon form.

Now that the level snippet is ready, open up the map you wanted to import it to and go to the
texture editing mode with F2 . Point the cursor to the point you want the polygons to be imported.
Like I mentioned above, I always use bottom-left corner of the area, so I point that grid point with
the mouse.

Next, simply press F4 – this brings up the map file list. Simply choose the snippet we created
earlier (in the example, “_import_sec_room1”). And that's it. Now the texture data from that snippet
are copied over, using the previous mouse pointer as an origin reference.

Whilst we started by using this on the secured lockers, this function became a true lifesaver in
other areas as well. For example, setting up those complex ventilation systems was a lot easier,
when the big, round chambers were ready to be placed with a press of a button. Also,
implementing all those war ships in the PDOD levels would've been a nightmare without this
function.

Editor Setup
Developer Mode itself has its own setup screen that can be accessed from the bottom-right menu
of the level editor or at any time – including during gameplay – by hitting F8 .

First three options are for visual developer to be used during gameplay. FPS display toggles the
framerate counter (frames-per-second), Sound CPU toggles the display of how much CPU power
the sound engine is using and Show bounds toggles the rendering of the entity bounding and
visibility boxes and light origins. Sound CPU and FPS display counter selections are stored into the
config file so the game remembers how you left them, but Show bounds resets to 'off' on startup.

You won't need Sound CPU measurement much, though; it was there mainly to balance things out
during development. The other two, on the other hand, are vital. To quote Richard “Levelord” Gray:
“Framerate is God”. If you create a level with insane geometry and plenty of fancy effects, the
framerate WILL dip below playable and that's never a good thing in a game.

The bounding boxes are something that you have to get just right, too; use a bounding box too
small and your attacks will go through enemies. And the visibility boxes are even more crucial; they
determine the rendering area of the entity. If the visibility box is smaller than the actually rendered

[ 14 / 90 ]
object, the object will awkwardly pop into to view on the screen edges. Alternatively, too large a
visibility box forces the engine to render that object even if it isn't on screen. It doesn't hurt to take
a screenshot of the entity ( F12 ) with “Show bounds” on and inspect the results closely with
Photoshop.

In TAGAP 3, toggling on the bounding boxes also displays the entity limbs in their wireframe form –
basically drawing a stick-figure over the entity, showcasing clearly how the limbs are positioned
and bent. This can come very handy when you're rigging up completely new kinds of characters
with unconventional limb placement.

Now, onwards in the options. Lobotomy is pretty much how it sounds; It turns the AI off on all
entities, including projectiles and even all enemy generators (cannon fodder, spawning triggers,
etc.). Having such an option may sound weird, but it can come in really handy. For example;
You've created a level with geometry and enemies in place – and now you need to place the
textures. Trying to inspect texture placement is hell-of-a-lot easier with all the enemies and enemy
spawning turned off, I can tell you that.

Detailed log is something you should, if you are doing custom scripts of any kind, turn on.
Normally, only key events are logged into the game log (“user/log.txt”) - things like loading an
engine component, loading a script file, starting a new game, errors etc. With this option, all file
handling is logged down; sprites, layers, sound effects, the works. It's always a good idea to see
every once in a while if the script is put together properly to load everything just the way you
intended. Like FPS display, this one is also stored into game config.

Finally, there's Save and launch. If it's 'on', hitting launch in the editor will save your changes
before launching it in the game. Naturally if it's 'off', you will launch the level without saving. Note
that this doesn't affect the quick launch button F6 ; It never saves before launching. This option is
also stored into game config.

[ 15 / 90 ]
Using Triggers
Now you know how to create and modify triggers, but what are they for? Each type of trigger field
has it's own specific purpose and in this section you'll find introductions to them all. Under the
description is trigger's 'on use' function – thats what the trigger does when it is fired by another
trigger or a multitap.

When normalizing the trigger size, all triggers using entities as their visual representations use x
and y values of W_OFFSET (see: OFFSET) as their width and height respectively. If no such values
are defined for the entity – or they are zero – the trigger fields are normalized to engine defaults.
Also, if the entity is operatable (i.e. button, coop1, infocomp etc.), offsets W_ORIGIN_MOD and
W_ORIGIN_MOD_H define the origin and size of the 'use box' respectively.

action
description: Forces actions on player character via scripting. You can define which player to affect as well
as choose the action to be applied (i.e jump, stomp, etc.). While it is NOT recommended to
use these during actual gameplay – thou shall not interfere on player's controls during the
action – they do come in handy while creating in-game, in-level cutscenes with based on
focus.
entity: –
on use: Initiates and enforces the action on the chosen player.

always
description: Works just like field, only this one isn’t turned inactive after being used. If you want some
object or multitap to be fired multiple times without need of adding restore for each toggle,
use always.
entity: –
on use: Triggers its target, stays active.

area
description: An area in which AI entities operate. To make an entity operate within certain area, choose
an entity and link it to that area trigger. Using an AI area overrides any AI_RANGE modifiers
(see: STAT) set within the TAGAP_Scripts. Also, area is handy for defining the movement
range of entities locked on virtual rails (see: AI_RAILS of STAT).
entity: –
on use: –

assist
description: Defines an area inside which you can't call in reinforcements, can't be followed to by allies
(see: AI_ALLY of STAT) or both. The effect area can be set to start on or off.

As an example of blocking reinforcements would be an indoors section in a level that is
primarily an outdoors one and the reinforcement attack summons air support (like in case of
TAGAP2). Alternatively, an example of blocking allies would be a hard-to-reach area that
could lead the ally entity to get jammed.
entity: –
on use: Toggles the effect of the field on/off.

[ 16 / 90 ]
background
description: Background filler layer consisting of entities. You can choose what entity to use, parallax
scrolling multiplier and the cap between entities. Parallax scrolling multiplier works exactly
the same as with background layers ( see: LAYER), so it's relatively easy to match movements
of background entities with the parallax sky behind them.
entity: If entity has FX_NOFACE flag ( see: STAT) set the entities will all face the same direction,
otherwise every other entity faces the opposite direction. Note that entity particle effects
won't work with backgrounds.
on use: Toggles entity on/off.

bouncer
description: Bouncer creates two bouncer walls ( see: FLOOR) that block only the zombie cannon fodder
(see: THINK, CANNONFODDER). While creating bouncer walls directly as linedefs is
preferable, some times you need to have control over them – i.e. toggle the walls on/off
whenever something in the script happens – and you can do just that with bouncer trigger.
entity: –
on use: Toggles the bouncer walls on/off.

breakaway
description: An entity-based custom blockade that can be blown away with explosives. Breakaway can
be either horizontal, vertical or rectangular. Horizontal and vertical triggers act as walls you
can break with explosives, while larger rectangular blocks can be broken only by triggering
them. You can also flip the entity facing and, if you want to add the trigger for decorative
purposes only, set it to non-solid.

Those coming in from editing the first two TAGAPs note that this trigger is completely
different compared to the original. If you wish to create a static texture block to trigger
rendering layer, use the trigger texblock.
entity: The entity range modifiers (s ee: RANGE* of SPRITEVAR) refer to the length (width or height)
of the blockade. When the blockade is destroyed, the entity is swapped to the corpse entity
(see: CORPSE).
on use: The blockade explodes.

brick
description: Solid or non-solid block that moves up-and-down and is represented by the chosen entity. By
default, brick will move like an elevator, but you can also set it's downward movement to
appear as free-falling according to gravity. The moving radius is shown in editor by thin line
drawn from the bottom of the brick. It will move to the other end of the line when triggered,
and back when triggered again.
entity: Entity's sounds are played when the entity moves and stops ( see: SOUND). The movement
speed of the entity (see: MOVETYPE) defines the movement speed of the brick object.
on use: Activates and starts to move to it’s other position.

button
description: Simple button. Unlike trigger, button that can be used unlimited times, like i. e. elevator call
button.
entity: The continuous rotation is stored into the entity's aiming angle ( see: AIM of SPRITEVAR,
FX_FULLANGLE_AIM of STAT). When the entity is broken as collateral damage, the entity is
swapped to the corpse entity (see: CORPSE).
on use: Triggers its target.

[ 17 / 90 ]
bush
description: Entity fill tool, mainly designed for automating vegetation creation, but can be used creatively
for all kinds of purposes. You can set the direction towards which the density of the entities
thickens and define whether the entities are rendered in the default trigger layer, background
or foreground.
entity: The rustling and idling movement of the objects is generated with the angles BIAS and AIM
(see: SPRITEVAR, FX_FULLANGLE_* of STAT) and the intensity of the movement is automatic.
Entity's sound loop (see: S_LOOP of SOUND) is played only when the leaves are rustling.
on use: Toggles all entities in the fill on/off.

clock
description: Adds a clock to the level. It takes its time from system clock, so it should be on time when
the level starts. However, cause time in TAGAP isn’t a constant, time shown will ultimately
be incorrect. Unlike in the original TAGAP, clocks in TAGAP 2 use entities for graphics and
sounds.
entity: For the entity, clock arms are set as follows; Hours are represented with animation style
ROLL_VEL (see: SPRITE), while seconds and minutes are shown by sprite variables AIM and
USEGROUND (see: SPRITEVAR) respectively. When the entity is broken as collateral
damage, the entity is swapped to the corpse entity ( see: CORPSE).
on use: Toggles entity on/off.

cold
description: Area of coldness that makes the breath of the characters visible, similarly to theme
environment 'COLD' (see: THEME, ENVIRONMENT). While in most cases it is preferable to
use either global or localized themes ( see: THEME, trigger themelocal), in some cases this just
isn't feasible, which makes cold an acceptable alternative.
entity: –
on use: Toggles the cold area on / off

coop1
description: The first and primary part of the co-op dual triggers. To set it up, just link a target as you
would do for, say, trigger. Starting position, tagged as 'start on' and 'start off', define the
starting position of the lever (left/right). There is no need to connect coop1 to coop2 in any
way, it's the coop2 that must be linked to coop1. If there is no coop2 linked to coop1, the
device works as a singular lever, thus working even in single player.
entity: Progress is stored into entity's aiming angle ( see: AIM of SPRITEVAR). General rotation is
stored into entity's velocity rotation (see: ANIM_ROLLVEL of SPRITE). Entity uses weapon
attack modifier (see: WEAPONMOD of SPRITEVAR) to determine if the trigger is being
'pressed' or not. Speed of the rotation is determined by the entity's AI speed ( see: THINK). To
prevent the entity from 'rebounding' back to zero after the trigger is released use
AI_NOBOUNCE (see: STAT).
on use: Turns the lever and – if the coop2 connected to the trigger is being held up – activates the
target.

coop2
description: The second part of the dual triggers. Unlike it's counterpart, coop2 must be linked to the
related coop1 and NOT the target. The options available work the same as with coop1.
entity: Entity functions are equal to the ones of the trigger coop1.
on use: Turns the lever and – if the connected coop1 is being held up – activates the target linked to

[ 18 / 90 ]
coop2
the related coop1.

copystats
description: Simple trigger that forcibly rewrites player stats (available weapons, grenades and ammo).
Very useful for creating inventory resets (like with scripted campaign start) when used in
tandem with state. Doesn't affect armour, health or the default weapon.
entity: Entity from which the stats will be copied.
on use: Replaces the stats of the player entities with the ones of the trigger entity.

counter
description: Counter monitor displaying numeric value, which can be either time counting down or index
number counting up.
entity: For customisation, the entity works pretty much exactly like sign.
on use: Add or subtract one from the counter value.

damage
description: Damage field that, well, inflicts damage to entities within it's area. You can customize the
amount of damage, whether the trigger starts on or off and an optional entity for further
damage definitions.
entity: Entity used defines the style of damage delivered. For example; If the entity is set to deliver
electric damage (see: DAMAGE_SHOCK of STAT), the trigger will deliver electric shocks. If no
entity is set, the damage is delivered as standard physical damage.
on use: Toggles the cold area on / off.

database
description: Database functions in a way similar to infocomp that it opens an external help file for you to
read. However, database is an invisible trigger that opens the help file ONLY if it isn't already
logged into your Database as read unlockable.

Path of the external help file is ”tagap3/script/gui/txt_*.txt” where * is the trigger's text value.
The file is opened only if there exists an unlockable Database definition ( see: UNLOCKABLE)
by the same name.
entity: –
on use: Opens up the information file and logs it down into your Database (if it isn't there already).

delay
description: Like field, but fires the target after a defined time. The delay time is given in milliseconds.
More complex scripted events always requires use of delayed events, so mastering use of
these is a must.
entity: –
on use: Triggers it’s target, turns inactive until it’s restored (see: restore).

dialogue
description: As the function of InfoComp has changed so radically from the original TAGAP, all dialogue
and monologues are now handled with dialogue triggers. You can set the dialog bubble to
appear as player comment (player one or player two) or as non-player comment. In latter
case the bubble is 'projected' from the position of the trigger, not an entity.

[ 19 / 90 ]
dialogue

For player dialogs you can also define which voice over audio group will be used ( see:
VOICEOVER). If the group has an icon defined (see: ICON), it will be used to accompany the
shown message. The icons will appear on non-player dialogs as well, though no sound will
be played.

Also note that player dialog bubbles are 'said' by player stand-in entities ( see: AI_STANDIN of
STAT).
entity: –
on use: Pops up dialogue message and voice according to used settings.

disable
description: Disable has one, single purpose; To disable triggers before they are activated. While you
might think you wouldn't need it often, it's actually crucial tool when doing complex in-game
demo scripts (see: focus).

In single player, disable is needed in very specific situations. Here's an example; Trying to
get through a door will trigger a dialogue about it being locked. However, if you open the said
door from a trigger before attempting to go through the door should naturally disable the said
dialogue.
entity: –
on use: Disables target trigger, preventing it from activating until it's restored ( see: restore).

door
description: Door can be set to slide either up (default) or down when opened. If there are two doors, one
moving up and one moving down, with their ends connected, it will appear as a double-door.
In case of the said double doors, the upper half is referred to as the master and the lower
will obey its activations.
entity: The entity range modifiers ( see: RANGE* of SPRITEVAR) refer to the height of the trigger.
Unlike almost all other entity-based triggers, door is rendered over (in front of) floors and
ceilings by default. If you want the door to be rendered under (behind) floors, equip the entity
with render-first flag (see: FX_RENDERFIRST of STAT).

If you want to alter the movement speed of the door, you can do so via the movement speed
modifier (see: MOVETYPE). If the entity has no speed set, the engine default is used. By
default, doors will not close on bigger entities (i.e. bosses and minibosses), but remain open.
You can disable this by using no-bounce-flag for the entity (see: AI_NOBOUNCE of STAT).
on use: Opens or closes the door.

doorstate
description: Door state indicator that can be linked to door, platform or brick. What used to be a simple
door indicator lamp now supports any sort of custom entity.
entity: When the linked object is open, the doorstate entity is active, otherwise the entity is inactive.
By default the doorstate entity is a simple toggle object, but if you use AI_INHERIT_TIMERS
(see: STAT) to force it to copy over the activation times as well for full sprite animations.

The background element toggle for the entity is defined with ALIVE ( see: SPRITEVAR). By
default the doorstates are rendered in the middle object layer – behind doors and floors –
but you can use FX_RENDERFIRST (see: STAT) to bring them to forefront.
on use: –

[ 20 / 90 ]
elebase
description: Creates elevator tracks. Useful for creating scripted events with elevators and elecycles, as
this way you can have elevator tracks of different size than the movement range of the
elevator itself. Note that the elebase should be one grid step (16 pixels) smaller from both
sides than the elevator it's related to – this is simply for making the editing easier as you can
clearly tell the elevator and the elebase apart.
entity: –
on use: –

elecycle
description: Very similar to elevator except for two things. First off, where elevator moves between two
positions (top and bottom), elecycle keeps moving to same direction. Also, unlike elevator,
elecycle can be made to appear as an entity instead of basic elevator.
entity: Entity functions are equal to the ones of the trigger elevator.
on use: Activates and starts to move up or down.

elevator
description: Guess what; It’s an elevator! It can start in top or bottom position and be set have an
automatically generated wall track (or not). Normally elevators can be activated by pressing
'Use' while standing on them, but if it’s target of some other trigger – expect always – it can’t
be activated that way.
entity: When the elevator is moving – or if player is standing on it and the elevator can be activated
manually – the entity is active; Otherwise the entity is inactive. The activity states work as
usual, with the exception of the sound effects ( see: SOUND) that are played only when the
elevator moves.

Entity's aim (see: AIM of SPRITEVAR) and panning (see: SPRITE) are defined by the elevator's
relative position. This makes them handy in creating an illusion of gears and/or pulleys.
on use: Activates and starts to move to it’s other position.

envdamage
description: A decorative block of texture that will break when damaged or hit by a ricochet. When
damaged, the texture will change to damage texture ( see: TEXDAMAGE). You can set both
texture dimming and block material from the editor.
entity: –
on use: Breaks the block.

exit
description: End of a level area. Exit can be invisible field that activates when entered or triggered, or a
doorway.

When door opens, it can be set to show either textures behind it or background layers. By
default the exit use ending sequence and following level as defined in properties ( see: Setting
up properties) with string NULL, but you can define some other sequence to be loaded as
well, i. e. if you want to create exit leading to a secret level or something like that. Like many
fields, exit can start either active or inactive.

If a light area ( see: light) is placed over exit in a way that their origins align, that light area will
be used as a light that shines through the door when it is open.

You can use exits in sequences as well, either fired with delays, timers (see: SEQTIMER) or

[ 21 / 90 ]
exit
sequence items (see: command id TRIGGER of SEQUENCE). In these cases, setting the trigger
string as “RESTART” works as a level restarting sequence, “NULL” loads the level defined
as the next map in the scripts (see: map_nextmap of Configuration variables: Editing variables),
while all other strings will be attempted to load as sequences.

Finally, you can also set the exit triggers to fade the music out with the exit fade-out, creating
smooth transitions between different songs.
entity: If y-offset of FX_OFFSET is set to other than 0 ( see: FX_OFFSET of STAT), the light blooms in
as if the door slides up – otherwise the light appears from the centre of the doorway.

To crop the parallax backgrounds seen through an open doorway, you should use the
entity's stencil masks (see: STENCILMASK).
on use: Either unlocks the exit door or activates exit.

fade
description: Fade overlay that is mainly designed to work as fade at the borders of the level. Fade can
appear as solid black or as standard fade. In TAGAP 3, fade layers can appear as rounded
corners in addition to square blocks. These corners are created using Bezier curves, so
instead of having to compose a complex set of (fade) texture polygons, all you need to do
now is set the fade into 'Round' and the engine rounds it for you according to the trigger field
dimensions.
entity: –
on use: –

fadeslope
description: Rectangular fade overlay tool which is sloped vertically. The height means the height of the
fade area – the tilting is the difference between the custom height and the height of the
trigger.
entity: –
on use: –

fan
description: Fan is a standard rotating device. You can control it by defining it's spinning speed and an
entity used for rendering. Fan can start on or off. Unlike in the previous two TAGAP Engines,
now everything about the fans is customizable, including sounds, effects and broken
variants.
entity: The sound loop emitted by the entity it bended according to the fan speed; Faster the fan is
set to spin, higher the pitch of the sound emitter and vice versa.

By default, the fan uses the exact speed defined in the editor, but you can customize this
further by setting an AI speed for the entity – i.e. “THINK NONE <multiplier> NONE 1”,
where '<multiplier>' is your custom value (see: THINK).

You can now also make the fans breakable; This works the same way as with guides (see:
guide).
on use: Toggles fan on/off.

fanfare
description: Plays a music stinger, during which the general music is faded out. Unlike the 44.1 kHz
Stereo streamed music, the stingers are 22050 Hz Stereo.

[ 22 / 90 ]
fanfare

Take note that unlike the music tracks, the music stingers aren't streamed but loaded into
memory on level load. This means that you shouldn't go overboard with stingers, as each
different one is another stereo file loaded into memory, making the level heavier to load.
entity: –
on use: Plays the music stinger.

fence
description: Simple, automated fence tool, with which it's easy to set up guide rails for bridges, elevators,
etc. The fence can be set to be in-background or foreground, dimmed or bright, diagonal or
straight and set to appear as decorative glass one or as an industrial metal railing.
entity: –
on use: –

field
description: Standard all-round triggering field can be activated either by other trigger or by playing
stepping into the field area. Field can also be set to start inactive, requiring restoration ( see:
restore) before it will fire.
on use: Triggers it’s target, turns inactive until it’s restored ( see: restore).

flag
description: Renders image layer (see: LAYER) as a waving flag. You can set the direction of the flag,
define the way the flag waves, flip the layer texture vertically and set the sound loop ( see:
SOUNDLOOP) that is played when flag moves. The engine assumes the image defaults as
'from left to right', so when creating flag textures remember to tilt the final texture image
accordingly (i.e. flag hanging down would need to be rotated 90 degrees counter-clockwise
for proper rendering results).
entity: –
on use: –

focus
description: Focus is used to create in-game cinematics where view is focused on something else than
player and actual gameplay pauses. View is centred to the origin of trigger field for defined
period of milliseconds. In TAGAP 3 you can also define the camera zoom (default is 130 %,
which is the standard game view zoom) and speed of the zoom (if speed is zero, camera
works as an instant cut).

If you want to allow the end-user to skip the sequence – and for sake of usability you really
should do so, especially with longer cut-scenes – you'll need to trigger skip at the start of the
sequence as well. There is a reason why these are separate; More complex cut-scene can
consist of multiple focus triggers, all with varying time modifiers and the only way to be 100%
sure you'll come out of the skip at exactly the right moment is to use a separate trigger for
the job.
entity: –
on use: Pauses gameplay and centred view on the trigger for a moment.

fodder
description: Changes the cannon fodder to another ( see: CANNONFODDER). You’ll also see a preview of

[ 23 / 90 ]
fodder
that fodder, so the right one is easy to pick. Use trigger tempo to change fodder spawning
interval. This trigger can be fired unlimited times. As a new option for TAGAP 3, you can also
change the way the fodder is spawned on the fly.
entity: –
on use: Changes cannon fodder

fodderarea
description: Changes cannon fodder option (see: map_fodderopt1-3 of Appendix C: Configuration
Variables) to another entity. Unlike the classic fodderopt trigger, fodderarea is an ambient
trigger; It doesn't change the globally stored fodder options, but instead switches the entities
if they happen to be spawned inside the fodderarea.
entity: –
on use: –

fodderopt
description: Changes the global cannon fodder option (see: map_fodderopt1-3 of Appendix C:
Configuration Variables) to another entity. This trigger can be fired unlimited times. If you
want to vary the fodder options locally without swapping the global variables, see the trigger
fodderarea.
entity: –
on use: Changes cannon fodder option

forbid
description: Forbids area from player access, cannon fodder spawning, or both. Very necessary,
especially so when player has flying movement and can go beyond all level bounds.
entity: –
on use: Toggles forbid on/off.

forcewall
description: Nano-glass wall that blocks all the fire and blocks movement. Nanowalls can be either
vertical or horizontal, which is defined by the field dimensions. They can also start active or
inactive.
entity: If the nanowall is horizontal, it generates two bouncer linedefs ( see: FLOOR) at the both ends
of the wall. If the nanowall is turned off, the bouncers are turned on – and bice versa –
preventing cannon fodder and zombies from falling into places they shouldn't be falling into.
However, if you wish to NOT have those bouncers in place, simply make the nanowall entity
'non-blocking' (see: AI_NONBLOCKING of STAT).
on use: Toggles forcefield on/off.

gas
description: Area of lethal gas will damage everything organic.
entity: –
on use: Toggles gas on/off.

ghost
description: Basically a copy of field, only it can't be triggered by players, but only by entities flagged as

[ 24 / 90 ]
ghost
ghosts (see: AI_GHOST of STAT). Like fields, also ghost fields can be set to start inactive,
requiring restoration (see: restore) before it will fire.

As a new feature in TAGAP 3 you can define the ghost fields to react only to a specific
entities by setting the id value. For example, ghost field with an id value of 4 will only react to
entities whose AI_GHOST is set to 4 (see: AI_GHOST of STAT). If you want the field to react
all ghost entities, set the trigger's id value to 0.

The most common example of ghost usage in TAGAP 3 can be found in the boss fights; The
way the levels react to the boss fight progress have been scripted by a clever use of ghost
fields.
entity: Using FX_RENDERFIRST (see: STAT) the trigger will be rendered in the background,
similarly like with 'background' version of hologram.
on use: Triggers it’s target, turns inactive until it’s restored ( see: restore).

guide
description: Most dynamic way of rendering an entity to the background, guide is used to add lamps,
monitors, guide arrows and other similar decoration to the levels. Guides can be toggled
on/off and you can choose which direction the face.
entity: The entity is rendered pretty much as-is. If the entity has AI_RENDERFIRST flag ( see:
AI_RENDERFIRST of STAT), the trigger is rendered in the background layer (behind the
textures).

If the entity has been set to take damage ( see: AI_TAKEDAMAGE* of STAT), the entity can be
broken. If the entity has a corpse defined ( see: CORPSE) it will be used as broken entity. If
there is no corpse, the entity will just vanish from view. By default, the entity's bounding box
(see: SIZE of OFFSET) defines the entity's damage taking area, but you can customize with
weakpoint (see: WEAKPOINT).
on use: Toggles entity on/off.

guncloset
description: Security closet filled with weapons. You can define the range of weapons it holds (shown as
weapon slot selection numbers from 2 to 9) and the ammo quantity. The amount of ammo
gained is default weapon item ammo quantity ( see: AMMO) multiplied by the trigger's
quantity. You can also restrict the given ammo to all weapons (but no grenades), no heavy
(explosive) weapons or all weapons and grenades. In co-op mode both players can stock on
ammo, each player only once.
entity: Charge (see: CHARGE of STAT) defines how long it takes between opening the closet and
when you can actually loot the contents. The boxes of explosives, ones that appear in the
closet if there is heavy weapons ammo or grenades to be looted, appear via random frame 0
(see: RANDOM_FRAME of SPRITEVAR); If there is explosives, random frame 0 is set to '1',
otherwise it's zero. Finally, whether the cabinet is empty or not is done with sprite armor
flags 0 and 1 (see: ARMOR of SPRITEVAR). All of these are hacks of sorts, but then again, it
saves memory not to add any specific variables just for this trigger.
on use: Opens the closet.

hologram
description: Something between guide and envdamage, with hologram you can render entities either as
full entities that break like envdamage, or as holographic representations. Hologram entities
are a lot more simplistic and you have less control over them, but they work great for
decoration. Hologram can also be set to appear in background or on top of all other triggers.
entity: The entity is rendered pretty much as-is.

[ 25 / 90 ]
hologram

Unlike with guide, with hologram you can set the trigger's rendering layer in the editor
without messing with the AI_RENDERFIRST. Also, the way the entity will be damaged works
differently; You set everything from damaging taking and debris generation in the editor
instead of scripts.

If the entity has a corpse defined ( see: CORPSE) it will be used as broken entity. If there is no
corpse, the entity will just vanish from view.
on use: Toggles entity on/off.

infocomp
description: Right from the start you should know that function of InfoComp is completely different from
how it used to be in the first TAGAP. If you want to create monologue / dialog, please refer to
use of brand new trigger dialogue.

In TAGAP 3, InfoComp displays an external help file (”tagap3/script/gui/txt_*.txt” where * is
the InfoComp's text value). If there exists an unlockable Database definition ( see:
UNLOCKABLE) with a name equal to InfoComp's text value, the contents of the InfoComp will
automatically become available in the Database and can be read at any time from the
menus.
entity: In TAGAP 3 the InfoComp is entity based. Basically this entity is rendered as active until the
player reads it. At this moment, the camera is zoomed in, the entity is toggled off and you
can see the text file content through the entity. InfoComp uses the entity's stencil masks ( see:
STENCILMASK) to crop the on-screen content, so it is important to set those up properly.
on use: Opens up the information file and logs it down into your Database.

layer
description: Renders image layer (see: LAYER) as part of the world. You can set the layer dimming and
material like with envdamage, but you can also make layer unbreakable if you wish. Layer
triggers are set to “toggle off” by default, which means they will just be disabled when
broken. Alternatively you can make them switch the used layer to next available one (i. e.
trigger displaying layer #1 will display layer #2 when broken). Layers can be set to be
rendered ‘in background’, back between parallaxes and textures.

As a new feature in TAGAP 3, you can also define a reflection to be used. Reflection indexes
are exactly the same as with the sprites ( see: REFLECTION of SPRITEVAR). Also, upon
breaking, the layer will spew out scrap. Type of scrap is determined by the breaking material,
while the amount is determined by the size of the trigger field.
entity: –
on use: Breaks the block or, in case of unbreakable ones, just disables it.

light
description: Custom light / flare element. You can define your own alpha (in this case, the flare density)
and colour (using standard Red-Green-Blue components). The shape of the light is defined,
naturally, by the shape of the trigger field; A rectangular field will produce a light beam, while
square produces a halo.

In previous TAGAP Engine iterations, if you wanted custom lights, you would've had to
create a specific entity for that purpose. While this new trigger makes most of these
instances obsolete, there are still situations where you can achieve things only with entities,
like pulsing lights (see: FX_DIM of STAT).
entity: –

[ 26 / 90 ]
light
on use: Toggles light on/off.

lock
description: Works exactly like trigger, but requires a keycard to be activated.
entity: Entity will appear as the lock in the world. Rate-of-fire ( see: THINK) defines the delay
between using the object and the target triggering. Entity transformations ( see: TRANSFORM,
TRANSFORM_DIRECT) are also triggered only when the trigger has been used.
on use: Triggers target if player has a keycard.

manhole
description: Generates cannon fodder (see: CANNONFODDER) from a specific spot in the level. Like with
level cannon fodder, you can choose the list of entities used, spawning frequency and the
direction from which the entities will emerge. With burst you can define how many entities
the trigger will spawn in a sequence before pausing for a short while.

Spawning from some specific direction will make the entity appear to emerge from a hole in
wall, floor or ceiling, while “center” position works a bit like effects mode of spawner; If
manhole trigger is inside exit, portal or teleport, that device is “activated” making the entity to
emerge through it. If you want some other kind of entry effect, create and use a spawner
effect entity (see: AI_SPAWNER_EFFECT of STAT). Manhole is active only when it's in visibility
range, so there's no need to turn it off once player gets past it.

Note that manhole generates entities from the cannon fodder list in totally random fashion. If
you want to spawn entities in the order they are defined in the list, use trigger squad instead.
entity: –
on use: Toggles entity spawning on/off.

map
description: Map area tool for defining area properties for in-game map. You can name the area – or use
default string “NULL” for the area to have no name – and you can define whether or not it
will uncovered or hidden in the in-game map by default. Also you can define whether or not
unlocking an area map via an infocomp will reveal the area or not.

If you have complex area shapes (i.e. not rectangular), you might want to use field with a
multitap to uncover multiple map areas at once.
entity: –
on use: Turns the area off, thus revealing the covered area for viewing in the in-game map.

monitor
description: Monitor fill tool can be set to appear as standard sized or large wall monitor. Tracking
monitor will, well, track player and white noise is exactly that, white noise. In entity mode you
can select the entity to be used, a bit like with guide or hologram, only the monitors will fill
the entire trigger field instead of rendering just one entity. Monitors can be set emit their
native sounds or appear silent.
entity: Renders the entity as-is, over the desired monitor content; think the entity as a frame for the
picture within. Monitor uses the entity's stencil masks ( see: STENCILMASK) to crop the on-
screen content
on use: Toggles between tracking and white noise screens, entity monitor is first turned off, then
swapped to white noise on the second toggle.

[ 27 / 90 ]
music
description: Change music on the fly. You can define the transition to be an instant cut, power-down fade
or basic fade out. Use string “off” to turn the music off.
entity: –
on use: Changes or stops music.

odor
description: Odor is a custom particle generator field. You can define the style of the particles (ranging
from smoke and mist to rubble, debris and sparks), the density of particles in per cents and
whether the generator starts on or off by default.
entity: –
on use: Turn the particle generator on/off.

odorent
description: Odorent, or “odour entity”, is basically the same as odor, only based on the effects of the
defined entity. In addition to selecting the entity used, you can also define the effect density
in per cents and the default toggle state.
entity: The effect generated is the death effect of the entity ( see: GIB of EFFECT). In addition to the
effect, odorent also generates the death sound if the entity happens to have one ( see: s_DIE
of SOUND).

Finally, you can randomise the effect via using MISSILE_RANDOMIZER ( see: STAT). For
example, “STAT MISSILE_RANDOMIZER 3” would result odorent to pick either the chosen
entity or one of the following three entities defined.
on use: Turn the effect generator on/off.

ost
description: No, it's not 'cheese' in Swedish, but standard abbreviation for 'Original SoundTrack'. In
TAGAP 3, OST triggers manipulate the state of the dynamic soundtrack. You can set the
trigger to force the music to go either mellow or action-y.
entity: –
on use: Changes the state of the streamed music when camera is within the area. Note that music
stream automation options can also affect the state of the music; Use music id tag “AUTO 0”
to disable such automation (see: File Types: Audio).

platform
description: It’s platform moving sideways, kind of like vertical door that is hidden inside a wall when it’s
off. Platform can also be used to create telescopic bridges, as it’s totally invisible and non-
blocking when it’s off.
entity: Platforms entity-based and the entity is rendered as-is. Use TEMPMISSILE variable ( see:
STAT) to define the time period the platform is rendered after use. To create an illusion of the
entity coming from a wall, use stencil masks (see: STENCILMASK).
on use: Turn the platform on/off.

pointer
description: Navigation pointer, aka the perceptual guide arrows shown in the game. These for the basis
for the navigational help system in the levels and are to be used in tandem with waypoint
triggers. You can set a pointer to appear as a general arrow (points only left, right, up or
down), direct arrow (points directly at the next pointer) or as invisible pointer (which has no

[ 28 / 90 ]
pointer
visible or audible in-game presence, but exists in the chain nonetheless). You can also
define whether the pointer is part of the main chain or an orphan.

This is how the pointer system works;

1. Once the paths are set, the biggest priority waypoint is looked up.
2. Pointer closest to the waypoint (1) points towards the waypoint.
3. The next pointer in the chain (2) points towards the pointer (1).
4. The next pointer in the chain (3) points towards the pointer (2).
5. …and repeat through the entire chain.

In order for this to work, you need to design your pointer structure so that each pointer is
linked to the next pointer in the chain (use L to link pointers to one another). To do this,
create a main path – and if you need 'branches' of pointers, create as many 'orphan' paths
as you need.

To explain this further, here is a visual representation of a more complex pointer structure.
The arrows point at the next pointer in the chain (target of '1' is '2', target of '2' is '3' and so
on).

entity: Entity is rendered almost as-is; the aiming angle of the entity is defined by the direction the
pointer is pointing (see: FX_FULLANGLE_AIM of STAT, AIM of SPRITEVAR).
on use: Toggles the entity on / off. When the entity is turned off, it doesn't update the pointing
direction.

portal
description: Basically a teleport that appears as door, portal's transfer player to another portal instantly.
Portals that are inactive or don't have a target can be used only destination, not as
transporters.

If a player start point is placed inside a portal – and the player is set as 'inactive' at the start
– the level stats by the player entering the room through the portal.
entity: Identical to how entity-based exit functions.
on use: Transports player to the linked portal.

pose
description: Pose is exactly what it sounds like; A limb animation changer. The trigger string is the name
of the pose script (as located in the 'tagap3/script/poses/' folder) (see: POSE). By default the

[ 29 / 90 ]
pose
trigger affects the entity linked to the trigger, but you can choose to make if affect players via
the manual override.

The poses are automatically dynamically loaded and unloaded from the memory.
entity: –
on use: Changes the pose of the target entity.

pulse
description: Pulse is sort of a constant delay that fires its target by every defined milliseconds. As an
example, pulse with 1000 millisecond delay linked to an elevator will make the elevator go
up and down, changing its direction on every second.

Pulse only function when it's in player's visibility radius, so remember to make pulse trigger
as wide as the area it affects. Pulse can start either active or inactive, requiring restoration
before starting the loop (see: restore).
entity: –
on use: Toggles the pulse on/off.

quake
description: Shakes the screen by defined factor.
entity: –
on use: Shakes the screen.

rain
description: Section of foreground rain, similar to theme environment RAIN_HEAVY ( see: THEME,
ENVIRONMENT).
entity: –
on use: Toggles rain on/off.

realtime
description: Turns button, delay, trigger or lock trigger to work in realtime instead of 'game time'. This
means that if you want to create timing sensitive events from press of a button, use this
trigger field to work around slowed down time. To tag a trigger with realtime, just place this
trigger inside the to-be-affected one.
entity: –
on use: –

relocate
description: A hack of a trigger, which instantly relocates the targeted entity to the trigger's origin. This
function is useful when creating complex events, whether in-game or especially in the
sequences.

In sequences, this function is key. See, during sequences the AI still works, trying to aim and
follow the player even though player entity appears invisible. With changing player’s location
via relocation, you can have the entities change their aim, movement, etc. So, when in a cut-
scene you see a character standing still, then turn and walk away, you know it's done with a
delayed player relocation.

[ 30 / 90 ]
relocate
Note that in previous TAGAP Engines, the relocate functioned only in sequences and
worked only on players. This is no longer the case; you can relocate any kind of an entity at
any time, in-game or in sequences.

Feel free to experiment with this one.
entity: –
on use: Relocates the target entity instantly.

restore
description: Tool to restore inactive triggers – triggers that either have been already fired or ones set on
purpose inactive before some event occurs. If restore is linked to multitap, it will attempt to
restore all trigger fields linked within.
entity: –
on use: Makes target trigger active again or resets it to starting values.

rewrite
description: Trigger for re-writing properties of other triggers; Particularly useful for scripting conditional
events (see: STATE). For example, the exit at the end of the level may trigger a specific cut-
scene, but after seeing it once, you may want to 'rewrite' the exit to load a different
sequence.
entity: –
on use: Re-writes the string value of the target trigger.

rift
description: Rift is a window to another point in the level and through it you can see the entities, particles
and the works. You can have two way or one way rifts – it's defined whether the rift has been
linked to another rift or not. Note that linked rifts should be of same size in order to avoid
glitches and stretching. You can also flip the rift view to appear as mirror image – useful for
two-way rifts between places the player can visit – and you can choose whether it's rendered
among the other triggers or in the background.

Rift doesn't show the background (layers, triggers, texture polygons etc.) from the other side.
Instead, user defined layer is used as the 'back wall'. After all, if you into a room through a
window, you don't see the very same window again on the back wall, now do you?
Alternatively, you can set the background to be rendered as a parallax background instead.

Only exception to these rendering rules is the 'Monitor' display mode, in which the monitor
rift is rendered as a grayscale monitor view. In this mode, the scene from 'the other side' is
rendered in full, effects, backgrounds and all included. This is very CPU and GPU tasking,
as essentially the game renders two full scenes. As such, it is recommended that this mode
isn't used in in-game situations – in fact it was implemented exclusively for use in
cinematics.

Worth noting; In any other game engine this trigger would've been called 'portal', but since
we already had a trigger with that name and considering I've always wanted to keep
continuity between engine versions in order to make lives of modders easier, I went with 'rift'
instead. In practice that's what it is; A rift through which you can see pocket view of another
place.
entity: –
on use: –

[ 31 / 90 ]
rotaway
description: Again pretty much like field, but requires defined times of activations before actually firing.
Like, if you make it require 5 activations, it won’t fire its target until it has been triggered 5
times. Note that the secured loot lockers in TAGAP 3 have their own automated system of
security triggers, so if possible, don't try to implement those through rotaways.
entity: –
on use: Triggers its target after defined times of activation, then turns inactive.

security
description: Security is basically an always trigger that is automatically triggered when all the security
devices in the level – entities with AI_SECURITY tag ( see: AI_SECURITY of STAT) – have
been destroyed. In other words, those secured loot lockers in the game have been created
with these triggers. While you could achieve the same results by linking entities to a rotaway,
with this automation re-iterating level designs is a lot easier. Only one security trigger is
taken to account, so if you need a plenty of operations occurring at once, use multitaps.
entity: –
on use: Triggers its target.

sfx
description: Plays sound effect, either positioned to trigger origin, as a voice over or as global, full-
volume sample. The sound sample loading is automated; Sounds already loaded will be
used from memory, otherwise the sound will be loaded as dynamic sample.
entity: –
on use: Plays the sound effect.

shadow
description: Solely decorative soft shadow area. Shadow can be made to appear as simple round shade
or rhombus shaped, like if light was hitting an object from an angle. You can also choose
from full shadow, or one that is cut from either top or bottom (if the object is i. e. sitting on a
floor, you should use “Cut bottom” so that shadow reaches floor without fading out). The
value in the input field defines the length of the fade out (in pixels). You don't have to worry
about the arrangement of shadows and other triggers, as shadows are always rendered in
the far back.
entity: –
on use: Toggles shadow on/off.

sign
description: Electric light sign or one of standard letters. You can set the text yourself.
entity: Size of the text is defined by muzzle flash size (see: FX_MUZZLEFLASH of OFFSET);
Muzzleflash size defines the size of the font, while the length variable works as a flag for
defining whether the text is rendered behind or on top of the entity.

Colour of the text is defined with entity colours ( see: COLOR). The entity range modifiers (see:
RANGE* of SPRITEVAR) refer to the width of the sign (which in turn is defined by the length of
the user-defined text). The text defaults as centred on entity origin, but if you want to
reposition the text, you can use weapon offset variable ( see: W_OFFSET of OFFSET). Finally,
you can use smoke alpha factor to adjust the transparency of the text ( see:
FX_SMOKE_ALPHA of STAT).

When the entity is destroyed, the entity is swapped to the corpse entity ( see: CORPSE).

[ 32 / 90 ]
sign
on use: Toggles the sign on/off.

skip
description: Skipping tool to be used in tandem with focus. When triggered, skip enables a fast-forward
timer that, if user so chooses, can be executed in order to skip an in-game cut-scene.

Skip essentially fast-forwards ahead by defined amount of milliseconds without rendering or
sound playback, thus ensuring all the scripts associated with the sequence are run on the
clock. Having a buffer of 100 to 300 milliseconds should suffice compensate for any
differences caused by performance dibs.

Note that since skipping a cut-scene assumes it's safe to fast-forward for the defined amount
of time before stopping, you should make sure the time defined for skip correlates to the
time the entire scene lasts. Too short a skip and you'll come out of fast-forward awkwardly in
the middle of the scene – and too long a skip and you run the risk of having player standing
defenceless for a moment while everything is processed around him/her/it regardless.
entity: –
on use: Enables in-game cut-scene skipping for the defined time period.

slide
description: Forces player to slide, regardless what player is actually doing. If you want to create a low
passage that the player must slide through (i.e. an air vent), you should also define a slide
field for that passage. This ensures player can't stand up in the middle of the vent, banging
his/her/its head to the ceiling and fall off the entire level.
entity: –
on use: Toggles the sliding on/off.

sound
description: Emits sound loop from trigger. Sound loops are defined in TAGAP_Scripts ( see:
SOUNDLOOP). Sound loops can be set to fade out instead of muting instantly; Use 'fade'
value to define the fade-out time (in milliseconds). New feature in TAGAP 3 is the ability to
customize the fall-off distance (in per cents) – longer the fall-off distance, sooner the sound
becomes audible. For example you can hear a heavy machinery operating from a much
greater distance than, say, an AC vent hissing.
entity: –
on use: Toggles sound on/off.

spawner
description: Spawns an entity to the game. You can choose any entity you wish and select between
standard teleportation effect, no effect at all or use a specific spawning direction for scripted
events – just like with manhole. Spawner can be triggered unlimited times. If the
teleportation effect is on and the spawner field is inside a teleport or portal field, upon
spawning the entity will appear as it was coming through that device. If you want some other
kind of entry effect, create and use a spawner effect entity ( see: AI_SPAWNER_EFFECT of
STAT).

As a fun 'hacky' usage for spawners is as pre-loaders for cut-scenes. Say that you have a
sequence that is so complex that it's split into multiple sequence scripts, the first one
functioning as a content pre-loader. So, to ensure the first sequence script loads all the
entities in the following ones, simple add them to the first script as spawners. They won't be
visible, but force the engine to load all their assets regardless.

[ 33 / 90 ]
spawner
entity: The entity selected is the entity that will be spawned.
on use: Spawns the defined entity.

squad
description: Very similar to manhole, with one key difference; While manhole keeps pumping out random
fodder until it's turned off, squad spawns them in the same order as in they appear in fodder
definition list (see: CANNONFODDER). Also, squad will spawn only the amount described and
then shuts off (until toggled again). Squad is very useful for setting up intensive scripted
sequences with enemies jumping into the scene – for example from a portal.
entity: –
on use: Toggles squad spawner on.

state
description: In-game progress related if-state for level scripting. State can be set to fire in two ways – if
the progress string has the required tags, or if the progress string DOESN'T have the
required tags.

For programmers, think state as 'if (ProgressIncludesTags)' or 'if (!ProgressIncludesTags)'.
entity: –
on use: Triggers its target on level start-up if the demanded progress state is true.

stream
description: This trigger plays defined ambient stream. The default folder for these streams is
“data/sound/streams/”. To stop the stream, use string “off”. This function can also be used to
start audio streams for in-game cut-scenes – which saves on memory usage, as instead of
pre-loading samples to memory, the audio is streamed
entity: –
on use: Plays or stops an audio stream

teleport
description: Teleport device. If linked to other teleport, it can be used to travel to that teleport instantly. If
no link is set for current teleport, it can be used only as destination, not as transporter. It can
also be linked to exit, in which case instead of teleporting, using the trigger triggers the exit.
entity: Aiming angle (see: AIM of SPRITEVAR, FX_FULLANGLE_AIM of STAT) is used for the
acceleration animation, whilst the effect layer fade-in is set with sprite weapon mod ( see:
WEAPONMOD of SPRITEVAR). When player stands on a usable teleport, the entity is turned
active (and back to inactive when players steps off of it).

The effects generated when the player or other entities are teleporting are defined by entities
“fx_teleport_focus1”, “fx_teleport_focus2” and “fx_teleport_focus3”.
on use: Uses the teleport or uses the linked exit.

tempo
description: Changes the spawning speed of cannon fodder. Smaller the spawning interval, more frantic
waves of slaughter you’ll get. Use trigger fodder the change the actual cannon fodder.
entity: –
on use: Changes the spawning rate of cannon fodder.

[ 34 / 90 ]
texblock
description: A block of texture; Some times it just is necessary to render a piece of texture to the trigger
rendering layer – i.e. say, when you need to have a bolt texture between two layers. You can
define the texture offset point, whether it appears bright, dimmed or in the background
trigger layer. Whatever texture entities (see: TEXLITE) the texture might have will also be
rendered.
entity: –
on use: –

textag
description: Trigger designed to manipulate tagged texture polygons ( see: POLYGON). It's super-simple to
use; All tagged texture polygons inside the trigger area are automatically assigned to the
trigger.

How the textag works is defined how the polygon is set up; the textag can affect the whole
texture or just the texture's overlay effect.

By default, the textag will simply toggle the texture (or the texture's overlay effect) on/off.
However, if set the textag to use layers, it will replace the texture used with the chosen layer.
For example, a polygon marked as tagged inside a textag trigger using layer #3 will use the
image layer #3 in place of the texture defined texture mode.

This sounds like lots of pointless trouble, but it can come really handy; instead of slowing the
editor usage down by adding dozens and dozens of dynamic textures, you can set some of
them up via using textags and layers. This is recommended particularly in cases, where a
piece of texture you need is very scene specific and not used anywhere else – there's no
sense in auto-loading it in the editor, now is there?

You can set the trigger to start as active or inactive – meaning the polygons attached start
either on or off.
entity: –
on use: Removes all tagged texture polygons inside its trigger area.

theme
description: Trigger to switch the global level environment theme ( see: THEME) in-game. You can choose
from an instant cut, smooth cross-fade and fast cross-fade transition between the themes.

As a new feature in TAGAP 3, you can also define whether or not toggling the theme will
affect the level stream; By default when the theme is used, the stream defined in the theme
(see: STREAM) will override whatever stream is currently being played. This also applies to
themes without streams, in which case the stream is stopped. This doesn't happen during
the sequences, only in-game – except when you specifically choose to ignore the streams.

Note that this is affects the global theme that is applied the whole level. If you want to set
localized theme for a specific section within the level, use themelocal instead.
entity: –
on use: Switches level environment theme.

themelocal
description: Specifies an area in the level where a selected theme overrides the globally set one ( see:
THEME). You can choose the theme to be an approximate (applies to everywhere within the
same horizontal vis-data slice, less CPU taxing) or exact (applies only when the trigger is

[ 35 / 90 ]
themelocal
within the screen bounds). You can also choose if the theme transitions smoothly or as a
hard, instantaneous cut.

Note that local themes don't support streams or shift sounds. This goes both ways; If the
global theme has, say, a stream, it will play even when you are in a section covered by a
local theme.
entity: –
on use: –

ticker
description: Different kind of counter that counts either from zero to defined value or the other way
around. Alternatively, you can also set it so that it counts from defined value to maximum of
99. You can set the counting speed. Use restore to revert ticker back to its starting value.
Note that unlike in the original TAGAP, tickers of TAGAP 2 can't be set to appear as gauge
meters – there just is no need for that thanks to more advanced custom entity guides.
entity: For customisation, the entity works pretty much exactly like sign.
on use: Start counting from/to zero.

transform
description: Transforms the targeted entity into completely different kind of an entity.
entity: The entity the trigger's target will be transformed into. If the entities are similar in the scripts
(have same health, weapon usage rules, etc.), the transformed entity will inherit all the stats
of the original entity.
on use: Transforms target entity into the trigger's target.

trigger
description: Basic object that can be triggered upon use. Triggers can be defined to start either on or off.
Unlike button, trigger becomes unavailable after use, unless it's restored with restore.
entity: Entity will appear as the lock in the world. Rate-of-fire ( see: THINK) defines the delay
between using the object and the target triggering. Entity transformations ( see: TRANSFORM,
TRANSFORM_DIRECT) are also triggered only when the trigger has been used.
on use: Triggers its target.

tutorial
description: Displays a tutorial message on the player's hud. The tutorial message, set to the trigger's
string value, is loaded from an external help file (“script/gui/hint_<string>.txt”). The triggers
can be toggled on/off.
entity: –
on use: Via trigger; Toggles the trigger field on off. Via player; When the player is inside the field, the
tutorial message is displayed.

unlock
description: Trigger unlock is quite peculiar one; It is essentially an automated version of a key item (item
“keycard” in TAGAP 3, see: S_KEY of STAT) being linked into always or field. The idea is that
when a key item is generated inside unlock field – either by an entity dropping it on death
(see: GIB, ITEM) or spawned by a trigger (spawner) – that key is automatically linked to said
unlock. When player picks up the item, unlock is toggled.

[ 36 / 90 ]
unlock
The main use for unlock is to create sequences where doors open for the player when it is
assured that player actually has the means to progress further. For example, a boss room
locks down for the duration of the fight – and opens again when the player picks up the
keycard the boss dropped.
entity: –
on use: Triggers its target – doesn't activate until the related key item is picked up.

used
description: Used is a specified version of triggers like always. Here's how it goes; Place used inside
another trigger (i.e. guncloset) and give it a target like with always or field. Now in the game,
used isn't triggered upon touching it, but rather when the weapon cabinet is opened. This
works with most types of triggers. In other words; Trigger used is triggered when the
surrounding trigger is used.
entity: –
on use: Triggers it’s target, turns inactive.

water
description: Well, it’s water. Water can be crystal clear, muddy, green toxic waste, burning lava, life-
regenerating clone fluid or even blood. Since edges of a water area are faded, it’s strongly
recommended to make water areas consist of only one trigger field instead of multiple ones.
If you want to make completely flooded level, use level theme with UNDERWATER
environment setting (see: THEME, ENVIRONMENT). The option “Tide” defines amount the
water level will rise or descend when triggered. You can also choose the sound the lapping
waves emit.
entity: –
on use: Rise or lower the water level according to its tide.

waterbg
description: Water background, mainly intended for creating illusion of open sea type environments. Like
water you can interact with, water backgrounds also can appear as crystal clear, muddy,
green toxic waste, burning lava or clone fluid. Additionally, you can choose whether the
water appears bright or dimmed (this is handy for creating more illusion of depth).
entity: –
on use: –

waterfall
description: Surprisingly, it’s a waterfall. It’s mainly for decoration and to be used in context with related
water area. Like water, waterfalls can also be water, toxic waste, lava, healing fluid or blood.
Water can also be made to pour from either left, right, centre – or even defy gravity and flow
up! If the waterfall is connected to a water area, the waterfall will be automatically adjusted
when the water level rises or descends.
entity: –
on use: Turns water flood on/off.

waypoint
description: Mission objective waypoint that is used by both the in-game map in the Database as well as
the pointer system in-game.

[ 37 / 90 ]
waypoint
The priority of the waypoint defines, well the priority; Higher the priority, more important it is.
The most important waypoint active at the time is chosen as the target of the pointer system
and is highlighted in the in-game map. If there are more than one waypoint active at one
time, the rest will still be shown in the map, though as non-highlighted.

For more information how the pointer system works in relation to waypoints, check out the
detailed explanation of pointer trigger.
entity: –
on use: Toggles the waypoint on/off and forces pointer system update.

weapon
description: Adds an armour piece or a weapon to the both players, complete with the default
ammunition it carries as a collectible.

This trigger has two main uses. More visibly, it is used in adding weapon's to the player
inventory during the sequence cut-scenes. Obviously, as non-player entities posing as the
player can't pick up items, activating this trigger does the trick.

Additional, less obvious use is in progress-based scripting; If you want to make sure the
player has the tools to proceed – say, Thereminizer and some ammo – in the beginning of
the level, using this trigger in combination with state will do just that, discreetly behind the
scenes.
entity: –
on use: –

window
description: The use of window triggers is completely changed from the original concept seen in TAGAP
and TAGAP 2.

Window creates a, well, window through which you can see the parallax background sky
box. The idea is that you can create areas through which sky boxes are visible without the
need of having a constant full-screen parallax – on for you to painstakingly cover parts of it
with textures and fades.

All the sky parallax types are supported and you can also set a layer offset for rendering.
This offset simply means that instead of using the three first layers for the sky box, image
layers counting from the offset will be used instead.

Some times you may wish to create a sky box that moves into a different direction from than
what the global parameters suggest, be it change of wind or being transported to a section
that needs a different perspective. In that case, use the speed modifier. It is what the name
suggests; It multiplies the speed of the sky movement by the defined factor.

You can also set the entity to appear in the foreground or background. Note that if the trigger
is thrown to background, it will be made part of the global background of the level. This
means that some of the individual operations – like layer offsets, toggle fades and the like –
will not work. Then again, those are usually reserved for special events, so this won't cause
much trouble.
entity: If the entity is chosen and it has its own stencil mask ( see: STENCILMASK), that will be used
to crop the parallax. Also, the entity range modifiers ( see: RANGE* of SPRITEVAR,
FX_USERANGE of STAT) refer to the width of the window.
on use: If the window is not set as a background parallax, the sky box will be toggled on/off, resulting
a fade-in / fade-out.

[ 38 / 90 ]
Basics of Scripting
Introduction to scripting
Though TAGAP_Script is intentionally left very simplistic, it's still the most complex aspect of
TAGAP 3 editing. There are so many things you can do with basic commands, all sorts of hacks
and combination of both, that in this handbook we're not even trying to cover it all. Instead we'll
focus on a couple of most asked-about subjects to get you started. Note that only a small fraction
of TAGAP_Script commands are mentioned and explained here, so it's strongly recommended
you'll scan through Appendix B: TAGAP_Script Syntax for the whole scripting language specs at least
once.

So what makes a TAGAP_Script file? They are plain text ASCII text files that start with line
“//TAGAP_START” and end with “TAGAP_END”. The code is written in the between. You can add
comments in C-way by placing “//” at the beginning of the line. Script is being read line-by-line, so
splitting script command to two lines isn't allowed. Note that strings don't support spaces, so
replace them with “_”, which will appear as space in-game. That's the very basics, now let's look at
what we can do with it.

Weapons scripting
New weapons.

No matter what game we're talking about, that's what people want to do first.

To make a new weapon, you need to start with creating the weapon projectile entity. In
TAGAP_Script, entities are defined with code block starting with ENTITY <entity name> and ending
with END. Missiles have AI set to AI_MISSILE with projectile movement speed as speed value ( see:
THINK).

Now with the graphics. The projectile needs a sprite defined ( see: SPRITE) in order to appear as
moving entity, otherwise it will be handled as traceline projectile, like bullets, beams and lightning.
Entity projectiles are flying by default, but you can set them ballistic ( see: MOVETYPE) in order to
create grenades and alike. For good gameplay's sake, projectiles should never have range greater
than screen dimensions. To tune the range, use TEMPMISSILE relative to missile speed for entity
projectiles and AI_RANGE for tracelines (for both, see: STAT).

While many of the weapon-specific stats are rather self-explanatory, DAMAGE_EMP ( see: STAT)
might require some explanation. Instead of damaging the entity some more, this variable makes all
EMP-vulnerable entities – those set as TAKEDAMAGE_EMP or TAKEDAMAGE_ELECTRIC – will
be shut down for amount of time defined by DAMAGE_EMP value. Note that this goes both ways,
i.e. if player is EMP-vulnerable, an EMP bomb thrown by the enemy will make him/her/it immobile
for the defined time.

TAGAP 3 is different from the predecessors in a way that it handles damage – there are tons of
different ways that entities both deal and receive damage, leading to some entities being
vulnerable to specific kinds of attacks. Whilst TAGAP 2 introduced EMP and organic-only attacks,
but TAGAP 3 expands the repertoire with nano-damage (DAMAGE_NANO), leeching damage
(DAMAGE_LEECH), sonic damage (DAMAGE_SONIC) and electric shock damage
(DAMAGE_SHOCK). On the receiving end, you can set up multiple kinds of vulnerabilities – even
separately for the entity itself (see: TAKEDAMAGE_* of STAT) and its weakpoint (see: WEAKPOINT,
TAKEDAMAGE_WEAK_* of STAT). This may sound alike mess on paper, but the way these different
damage types affect different kinds of entities is key to TAGAP 3's more varied minute-to-minute
action.

[ 39 / 90 ]
Once the weapon projectile entity has been made there are two ways to assign it for an entity; via
weapon slot (see: WEAPON) or as entity missile (see: MISSILE). Weapon slots work like player's
weapons and every entity can use one, all you need to do is add STAT S_WEAPON <slot>
variable for them (see: STAT). As weapon slots are global, many entities can use the same exact
slot, so modifications to the weapon affects every entity using the slot.

Missile is handy in many occasions too, like if you want multiple entities to use the very same
projectile, but handle it in different manner. This is cause non-weapon slot missiles use rate-of-fire
and charge values of the attacking entity, not ones of the projectile. Note that weapon projectile
that is used as a weapon slot can also be used as missile – and an entity can have both weapon
slot and missile defined.

Weapon slots have one significant advantage; You can have more control over them. Weapon
slots 0–9 are available for player use and use ammunition unless defined otherwise. Other entities
can naturally use these slots, too. Player can also use slots beyond that, but those act as non-
ammo eating mounted weapons – like the spacepod chainguns – and when player entity uses
such weapon, they can't access standard weapons.

Other cool thing is, that unlike with defined missiles, entities can swap weapons too, if they're
allowed to. Entity can be set to respond to each player weapon individually ( see:
WEAPON_RESPONSE) or forced to always use the same weapon player is wielding ( see:
AI_COPY_PLAYER_GUN in STAT). You should think carefully which entities you'll allow to do this,
however, as though it's makes cool combat situations with bosses, it goes a waste in run 'n gun
levels.

Then there are the weapon models ( see: GUNENTITY). These are essentially separate entities that
are rendered as a weapon in the hands of the user. There are lots of intricacies into animating a
weapon and I fully confess I went way overboard with it all myself, so feel free to check out the
existing scripts for many kinds of examples. You don't have to animate everything to the same level
we did – pulling the trigger, moving casing ejectors, operating mechanisms and so on – but it does
make the shooting more lively and impactful. As a new option to TAGAP 3, the weapon entities can
emit sounds, like loops (see: S_LOOP of SOUND); perfect for creating things like minigun motors
and continuous beam weapons.

Finally, you need to set the procedural limb animation system to hold the weapon properly. These
are defined by limb connection offsets in the weapon slot script ( see: WEAPON, OFFSET). You need
to set up the weapons bobbing, the origin in relation to the player character, muzzle offset, ejector
offset, grip offset and handle offset. Additionally, you'll want to tune the weapon handling
movement (see: W_ORIGIN_* of OFFSET) to ensure the limb animation doesn't break when aiming
up/down and sliding. The limbs-to-weapon setup can sometimes be a time-consuming task, but
getting it right is the difference between a smooth character actions and a broken, glitchy mess.

And don't even dare to think it's over once the weapon is slapped to the game! Oh no, now the
hard part begins; Whatever weapon you choose to create, remember to balance it well. Make it
have weaknesses and strengths and keep testing and testing and testing until its perfect.

Sprites and animations
Now that your main scripting urge has been dealt with, it's time to look at sprite handling. It doesn't
take long for you to notice how dull non-animated, non-interactive graphic blocks look like.

First off, there are two basic ways of loading sprites, static and dynamic loading. Static loading
means the sprite is stored in memory at all times and can be accessed at any time without more
loading, while dynamic means the sprite is loaded during initialization of the level in which the
object is used and flushed out of memory when that level is completed. It's strongly recommended
to use dynamic loading for entities and objects used only in certain specific locations of the game,

[ 40 / 90 ]
like big bosses, decoration objects and level specific cannon fodder. This way you'll save a lot of
precious memory from going a waste. A word of warning, though; Never use both methods for the
same sprite! If the sprite is used in one entity as static and as dynamic in another, you'll end up
confusing the engine on how to handle the sprite, which may result in game crash and/or glitchy
rendering.

The main way TAGAP 3 uses to animate entities is called parametric animation. Way more
common with polygonal objects than sprites, this means that instead of animating object by
displaying frame-by-frame, portions of the object are moved mathematically according to the
entity's state or movement.

An example to simplify the idea; When the player fires the Smartgun, the weapon is animated in
various ways – the ejector moves, trigger rotates, telescopic barrel recoils. Instead of showing a
new frame 24 times per second, these elements are actually moved and rotated. As a result, the
animation looks buttery smooth even in super-slow-motion – not to mention this method eats a lot
less memory. Additionally, together with the skeletal limb system (more on that later in this
document), you can have virtually limitless amount of animated details going on at once.

The basic animation behavior is set in sprite definition itself ( see: SPRITE) while the more advanced
customization is done with sprite variables (see: SPRITEVAR). Read the documentation of both
ways carefully and start bringing your creations to life. And, as always, feel free to experiment.

The most useful commands of the bunch – the ones the more complex setups in TAGAP 3 are
rigged with – are “HIDE_<suffix>” variables. Hide animations are initiated when the entity is toggled
active/inactive, when the entity is spawned or when the entity transforms to another entity ( see:
TRANSFORM, TRANSFORM_DIRECT). When this happens, the sprite in question is moved, rotated
and/or scaled according to variables in span of HIDE_TIME milliseconds (default is 200 ms). For
example a custom door object would move, say, 128 pixels up in span of 750 ms, meaning
“HIDE_MOVE_Y 128” and “HIDE_TIME 750”; To use it in a level, simply add the entity to the level
as guide and activate it at the same moment as the brick used as a the invisible door block.

Skeletal limb system
Yes, I mentioned this earlier – and oh boy, this is the most complex part of TAGAP 3 engine bar
none. The idea is simple enough; imagine the entities as rag dolls with simple, jointed limbs. These
limbs can have up to 3 separate segments (like a leg, for example), or just one segment (like a
head). Of course, simple entities – like items you pick up – have no limbs at all.

First you obviously have to set up the entity with a limb. Since a hand is the easiest example to
explain, let's do just that. Before you start rigging a limb, you need to know a couple of important
things;

• What is the limb's origin? In case of a hand, this means the shoulder point.

• How many segments does the limb have? All hands have 3 segments.

• Determine the limb and limb segment lengths. This is important. For the sake of this
example, let's use the standard player hand as an example; The limb totals 27 pixels in
length – 12 pixels for element 0 (from shoulder to elbow), 12 pixels for element 1 (forearm)
and 3 pixels for the hand. Of course, in order for the look proper, the sprites for the
segments have to match these lengths.

So, now you know how long the limb will be and how it'll be placed on the entity, you can proceed
one of two ways; Either have the limb sprites on the ready – or set up the limb using the
wireframes (using visible bounding boxes, see: Editor Setup) and add the sprites later. For sake of
simplicity, in this example I'll assume you have the sprites ready and measured to be of correct

[ 41 / 90 ]
length.

Setting up a limb for an entity in the script simply involves adding a limb inside an entity script (see:
LIMB, ENTITY). A simplified version of player's hand would look like this;

// create a weapon hand #1 (attached to grip);
// shoulder is entity's origin + (-3 21);
// hand is in layer 0 (drawn over the base entity)
// hand is attached (obeys program HAND1 by default)

LIMB weapon_hand1 HAND1 -3 21 0 1
// shoulder-to-elbow
ELEMENT 12 -180 90 -90
// forearm
ELEMENT 12 0 170 0
// hand
ELEMENT 3 -45 45 0
SPRITE STATIC 0 NONE 0 0 player/wing
SPRITE STATIC 0 NONE 0 0 player/wing
SPRITE STATIC 0 NONE 0 0 player/wing
// sprite 0 = segment 0 (arm)
SPRITEVAR 0 LIMB 0
SPRITEVAR 0 OFFS_X 36
SPRITEVAR 0 SCALE 0.1666
SPRITEVAR 1 FRAME 1
// sprite 1 = segment 1 (forearm)
SPRITEVAR 1 LIMB 1
SPRITEVAR 1 OFFS_X 36
SPRITEVAR 1 SCALE 0.1666
SPRITEVAR 2 FRAME 2
// sprite 2 frame to be rendered when the limb is attached;
// value '-2' disables the sprite when the grip is held
SPRITEVAR 2 FRAME_ATTACH -2
// sprite 2 = segment 2 (hand)
SPRITEVAR 2 LIMB 2
SPRITEVAR 2 OFFS_X 14
SPRITEVAR 2 SCALE 0.1666
// hand bobs up and down by this multiplier when the
// entity moves; bobbing of hands should always match
// the bobbing of the torso
BOB -25
END

Now that the limb is set up, we can get to moving it. There are two ways to do this; automatically
by the pre-defined program or manually segment-by-segment. Which type of movement is used is
determined to variable called 'attachment' ( see: LIMB, POSE). If the limb is 'attached', it
automatically follows the program. The term 'attach' simply comes from the first limb implemented;
a weapon hand can either be loose or attached to the weapon grip.

And of course 'attached weapon hand' means that when the weapon moves – like when the player
aims up and down – the hand automatically follows the movement. Since TAGAP 3 is fully 2D,
rigging the weapons so that the limb movements don't look glitchy and funky can take a couple of
tries to get right.

With custom movement – without attachment – the limb is simply moved via pose scripts, segment
by segment. The input values for the limbs are simply angles. In an example of a hand, using
angles 0-0-0 would have it extended straight forward. Since this a bit tough to put into words, here
are a couple of examples;

[ 42 / 90 ]
// hand down, forward // hand curve up
POSE weapon_hand1 0 POSE weapon_hand1 0
POSE_ELEMENT -90 10 POSE_ELEMENT -45 10
POSE_ELEMENT 90 10 POSE_ELEMENT 45 10
POSE_ELEMENT 0 10 POSE_ELEMENT 0 10
END END

Whilst majority of limbs follow these rules – where input values designate the angle of the limb
segment – there are two special sorts that work a little differently. These are the eyebrow and the
eyes (see: LIMB). In case of the eyebrow, instead of an angle, the input value works as a modifier
telling how much the brow is curved up or down. For example;

// updward brow // angry brow
POSE eyebrow 0 POSE eyebrow 0
POSE_ELEMENT 1 10 POSE_ELEMENT -1 10
END END

Eyes are even more different in terms of input; Instead of speed and angle, the input values define
the relative position. For example;

// eyes default (ahead) // eyes slightly up
POSE eye1 0 POSE eye1 0
POSE_ELEMENT 0 0 POSE_ELEMENT 0 0.5
END END
POSE eye2 0 POSE eye2 0
POSE_ELEMENT 0 0 POSE_ELEMENT 0 0.5
END END

Now, custom poses can be set in two ways; either on entity transformation by giving the entity itself
a custom pose (see: POSESET) or during run-time with the trigger pose. Though not always, usually
the in-game actors (like enemies) have their poses set in entity scripts, whilst the use of pose
triggers is reserved to cut-scenes (both in-game and in sequence scripts).

And finally, there are pose animations. These are what you would expect, an additional scripts
that define a sequence or a loop of poses that are called upon an entity based on pre-defined
timing. The animation can be 'single-shot' sequence that is played only once, or looping one. In
TAGAP 3, the most common use of pose animations is with NPCs who are hanging around in the
background doing their own thing, like reading a magazine or lifting weights.

To create such animation, you need to first create the poses the animation uses and then create an
additional script with the information of the frames and the delay of them being used ( see:
POSEANIM). Once the animation has been created, add it to an entity ( see: SETPOSEANIM). As a
simple example of a pose animation script;

// start a pose animation (1 indicates it loops)
POSEANIM 1
// wait 1000 milliseconds to set pose 'example_pose1'
POSEFRAME example_pose1 1000
// wait another 1000 milliseconds to set pose 'example_pose2'
POSEFRAME example_pose2 1000
// wait another 500 milliseconds to set pose 'example_pose3'
POSEFRAME example_pose3 500
// since this animation loops, animation waits for another
// 1000 milliseconds to set pose 'example_pose1'
END
// always end a script file with TAGAP_END
TAGAP_END

[ 43 / 90 ]
Note that it is not necessary to create separate animation scripts for every little animated
sequence. In fact, majority of even the most complex sequences in TAGAP 3 are created using
delayed pose triggers fired in a sequence through a multitap.

This is just the basics of the skeletal animation system and setting up poses. I am not even going
to try to explain everything this system can do, since over all these years of development I honestly
believe even I've forgotten a trick or two. I strongly recommend you to delve deep into TAGAP 3's
animation files for examples and inspiration.

Entity-within-entity objects
An acting in-game entity – enemy, NPC character, whatever – can consist of not just one, but
multiple entities. There are two three kinds of 'sub-entities' – objects, weapon models and group
members (see: OBJECT, GUNENTITY and GROUP).

First of these, weapon models (see: GUNENTITY), are is exactly what it says in the name – entities
that are rendered as the weapons the main entity wields. These weapon models can be set up one
of two ways – either for the main entity itself, or, more commonly, in for the weapon entity. We
already covered weapon models more thoroughly in the chapter Basics of Scripting: Weapons
scripting.

Next up; objects (see: OBJECT). These are purely decorative objects that have no actual effect on
gameplay itself.

Why would anyone do this? Since objects are full entities, they can have the full entity properties
(apart from limbs). This means that instead of just a jumble of sprites, objects can have lights,
generate particles, be angled and moved entirely depending on needs ( see: FX_FULLMODEL of
STAT) and even have different activity states than the main entity ( see: AI_ACTIVE_MODIFIER of
STAT).

Simplest objects are just rendered along with the main entity, based on the offsets given. For
example the TAGAP 3 Spacepod has several sub-objects – the Theremin engine in the back and
the four sub-hull jets. The objects aren't necessarily that static, as you can set their behaviour. For
example, you can have the object to drop to the floor level and light itself with the ground; this is
perfect for creating wheels of a car – or suspension-mounter tank tracks.

For seasoned TAGAP modders, there is a new, very useful behaviour model available in TAGAP 3;
a hold-object (see: HOLDOBJECT of OBJECT). It functions the same your normal object, except it is
rendered as if it's being held in the main entity's hand. If that character moves its hand, the hold-
object placed in that hand moves accordingly. Additionally, if a melee-entity that has no weapons
(see: AI_MELEE of THINK), has hands and has a hold-object, upon attacking the hand holding said
object is animated as if the entity punched with it. You guessed it, all the level-specific custom
entities carrying various tools have 'hold-objects'.

Objects – both normal and hold-objects – can have their own 'items' ( see: ITEM). This means that
when the main entity dies, not only does it drop its items, the objects that have items drop theirs as
well. This is how an entity dropping the item they hold in their hands works.

And finally, an entity can have a sub-group of other, acting entities (see: GROUP). Entities in a
group act autonomously, but are part of a whole in a way defined in the script. Depending on the
grouping rules and the AI of the entities in the group, you can have a wide variety of different kinds
of scenarios, but let's have a couple of examples.

A simple example of usage of group in TAGAP 3 would be the Absorbia flower seen in the
botanical gardens. The main entity is the flower and the buds you need to destroy are its group
members. As group rules, these buds are set as COLLECTIVE; this means that the main entity

[ 44 / 90 ]
can't be damaged until all the 'collective' members have been killed off.

Or, from the same level, the mushroom robots are, too, group entities. The main entity has all the
basic functionality and art assets, but it does have an invisible group member. See, the
'indestructible, bullet-blocking cap' is a group member (group rule: MEMBER) and has AI of
AI_CONSTANT. This means that the invisible group member follows the main entity everywhere
(defined by the cap's AI setting) and is simply along for the ride for as long as the main entity is
alive (as told by the group rule).

But when it comes to groups, things can get insanely complex, often in ways that aren't visible to
the player. This is especially in the case when you bring entity transformations; if you want the
group members to transform into something else, too, they have to have their own transformations
set up!

Speaking of...

Transformations
What makes the combat dynamic in TAGAP 3 (and TAGAP 2) is the use of on-the-fly entity
transformations. This means that an entity can be transformed into a completely different entity on
the fly. This can be used to create animated sequences using sprite variable animations
“HIDE_<suffix>” (see: SPRITEVAR), create literal transformation sequences (i.e. Pablo steps onto
the tram) or even form the basis of boss attack patterns.

The basics are simple enough. There are only two commands to apply transformation; with
TRANSFORM you can transform the current entity to any one defined earlier in the scripts by
referring to its name and with TRANSFORM_DIRECT you can transform to ones defined later via
entering their index number (as an offset from the current entity, i.e. the entity next from the current
one has offset index 1).

In addition the entity name and entity index, all you have to type in is the transformation timer.
Defining the time in milliseconds means that when the entity is woken up (either toggled on,
spawned or transformed into the entity) it will remain that entity until the said amount of time has
passed. Then, naturally, it transforms. You can create infinite loops as well by transforming back to
the first (or any other) entity in the transformations chain with TRANSFORM_DIRECT; Boss attack
patterns, for example, work just like this. Alternatively, you can use negative time value (“-1”),
which won't transform the entity on the fly, but when it dies.

If you want toggling effect ( see: EFFECT) to work upon transformation, add AI_FIRE_ON_ACTIVE
flag (see: STAT) to the entity you are transforming an object to. Also, by default transformation
ignores the temporary life span of the target entity, so if you want the entity to drop off after the
transformation, use AI_TEMP_ON_ACTIVE with the original entity (see: TEMPMISSILE an
AI_TEMP_ON_ACTIVE of STAT). If you have copied an entity (see: CLONE) and want to remove the
transformation, simply add “TRANSFORM NONE 0” somewhere after the cloning command.

– group transformation --

Sequences
Sequences are toughest part of scripting and really hard to describe, as they are more or less
based on exploiting the game routines in every possible way imaginable. Instead, this chapter
describes the basic concept of doing animation sequences in TAGAP 2.

Perhaps the best way to start scripting a sequence is by first adding all the relevant configuration
variables, or CVars (see: Appendix C: Configuration Variables, CVAR), most notably music to be
played, save game allowance, level theme and, in case of cutscenes, the next single player an co-

[ 45 / 90 ]
op level. Note that there's no sense in adding an audio stream at this point, as there's nothing to
sync it with yet. Next, to make testing a lot easier, you should add a temporary sequence button
that restarts the sequence. This way you can run TAGAP 2 in window and write the script and/or
edit its graphics at the same time, just reloading the script in-game. To do this, use SEQUENCE and
make it a sequence button, with the filename of that sequence as a target. Simple.

Now once the framework is done, its time to start creating the content. Basically sequences fall into
three categories; in-engine animations with entities and level objects, image layer based
animations and complex combinations of both. Image layer based ones are the easier, I guess, so
let's start with those. Once you have the graphics, add them in with LAYER command. The image
manipulation is done with image flags (see: SEQFLAG). Scaling, moving, rotating, it's all done with
those. There's no need to go into details how to do some particular trick, as you're bound to learn
more from just messing around and experimenting with the flags. Just note that most of the flags
can be set to affect whole scene instead of an image by using index pointer -1.

Making in-engine animations is more complex and requires some experience in scripting already
under your belt. First you naturally need to make the level data and it's obviously easier to do with
the level editor. Start a new map and go to geometry mode. Unlike with the original TAGAP, there is
no need to force the level content to the global origin (x0, y0); You can use sequence flag OFFSET
(see: SEQFLAG) to move the camera anywhere you want. The entities used for sequence scripting
aren't shown in editor, so add any entity, just replace them with text editor later. Save the level and
open it in text editor. Now copy all the contents except CVars from the level file to the sequence
script and restart TAGAP to that sequence (see: Appendix C: Configuration Variables). In the text
editors swap the entities to the ones you wanted by replacing their names – the positions you set in
editor should be right. Save the file and hit that reload button you made first. And enjoy the show.
I'm sure what you'll see is far from cool action scene you wanted to make, but it's a start.

By default, the dynamic graphics and sounds are flushed every time a new script is loaded. This is
fine with simple animations of one script, but if you want to do more complex cinematics with timed
music and audio streams, it's strongly recommended to use “noreload” ( see: Editing Variables).
Enabling that prevents graphics from being unloaded from memory, allowing loading all the
graphics on starting script, making the cinematic smoothly flow through multiple scripts without any
load times in between. Variable “noreload” reverts back to zero after each script load for obvious
security reasons, so you have to enable it again before every transition beyond which you want to
keep the graphics. Dynamic sprites of entities ( see: ENTITY, SPRITE) are also not flushed, so to
preload an entity, define a “spawner” trigger ( see: Using Triggers, TRIGGER) with the entity you need;
It won't show-up if you don't activate the trigger, but it's graphics are still loaded.

Now you know how to set up a one script, but how about longer animations? It all starts with
understanding the structure of a longer sequence chain;

1. Loader script
Loader (usually “_loader.txt”) is a script with nothing going on, it just features all the entities,
graphics and sounds for pre-loading purposes. All image layers are disabled (see: DISABLE
of SEQFLAG), noreload is set to 1 (see: noreload of Editing variables) and the timer to load the
next sequence – the first actual frame of the sequence chain – is no longer than 50
millisecond (see: TIMER of SEQUENCE).

2. Sequence chain
The actual content of the cutscene goes here. There is really no limit to how long a chain
you can create, but remember that more stuff you have to load, the longer it takes and
more memory it will consume. Take note that, as mentioned earlier, TAGAP 2 has a lot
better camera controls, meaning you don't have to do a separate script for every camera
cut. Sequence chain items all have noreload is set to 2 (see: noreload of Editing variables) and
the layers not used in the current script are disabled (see: DISABLE of SEQFLAG). The skip

[ 46 / 90 ]
button, as well as the command loading the scenario after the final script in chain, should all
refer to the next step, Buffer frame, for reasons explained ahead.

3. Buffer frame
If the scenario after sequence chain is another sequence (i.e. “Level Completed” scene),
you'll need a buffer frame. This is an empty frame with all image layers are disabled (see:
DISABLE of SEQFLAG), noreload is set to 0 (see: noreload of Editing variables) and the timer to
load the next sequence – the first actual frame of the sequence chain – is no longer than
50. Disabling the layers is important, as the memory isn't flushed until after the buffer frame
is loaded, meaning the layers without DISABLE flag will be rendered. While you might think
this is weird or bug, it's actually crucial feature if you want to do data loading in the middle
of sequence chain and have something else but solid black on screen.

The most used example of buffer screen in TAGAP 2 is “intermission/skip.txt”; This clears
the memory, disables all possible layers and loads the regular “Level Completed” screen.
Buffer frame isn't necessary if the next scenario from the sequence chain is the game itself;
The actual game always flushes memory clean before loading an actual level.

Knowing the structure, you can get to actual planning the cutscene. This is how I personally
mapped out all the sequence chains;

1. Write a script and preferably design some storyboards

2. Plan the actual scripts; What camera cuts need to be separate scripts and what you can o
with in-script cuts? How the camera pans affect things? Where might be a good spot to
flush memory and load the data for the next batch of scripts?

3. Create the individual frames, all with noreload 0; It's easier to test them this way.

4. String the scripts into a chain, still using noreload 0. If you haven't done so, go to editor
setup ( F8 or “Editor setup” in editor), toggle “detailed log” to “on” and watch the whole
thing. Copy the log (“user/log.txt”) into another text file.

5. Create the loader and use the above created text file as your guide on what entities need to
be defined there for pre-load. You'll know what they are, as they are logged into the script
during loading of each script.

6. Change the noreload variables as described earlier and possibly, depending on how you
planned things, re-organize the layers. The latter matters, as every layer stays in the slot
and position defined in the loader script. Also, if you reposition a layer ( see: RELOCATE of
SEQFLAG), the modified position carries over to the later scripts.

Creating sequences is pretty much “everything goes as long as it works”. If it can't be done directly,
it can be hacked with workaround. And if it can't be done with workaround, it can be faked. While
creating the game, every time I started doing a new sequence I was surprised by the flexibility of
the system, as it's simple but offers so many options. All you need is imagination and too much
spare time. And love for machimina.

[ 47 / 90 ]
Appendices
Appendix A: Editor Controls
GUI controls
F1 - F3 Switch editor mode
F5 Next level * / **
F6 Toggle between game and the editor
F7 Restart level *
F8 Editor setup
Ctrl +S Save level
Ctrl +L Load level
Ctrl +X Instant quit

General editor controls
Arrows Nudge selected object by one pixel
Alt +Arrows Nudge selected object by one grid
Shift +Arrows Nudge selected object by half a grid
Home Centre view on player start position
End Centre view on level exit trigger
Shift Hold to move entire object instead of a point
Alt Hold for grid-free movement
PgUp / PgDown /Mouse wheel Select next / previous object in the list
Tab Centre view on the current object
Del Deletes current object

Ctrl + Shift + Home Delete all objects before mouse cursor
Ctrl + Shift + End Delete all objects after mouse cursor
Alt + Ctrl + Shift + Home Delete all objects below mouse cursor
Alt + Ctrl + Shift + End Delete all objects above mouse cursor
Alt + Arrows Nudge object by one pixel
Alt + Shift +Arrows Nudge object by a half grid unit

Geometry mode
Space Add/complete a linedef
T Add a trigger field
Backspace Cancel linedef / trigger field
C Changes style of current linedef
E / I / D Adds an actor / item / decoration entity
G Copies entity or trigger; use E , I , D or P to paste
P Pastes the copied trigger
L Automated link tool
Shift + L Linear link tool
F Select target of the current trigger
O Select owner / user of the current trigger
M Multitap editor
~ Repositions parallax guide
Insert Relocates the player #1 start point
Shift + Insert Relocates the player #2 start point
, / . Replace the current entity with previous / next entity ***

[ 48 / 90 ]
Texture mode
R / T Adds rectangular polygon
Space Starts drawing custom polygon
Backspace Cancels the previous polygon point
Enter Completes the polygon
G Copies the selected polygon
P Pastes the copied polygon
D Grab texture to fill tool
F Use fill tool on polygon
H Flip a polygon horizontally
V Flip a polygon vertically
1 - 8 Set the polygon texture offset point
~ Set the polygon to use the world texture offset
Ctrl Hold for Overdose view
Mouse 2 Disable tagged polygons from view
Mouse 3 View polygon wireframes
Shift + PageUp / PageDown Change the rendering order of polygons
, /. Replace the texture with previous / next texture
F4 Import textures from a map file

*) only available in-game;
**) only available when cheats are allowed
***) when an entity or a trigger using entities is selected

[ 49 / 90 ]
Appendix B: TAGAP_Script Syntax
For ease of browsing, this appendix is split into four categories. Entity commands section covers
commands for entity creation and manipulation. Limb commands features commands for entity
limb structure and skeletal animations. Definition commands describes available game definitions.
Scripting commands covers event- and map specific commands used for in-game levels and cut-
scenes..

Take note that not all script commands are always accessible, like you cannot set an entire world
into a sprite. Don’t worry, though, all invalid script lines will be ignored by the parser and are
reported in the user log.

Each actual command line starts with id string that tells the script parser the form of the current
command. Here is the complete list of script commands (read: [id string] <variable input type>).

Entity commands
ACID <string>
description: Defines an hallucination alternative for entity when experiencing heavy overdose
syntax: <string> name of the replacement entity
notes: Hallucination entity must be defined before the currently parsed entity.

ALTERNATIVE <string>
description: Defines an alternative version of the entity used at random to replace the current one.
syntax: <string> name of the replacement entity
notes: Alternate entity must be defined before the currently parsed entity. In TAGAP 3 alternative entities are used mainly
to add female alternatives for certain entities. Unlike all other variables, ALTERNATIVE is not copied to a new entity
upon cloning (see: CLONE), meaning you'll have to set it up again.

AMMO <int #1> <int#2>
description: Player ammunition for specific weapon slot.
syntax: <int #1> weapon slot index ; <int #2> ammo amount
notes: Player can have up to 10 weapon slots only weapon slots 1-9 can have ammunition (see: WEAPON). Weapon 0
doesn’t use ammo. However, ammo slot 1 of weapon entity is used to define clip size for weapon slot 0. The
weapon item ammo values also define the ammo quantity of “guncloset” triggers (see: TRIGGER, guncloset).

AUTOTRIGGER <string #1> <string #2>
description: Creates a trigger field of desired type that is automatically linked and related to the entity.
syntax: <string #1> trigger style ; <string #2> trigger string
notes: See chapter Using Triggers for full list of available triggers and their options. Mainly used to create trigger-based
wall-mounts and alike. Entity is automatically linked and related to the trigger until the entity dies. However, you can
pass the generated trigger onto other entities via AI_INHERIT_TRIGGER (see: STAT).

CLONE <string / int>
description: Clones all info of an existing entity (in entity scripts) or weapon (in weapon scripts, see: WEAPON).
syntax: <string> the name of the entity to clone ; <int> index of the weapon slot to clone
notes: Entity or weapon slot to be cloned must be defined before the clone. Useful when creating multiple similar entities
or weapons, like containers spawning different goods – modifications made to the original affects all clones as well.
When copying entities, two variables are not cloned; ALTERNATIVE and NOLIST (see: STAT). More often than not
these variables need to be re-set anyway, so it's better for scripting work flow to always re-set them on cloning.

For entities, there is also an alternative way to clone an entity in a way that leaves the graphics and limb data out of
the copy process (see: CLONE_ALT).

[ 50 / 90 ]
CLONE_ALT <string>
description: Clones all info of an existing entity (in entity scripts).
syntax: <string> the name of the entity to clone
notes: Alternative to classic CLONE command, CLONE_ALT copies everything except graphics and limb data. This way
you can copy the behaviour and sounds of an entity, but 're-skin' it with completely different artwork.

COLLECTIVE <string>
description: Defines the collective membership for an entity.
syntax: <string> the name of the collective leader entity
notes: All collective members will relate to the first leader entity in the list thus allowing only one collective of each type
per-map. Collective leader cannot be damaged until the members are killed. Use this if you want to do, say,
generator-powered boss monster or something like that. Use GROUP for other entity grouping options (see:
GROUP).

COLOR <bool> <byte #1> <byte #2> <byte #3>
description: Defines a custom color for the entity.
syntax: <bool> color index (0 or 1) ; <bytes> light color in RGB
notes: Each entity can have two custom colors that are used by some effect generators (see: EFFECT).

CORPSE <string> <int> <bool>
description: Defines a corpse for an entity to be thrown upon death.
syntax: <string> the name of the corpse entity ; <int> y-wise throwing offset (from entity origin) ; <bool> only drop the
corpse when frozen
notes: Corpse must be defined before it can be assigned. Most of the corpse handling is done engine-side, so you don't
have to worry about how it spins etc.. Corpses can also be “detailed” by assigning a kill effect to damage inflicter
(see: KILLFX). I case of entities rendered via triggers (see: guide, hologram) the corpses represents the entity
drawn when the object is broken.

Since TAGAP 3 has the new 'freeze' damage type (see: AI_FREEZE of STAT), there is a new flag to utilize: you can
set the entity to 'drop a corpse' only when it's been frozen to death. If the flag is set off, the corpse dropping works
as before.

DESCRIBE <string>
description: Defines a description for an entity.
syntax: <string> short description
notes: Descriptions are not necessary, but they aid level editing a lot. Naturally entities that can’t be used in editor won’t
obviously need descriptions. In case of entities used as weapon slots (see: WEAPON) the description string is used
as the inventory display name.

EFFECT <string #1> <string #2> <int #1> <int #2> <int #3>
description: Adds event effects to an entity.
syntax: <string #1> event tag ; <string #2> effect to add ; <int #1> effect x-offset ; <int #2> effect y-offset ; <int #3> effect
scale / quantity in per cents
notes: Scale defines effect size, whether it's quantity of debris or size of an explosion. However, you can let the engine
calculate an approximation for you (this gives pretty good results in most cases) by setting the scale to 0. When 0
scale is used, the amount of debris is defined by the size of the entity (see: OFFSET) and the explosion size is set
according to the entity's splash damage (see: DAMAGE_SPLASH of STAT). Event effects can also be added to kill
effects (see: KILLFX). Weapon-specific effects like muzzle flashes and shell casings are controlled via effect stats
(see: STAT). Possible event tags:

DYING = entity falling apart before actually dying
GIB = entity blows apart
SHATTER = entity is shattered when frozen
TOGGLE = entity is toggled on/off
WEAPON = entity attacks via shooting

Possible effects:

NONE = clears all effects for the designated event (especially useful with entity clones, see: CLONE)

[ 51 / 90 ]
EFFECT <string #1> <string #2> <int #1> <int #2> <int #3>
AREA_GLASS = instead of spawning the debris from the origin, this command uses the area covered by the entity's
physical size (see: FX_DEATHEFFECT of OFFSET), which can be manipulated further with FX_USERANGE
(see: STAT)
AREA_GLASS_C = same as AREA_GLASS, only referring to entity colours (see: COLOR)
BULLET = bullet impact
BULLET_LITE = light bullet impact with plain sparks
CLOTH = cloth debris (basically coloured version of PAPER), refers to entity colours (see: COLOR)
CLOTH_C = same as CLOTH, but refers to the secondary of the entity colours (see: COLOR)
DEBRIS_FROST = creates a cloud of ice frost and steam
DEBRIS_GLASS = throws loads of glass debris and a few metal fragments
DEBRIS_ICE = throws shards of broken ice
DEBRIS_METAL = throws metal fragments and smoke
DEBRIS_METAL_C = throws coloured metal fragments and smoke (for color definition, see: COLOR)
DEBRIS_NANITE = throws nanite fragments
DEBRIS_STONE = throws concrete rubble and dust
DEBRIS_WOOD = throws wood shrapnel and dust
DISTORTION = distortion shockwave (like when tripping acid)
DUST = dust particles, based on the defined entity colours (see: COLOR)
EXPIRE = effect of plasma trail (FX_PLASMA_TRAIL, see: STAT) fading away
EXPLOSION = an explosion
EXPLOSION_NANO = nano weave explopsion
EXPLOSION_NANO_REV = nano weave implosion
EXPLOSION_PLASMA = energy explosion, refers to light colours (see: LIGHT)
EXPLOSION_PUSH = expanding sonic wave, refers to light colours (see: LIGHT)
EXPLOSION_SPARKS = pure-spark explosion, refers to light colours (see: LIGHT)
FEATHERS = throws up feathers based on the defined entity colours (see: COLOR)
FLAMES = a puff of fire, refers to light colours (see: LIGHT)
FLASH = simple flash of light
GORE_BLEED = small blood impact (quantity value works as angle in degrees)
GORE_BLOOD = spews out blood
GORE_GIBS = throws lots of blood and the severed eyeballs
LEAVES = throw green leaves
LIQUID_BLOOD = splash of blood drops
LIQUID_CLONE = splash of clone embryo liquid
LIQUID_CRYO = splash of cryogenic liquid
LIQUID_LAVA = splash of lava
LIQUID_MUD = splash of muddy water
LIQUID_POISON = splash of dark poison
LIQUID_SLIME = splash of radioactive goo
LIQUID_WATER = splash of clear water
NANOWALL = creates effect of nanite wall shutting down
PAPER = spew some paper debris and some metal fragments
PIXELS = explosion of pixels based on the defined entity colours (see: COLOR)
SPARKS = electric spark
SPARKS_COL = coloured electric spark, refers to entity light for colour (see: LIGHT)
STEAM = same as DUST, only this one is affected by FX_SMOKE_ALPHA (see: STAT)
IMPACT = laser-styled projectile impact, refers to entity light for colour (see: LIGHT)
TELEIN = teleport effect for entity appearing
TELEOUT = teleport effect for entity disappearing

END
description: Stops parsing values for current object (i. e. entity, polygon, etc.) and adds the to the list.
syntax: –
notes: Always close objects with END. Related objects: ENTITY, CUSTOMENTS, LIMB, MESSAGE, MULTITAP,
POLYGON, POSE, SEQCUT, THEME, VOICEOVER, WEAPON.

ENTITY <string>
description: Starts parsing values for a new entity.
syntax: <string> name of the entity
notes: Keeps parsing entity variables until entity is closed (see: END).

FLASHLIGHT <int #1> <int #2> <int #3> <int #4> <byte #1> <byte #2> <byte #3>
description: Adds flashlight to the entity.
syntax: <integer #1> flashlight origin x-axis offset ; <integer #2> flashlight y-axis offset ; <integer #3> light halo radius (in
percents) ; <integer #4> light beam length (in percents) ; <bytes> light color in RGB
notes: Flashlight won’t appear in fully lit levels (read: darkness set to 0, see: DARKNESS). Only one flashlight can be
defined per entity, but it can bee multiplied with FX_MULTITORCH (see: STAT). You can also force lights to use
global environment colors instead of preset colors with FX_DIM_LITCOLOR (see: STAT).

[ 52 / 90 ]
GROUP <string #1> <string #2> <int #1> <int #2> <int #3>
description: Adds other entity to current entity’s group.
syntax: <string #1> name of the entity ; <string #2> relation id ; <int #1> origin x-offset ; <int #2> origin y-offset ; <int #3>
constant angle
notes: Setting up a group affects pretty much everything in an entity, so to ensure everything works set groups at the very
end of entity definition. To use constant angle, the grouped entity must have constant angle flag set (see:
AI_KEEPANGLE of STAT). You can also define collectives that are level-bound instead of group-bound (see:
COLLECTIVE).

By default, group entities are rendered as, well, separate entities – meaning you can't, say, render limbs of the
group owner, then the group entity and then the rest of the group owner. However, you can do something like that
with STANDIN objects (see: OBJECT); That command converts the first group entity defined to be rendered in
place of an object instead.

It is also worth noting that while the very first TAGAP made all group members with AI_CONSTANT behaviour (see:
THINK) refer to the group owner for all main rendering values (angles, facing, etc.), it's no longer the case.
However, you can force the engine to revert to the classic way of doing things with AI_COLLECTIVE tag (see:
STAT).

Possible relation ids:

COLLECTIVE = creates collective union between current entity and the member
MEMBER = member's death doesn't affect current entity
USER = death of member immobilizes current entity

You can also reset and nullify the group of the entity by setting the name to “NONE”. This can become
very handy when dealing with entity clones (see: CLONE).

GUNENTITY <string> <int>
description: Sets an entity to be drawn as entity's weapon.
syntax: <string> name of the entity to be used; <int> rendering order (0-2)
notes: Entity must be defined before it can be used. You can define weapon entity for both weapon slots (see: WEAPON)
or directly for an entity. The rendering order is as follows; 0 = front of entity, 1 = behind entity but before the
background limbs and 2 = behind all entity objects. You can also use different entities for each firing mode. The
entity for primary firing mode is still used as default weapon entity.

In TAGAP 3 the role of the weapon entities can emit sounds as well. For example, if you add a sound loop (see:
S_LOOP of SOUND) to the weapon entity, the said loop will play when the weapon is firing, thus letting you use
continuous loops as attacking sounds for rapid fire weapons. For example continuous loop sounds a lot better on
Thereminizer than any one-shot shooting sound would've done.

Also new in TAGAP3 is the option to alter the rendering order of the weapon objects. The entity can be forced to
render all the weapons in front of the entity, behind it – or disable the weapon object rendering altogether! This is
done via status variable FX_WEAPON_LAYER (see: STAT). This can come in handy especially when creating in-
engine animations involving player stand-in entities (see: AI_STANDIN of STAT).

GIB <string> <int>
description: Defines an entity thrown as special debris on death.
syntax: <string> name of the entity to be used ; <int> amount of debris to throw
notes: Entity must be defined before it can be used. You can define just one debris per entity. This works for items, too, but
there is another, more specific function to do just that (see: ITEM).

ICON <string>
description: Entity that appears in status bar or in messages. Used in entity scripts (see: ENTITY) and voiceover scripts (see:
VOICEOVER).
syntax: <string> name of the entity to be used as icon
notes: Icon entity must be defined before attaching it via ICON. If there's no icon defined for an inventory item, the entity
will be rendered to status bar as-is. Boss gauge of AI_BOSS (see: STAT) requires that entity has an icon. Voiceover
icons will be shown when the voice is related to a dialogue message (see: Using Triggers: dialogue, VOICEOVER)
or when when the dialogue is between two players in splitscreen. In the latter case, if the avatar of the player other-
than-you says something, it will be shown in your screen accompanied by the icon defined for his/her/its avatar.

[ 53 / 90 ]
ITEM <string> <int #1> <int #2>
description: Defines an entity to be dropped when the current entity dies.
syntax: <string> name of the entity to be spawned ; <int #1> item x-offset ; <int #2> item y-offset
notes: To-be-spawned entity must be defined before the spawner. ITEM can also be used to spawn other entities than just
items, like smoke generators for flamethrower or ejecting pilot for destroyed chopper. You can define up to three
items per entity. If that isn't enough, you can use gibs for more flying debris (see: GIB). You can randomize the first
item entity with AI_ITEM_RANDOMIZER (see: STAT). To clear all items – say, in case of a entity clone (see:
CLONE) – just add an item of name NONE (“ITEM NONE 0 0”).

KILLFX <string>
description: Defines kill effect entity for weapon entity. Used in weapon definition scripts.
syntax: <string> the name of the effect entity
notes: The basics are as follows; When entity (projectile or a character) with assigned kill effect kills an actor with assigned
corpse (see: CORPSE), that corpse will inherit special effects of the kill effect. For example if kill effect creates
smoke, then the flying corpse will also create smoke. Use STATs and EFFECTs to add effects to kill effect (see:
STAT, EFFECT). Effect must be defined before it can be assigned.

LIGHT <int #1> <int #2> <int #3> <int #4> <int #5> <byte #1> <byte #2> <byte #3> <int #6>
description: Lits the entity with RGB-coloured light.
syntax: <int #1> light x offset ; <int #2> light y offset ; <int #3> light beam length ; <int #4> light beam angle ; <int #5> light
radius (in per cents) ; <bytes> light colour in RGB ; <int #6> light intensity (in per cents)
notes: Lights with negative radius value will disable all lights defined for the entity before that point (in particularly useful
option when using clones, see: CLONE). By defining a length for the light you can turn it into a light beam,
otherwise it will appear as a halo. If the entity is a traceline projectile – missile without a sprite – defining lights will
make the projectile appear as a beams of light. You can also force lights to use global environment colours instead
of pre-set colours with FX_DIM_LITCOLOR (see: STAT).

MISSILE <string>
description: Sets a projectile to be spawned on attack or sets the grenade entity.
syntax: <string> name of the entity to be spawned
notes: To-be-spawned entity must be defined before the spawner. Can also be used to spawn other entities than just
missiles. Use offset variable WEAPON_MISSILE (see: OFFSET) to set the launching offsets different than the
engine default and status variable MISSILE_OFFSETRADIUS to define the aiming radius (see: STAT). You can
randomize the fired entity with MISSILE_RANDOMIZER (see: STAT). To add multiple weapons combine projectile
definition with weapon slots (see: STAT and WEAPON). To transform missile into a grenade, use
AI_GRENADE_TIME (see: STAT) or (in case of player entities), just define a missile. Grenade entity always uses
S_GRENADE (see: STAT) for quantity.

MOVETYPE <string> <float>
description: Sets movement type for an entity.
syntax: <string> movement style tag ; <float> speed of movement
notes: Everything is NONE by default, except missiles, which are FLY. Possible movement styles:
NONE = static
FLY = flying movement
WALK = affected by gravity.

OBJECT <bool> <string #1> <int #1> <int #2> <string #2> <int #3> <int #4>
description: Defines an entity to be rendered as a part of the current entity.
syntax: <byte> behind (0), in front of (1) or inside of (2) ; <string #1> object entity ; <int #1> x-offset ; <int #2> y-offset ;
<string #2> behaviour ; <int #3> range A (on x axis or down) ; <int #4> range B (on y axis or up) ; <int #5> forced
angle
notes: Object entity must be defined before called as an object. LIGHTOFFS relates to sprite offsets set while rendering
(see: LIGHT_OFFSET of SPRITEVAR) and thus it doesn't necessarily always work as it should in case of objects
rendered before (behind) the entity. Possible behaviour references:
BOB = bob up and down (works like sprite variable BOB, see: SPRITEVAR)
CHAINGUN = Renders the object as a chaingun effect similar to that of sprite (see: CHAINGUN of SPRITEVAR). Range
A defines the amount of objects rendered (negative rotates them into inverted direction) and Range B sets
the range from the rotation axis. For the rotation angle, chaingun refers to aiming angle so that it'll make
using these kinds of objects easy with fans (see: Using Triggers: fan). Note that chaingun object renders only

[ 54 / 90 ]
OBJECT <bool> <string #1> <int #1> <int #2> <string #2> <int #3> <int #4>
one layer of the object halo – foreground or background – and which it is defined by where the object is
rendered (in front of or behind the main entity).
DROP = drops object to the floor or to maximum range (range B) from entity
HOLDOBJECT = hand-held object that is dropped on death. The hand the object is held in is defined by the byte tag; If
the object is behind the entity, object is in HAND2, otherwise it's in HAND1 (see: LIMB). The dropped version
of the hand-held object is the item (see: ITEM) of the object entity.
LIGHT_OFFSET = use entity's light offsets for origin manipulation (see: LIGHT_OFFSET of SPRITEVAR)
SPIN = spin around given origin (range A is distance from origin, range B is spinning angle offset)
STANDIN = entity works as a stand-in for the first entity in entity group (see: GROUP); for per-sprite alternative, see
sprite variable STANDIN (see: SPRITEVAR)
NONE = static, no behaviour set

OFFSET <string> <float #1> <float #2>
description: Defines a offset value for an entity or weapon (see: ENTITY, WEAPON).
syntax: <string> variable name ; <float #1> x-offset ; <float #2> y-offset
notes: Be careful with missile offset values – values outside entity physical size will allow it to fire through walls. For non-
weapon slot based missiles use STAT MISSILE_OFFSETRADIUS (see: STAT) to define radius distance different
from entity's size.

In case you want to modify only the floating range but not time, use FX_CONSTANT_FLOAT with x-offset 0.

All weapon-specific offset are offsets from the weapon origin (set with W_ORIGIN), except, of course, W_ORIGIN –
which in turn is offset from the entity origin. Or more simply; W_ORIGIN is relative to the entity origin, while all the
rest are relative to W_ORIGIN.

Entity variable references:

CONST_VELOCITY = constant velocities (not very practical for in-game AI, but useful in creating sequences)
FX_ARMOR_FRAME = for entity to use armour sprites even if there is no armour (x value is the armour slot 0-3, while y-
offset works as a boolean flag for the override (0 = off, 1 = on)
FX_BREATH = offsets for the mouth for breathing; for more control over breathing, see FX_BREATHE (see: STAT)
FX_CAMERA =custom setups for the in-game camera (player entities only)
x-value = y-offset of camera (in pixels, default is 100)
y-value = zoom of the camera (in per cents, default is 130)
FX_CONSTANT_FLOAT = time and range modifier for constant, non-origin related floating
FX_DEATHEFFECT = debris spawning area of large entities dying and/or area-based particle effects (see:
AREA_GLASS* of EFFECT); you can modify this area dynamically by using FX_USERANGE (see: STAT)
FX_FULLMODEL_SCALE = entity full scale modifier, x-value is the main scale, while y-offset is the starting scale. If the
two values differ, the scale of the entity is transformed from y-offset to the x-offset upon activation
FX_HIDE_MOVE = full-entity movement on activation/deactivation (in pixels, for controls, see: AI_HIDE_ANIM of STAT)
FX_MUZZLEFLASH = muzzle flash for weapon attacks (x value defines the size, while y-offset is the length of the flash)
FX_OFFSET = fixed special effect offset (from entity origin)
FX_RANDOM_FRAME = random sprite frame value for the entity (x is storage slot 0-5, y is maximum value). For
information on how to use sprite see FRAME_RANDOM of SPRITEVAR.
FX_RANDOM_STATIC = forced random frame; replace the target random frame (x value) with a static value (y).
LIMB_LOCK = locks a limb, preventing it from animating (x is limb index, while y is boolean flag defining the lock)
SCRAP = defines the amount and type of scrap generated on death; x-offset is amount, while y-offset defines the type:
0 = mechanical scrap
1 = electronic scrap
2 = both electronic and mechanical scrap
3 = just pieces of metal
SIZE = entity dimensions (collision sphere size and height)
TRANSFORM = appearing offset of target entity when transforming (see: TRANSFORM)
W_HIDE = move weapon by this amount of pixels when the entity is toggled off
W_MISSILE = missile launching offset for non-weapon slot missiles (see: MISSILE) (from entity origin)
W_OFFSET = additional offset for the hand-held weapon (for weapon user entity)
W_ORIGIN_MOD = moves weapon vertically when looking up (x-offset) or down (y-offset) (for weapon entity)
W_ORIGIN_MOD_H = same as W_ORIGIN_MOD, but moves the weapon horizontally (for weapon entity)
W_ORIGIN_SLIDE = weapon holding offsets when the player is sliding (for weapon entities, from entity origin)
W_STAT = weapon stat (x-offset is the weapon lost, y-offset defines the amount of ammo)

Weapon variable references:

W_BOB = bobbing of the weapon when the entity moves
W_ORIGIN = origin of the weapon as an offset from the entity origin
W_OFFS_CASING = offset for shell casings, some of the additional exhausts and optional hands (see: HAND3 of LIMB)
W_OFFS_GRIP = offset of the weapon stock or front grip for back hand (see: HAND2 of LIMB)
W_OFFS_HANDLE = offset of the weapon main grip for primary hand (see: HAND1 of LIMB)
W_OFFS_MUZZLE = offset of the weapon barrel (source of muzzle flash and projectiles)

SCISSORS <int #1> <int #2> <int #3> <int #4>
description: Adds scissor area rectangle that will cut out portions of sprite that exceed the defined area.
syntax: <int #1> area start x-offset ; <int #2> area start y-offset ; <int #3> area width ; <int #4> area height
notes: Simple entity cut-away stencil tool. Scissors are axis aligned; This means no matter what the orientation of the

[ 55 / 90 ]
SCISSORS <int #1> <int #2> <int #3> <int #4>
entity, the stencil will always be an axis aligned. If you need an entity-aligned and more customizable, non-
rectangular stencils, use STENCILMASK (see: STENCILMASK).

Usage of scissor mask is toggled with STAT FX_SCISSOR (in case of group entities, see: STAT) or with sprite
variable SCISSORS (on per-sprite basis, see: SPRITEVAR). If entity is part of a group, scissor mask of the group
originator is used instead. Scissor area doesn’t affect weapon sprites during their normal state, preventing them
from getting oddly clipped during aiming.

SOUND <string #1> <string #2> <string #3> <int>
description: Defines a sound for an entity action.
syntax: <string #1> sound loading parameter (STATIC or DYNAMIC) ; <string #2> sound event ; <string #3> sample name ;
<int> maximum allowed variation of the sound pitch (in per cents)
notes: Commonly used sounds should be defined as STATIC (loaded only once on game start-up), while level- or boss-
specific sounds should be DYNAMIC (loaded on per-level-basis when used). Only one sound can be defined per
event. Names of S_VOICEOVER1 and S_VOICEOVER2 don't refer to a sample, but to a predefined voiceover
group (see: VOICE, VOICEOVER, VOICEOVER_END).

You can make all entity's sounds global instead of positional with FX_GLOBAL_AUDIO (see: STAT). S_SONG_DIE
can be made to use music transitions (see: FX_TRANSITION in STAT), by default it instantly cuts to new song. Kill
effect frag sound can't be loaded dynamically (see: KILLFX). S_LOOP can also be played instead of standard
moving sound using stat flag FX_MOVE_LOOP (see: STAT). Non-moving, static entities won’t naturally make a
movement sound. Loop can also be used as a weapon firing sound; To achieve this, define S_LOOP for the
weapon entity of the weapon slot (see: GUNENTITY, WEAPON).

New to TAGAP 3 engine is the automated, randomised pitch alteration. In practice it simply applies random pitch
variation to the sample using the maximum range defined in the scripts. This way, say, shooting with a machine gun
sounds more lively without the need of loading multiple sounds for the weapon – the engine creates the needed
variation in real time. The pitch variation input is in per cents; Since all sound samples of TAGAP 3 are 22050 Hz,
using, say, variation '50' means the sample playback can be anything between 11025 Hz and 33075 Hz.

With loops the variation naturally works differently – you naturally can't pick a random pitch every time when a loop
is updated. For standard loops, the random variation is created for the entity and thus that entity will use the same
pitch as long as it exists. For special loops (i.e. with the aforementioned FX_MOVE_LOOP, triggers entities and
weapons) the variation defines the maximum pitch shift applied when, in example, the loop is used as a weapon
sound and the weapon stops firing, winding the sound down with a small fade-out and pitch-down.

Note that variations are stored per-action, not per-sample; You can use wide range with one sample on one entity
and deny variation altogether for the very same sample on another entity.

Also those used to do modifications for the very first TAGAP should note that there no longer is event S_IDLE, as
introduction of S_LOOP rendered it more or less useless.

Possible event references:

S_ATTACK = entity attacks
S_COUGH = coughing for air / weapon charging
S_DIE = entity dies
S_DYING = large entity falling apart just before dying
S_JUMP1 = normal jump
S_JUMP2 = double jump (see: SPECIAL_DOUBLEJUMP of STAT)
S_JUMP3 = triple jump with magnet boots (see: SPECIAL_TRIPLEJUMP of STAT)
S_LOOP = looped idle sound when entity is awake and active – or in case of weapons, firing
S_LOOP_ALT = looped idle sound when entity is knocked out by EMP (see: TAKEDAMAGE_EMP of STAT)
S_MOVE = sound of walking movement (see: BIAS of SPRITEVAR)
S_PHYSICS = physics impact sound
S_RESPAWN = resurrection effect / weapon reloading
S_SLEEP = entity deactivates
S_SONG_DIE = sound played on death (“resume” resumes level music)
S_SONG_WAKE = sound played on awakening
S_STOMP = sound played when stomping with magnet boots (see: SPECIAL_STOMP and S_AR_LEGS of STAT)
S_VOICEOVER1 = player #1 voice-over on death / item pick-up
S_VOICEOVER2 = player #2 voice-over on death / item pick-up
S_WAKE = entity activates / inventory item is used / kill effect fraggin' sound

SPRITE <string #1> <bool> <string #2> <int #1> <int #2> <string #4>
description: Defines a sprite for an entity.
syntax: <string #1> sprite loading parameter ; <bool> sprite color index ; <string #2> animation style ; <int #1> sprite x-
offset from entity origin ; <integer #2> sprite y-offset from entity origin ; <string #4> sprite name
notes: Sprite loading parameters;

[ 56 / 90 ]
SPRITE <string #1> <bool> <string #2> <int #1> <int #2> <string #4>
DYNAMIC = sprite is loaded on per-need basis when the level or sequence is loaded
DYNAMIC_MIPMAP = same as DYNAMIC, only with mipmapping allowed
STATIC = sprite is loaded once, on the game boot-up
STATIC_MIPMAP = same as STATIC, only with mipmapping allowed

If sprite is used frequently in the game, it should be set STATIC (it's loaded once). If, however, it's huge and / or part
of a boss used in only one level, make it DYNAMIC (it will be loaded only when it's used and flushed after) or use
layer for a sprite (see: SPRITEVAR). Remember, though, that the same sprite should never be loaded as both
dynamic and static, as it ultimately makes the engine confused and messes up the rendering.

New in TAGAP 3 are mipmapped sprites. In most cases, for the best, crispest graphical results, you don't want the
sprites to be mipmapped. However, there are occasions where it is preferred, like in case of vegetation fill elements
(see: trigger bush); Having these vegetation elements mipmapped can give you a significant performance boost,
even if it means smoother or blurrier sprites when camera zooms out.

As technical note, you should be aware that mipmapping isn't applied to textures unless they are within power-of-
two dimensions (32, 64, 128, 256 and so on). If the image isn't power-of-two, it will simply be loaded as non-
mipmapped one. And don't worry, single sprite can have both mipmapped and non-mipmapped frames.

Sprites with pan animation are handled like textures and must be sized “power of two” (see: TAGAP Engine
Introduction: File types) to be rendered. For more sprite handling parameters, see: SPRITEVAR. Possible colour
indexes:

0 = default
1 = fullbright
2 = always dim
3 = always bright

Possible animation flags:

ANIM_PANFORWARD(/BACK/UP/DOWN) = constant panning forward (/back/up/down)
ANIM_PANATTF (/B/U/D) = attack panning forward (/back/up/down)
ANIM_ROLLATT = attack rotation
ANIM_ROLLVEL = velocity based rotation
ANIM_WEAPON = bases the animation frame on the weapon slot used (see: WEAPON, S_WEAPON of STAT)
NONE = no animation

SPRITEVAR <int #1> <string> <int #2>
description: Sprite variable.
syntax: <int #1> index of the sprite ; <string> variable name ; <int #2> value (not used with variables marked as [toggle]).
notes: Use ACTIVE and INACTIVE only when you are dealing with on/off frames that are handled in different manner or
have different offsets. For static on/off objects, like lights etc. use FRAME_INACT instead. Negative frames (set with
value -2) are not rendered. Entity or it's weapon must have FX_RELOAD (see: STAT) set in order enable reloading
animation modifiers. If entity has been hit by EMP, the user-defined SNOWBLIND opacity is replaced for the EMP
duration. When turned on, SCISSORS will remain active until turned off or all the sprites have been rendered.

Energy effect (defined with variables ENERGY, ENERGY_FLOW and ENERGY_SPEED) renders the sprite with an
energy effect that uses the defined sprite as its alpha mask (what is transparent in the sprite will dim out the effect).
To create an energy flow without a visible sprite, simply create an image with all channels but the alpha blacked out
and then turn on the additive rendering with sprite variable HARDLIGHT.

Sprite variables can be called in both entity scripts and from within limb definition block (see: LIMB). If you want to
modify sprite variables of a limb that has already been defined (say, when using clones, see: CLONE), you can use
the new alternate version SPRITELIMBVAR.

Status variable references:

ACTIVE = rendered only when entity is active [toggle]
AIM = uses standard aiming angle for sprite angle without flipping the sprite [toggle]
AIM_FACE = same as AIM, but allows sprite flipping [toggle]
AIM_HEAD = Head movement and aiming angles [toggle]. Note that in TAGAP 3 these values refer to the head limb
(see: LIMB) instead of being calculated on per-sprite basis. Entity obviously has to have a head in order for
this variable to work.
ALIVE = only render when entity and it's user / weak points are alive (value>0) or dead (value<0)
0 = disables the alive-check (default)
1 / -1 = basic alive model, refers to group user / weak point (see: GROUP)
2 / -2 = self-referring model; Only checks if the entity itself is alive (i.e. see: AI_DEATH_DELAY of STAT)
3 / -3 = considered alive as long as the collective entities are alive (see: COLLECTIVE of GROUP)
ALPHA = set default alpha-blending multiplier (transparency in per cents, 100 being solid and 0 totally invisible)
ANGLE_RANDOM = uses entity's FX_RANDOM_ANGLE as sprite angle (see: STAT) [toggle]
ANGLEFACTOR = sprite angle multiplier in per cents (default is 100)
ANGLEOFFSET = default angle offset in degrees
ANIMATE = standard frame-by-frame animation (value is speed in per cents)
ANIMATE_FACE = eye animations (value is blink frame, use 0 for no eye animation)
ANIMATE_BIAS = uses non-default frame when bias angle isn't 0 degrees, i. e. while walking (value is the new frame)

[ 57 / 90 ]
SPRITEVAR <int #1> <string> <int #2>
ANIMATE_TO = same as ANIMATE, but stops when to the final frame (value is speed in per cents)
ARMOR = Associates the sprite with a specific piece of armour. For usage, see FRAME_ARMOR. Armour indexes are;
-1 = none (default)
0 = body armour
1 = shoulder armour
2 = hands / gauntlets
3 = boots
BIAS = waddle movement angle
BIAS_ACTIVE = defines when movement angle is used (1=when active; -1=when inactive; 0=default, always)
BIAS_AIM = variates waddle movement angles from aim angle
BIAS_CONSTANT = like FX_WADDLE_CONSTANT (see: STAT), but calculated on per-sprite basis (value is speed)
BIAS_MOVE_X (/Y) = move sprite according to bias angle
BIAS_MOVE_YB = enables bouncy y-wise movement (as opposed to default linear vertical movement) [toggle]
BIAS_OFFS_X (/Y) = additional offsets that are affected by the bias angle
BIAS_NEG = multiplier for negative bias angle (in per cents)
BOB = up ‘n down walk movement
BOOSTMOD = takes alpha strength from player triple-jump/gravity-stomp boosts (player only) [toggle]
CHAINGUN = multiplies the sprite by defined amount and simulates chaingun rotation (value is amount of barrels, up to
8); use negative value for inverted rotation direction.
CHAINGUN_SPLITS = alters chaingun rendering to draw only one layer of sprites;
0 = off (default, renders both layers)
1 = front layer
2 = back layer
same as CHAINGUN, except splits the sprites into two layers; positive values are the in-front sprites, while negative
value renders the in-back sprites.
CHAINSAW = Renders the image as a rotating fill tool, like a chainsaw or tank tracks. Use value 0 to disable (default), 1
to render as simple chainsaw or use custom size to create dual-sided tank-track type render. The chainsaw
sprite relies on sprite pan for movement and fill size (FILL_H, FILL_W) for dimensions.
CHARGE = weapon charge animation [toggle]
CHARGE_INV = weapon re-charge animation [toggle]
COIN = turns sprite into spinning flat object (by default uses BIAS_CONSTANT for rotation)
0 = off (default)
1 = horizontal spin
2 = vertical spin
COIN_FACTOR = multiplier for coin effect (in per cents)
COIN_HIDE = makes coin effect to use hiding instead (value is hiding-to-coin-effect ratio, in per cents)
DIM = dimming transparency [toggle]
EMP = being knocked out by EMP equals being inactive (1 uses EMP only, 2 uses both EMP and entity's activity state)
EMP_ACTION = action when knocked out by EMP (value is action modifier, action is set by behaviour, i. e. bias or aim)
ENERGY = toggles on defines the energy texture (use -1 to toggle previously defined energy effect off)
ENERGY_FLOW = defines the direction of the energy (0 = up, 1 = down, 2 = forward, 3 = backwards)
ENERGY_LOCAL = turns energy flow from global to local [toggle]
ENERGY_SPEED = speed of the energy (in per cents, default is 50)
FACE = flip sprite according to specified boolean face (doesn't flip offset coordinates)
FACE_RANDOM = uses entity's FX_RANDOM_FACE as sprite face (see: STAT) [toggle]
FADE = fades the sprite out or in (1 means fade out, -1 is fade in)
FADE_CHARGE = fades the sprite out or in after firing (1 means fade out, -1 is fade in)
FADE_HEALTH = fades according to the entity's health level or ammo life (1 means fade out, -1 is fade in)
FADE_TOGGLE = fades the sprite upon toggling on/off (value is fade time in milliseconds, negative value is fade in)
FADE_ZOOM = a modifier for fading the sprite out when the camera zooms in
FADE_X (/Y) = transforms fade effect into movement by x-y coordinates (value is the movement in pixels)
FILL_DRILL = sprite fill is rendered as a drum squashed from the other end by the designed value (in per cents)
FILL_DRUM = sprite fill is rendered as round drum instead of flat fill [toggle]
FILL_H (/W) = sprite fill tool height and width (no dimension uses frame dimension defaults)
FLICKER = flickering transparency [toggle]
FRAME = default frame to use (value -1 disables previously defined FRAME)
FRAME_ARMOR = if the sprite is associated with an armour element (see ARMOR above), this variable is used as the
frame when the entity possesses that piece of armour. If no FRAME_ARMOR is defined, the sprite simply
wont be rendered if the entity doesn't have that armour.
FRAME_ASSIST = uses specified frame while assistance (the summoning) is unavailable
FRAME_ATTACH = For limb sprites (see: LIMB), defines the frame to be used when the current limb is 'attached' (which
means following its in-engine program, like hand holding a weapon). Just set the frame to be used here, use
-2 to disable the sprite or -1 to disable the FRAME_ATTACH (default).
FRAME_FACE = frame offset that is applied when sprite is flipped (note that the frame is still flipped)
FRAME_GREN = frame used when entity is throwing a grenade (use -2 to disable sprite completely)
FRAME_HAND2 = frame used when entity's grip hand (see: HAND2 of LIMB) is not attached to the weapon; to disable
the sprite, use negative value -2 – or disable the FRAME_HAND2 with value -1
FRAME_INACT = frame used when entity is in-active
FRAME_RANDOM = uses FX_RANDOM_FRAME as frame offset (value defines the storage slot used) (see: OFFSET)
HARDLIGHT = use additive rendering (used i.e. lights, sparks and glows) [toggle]
HIDE_AMMO = For use with weapon entities (see: GUNENTITY), hide obeys the amount of ammo in the weapon, i.e.
when the ammunition goes below the amount defined here, the sprite starts to move. This can be applied to
to all HIDE_* variables and ANIMATE_TO. The value defined tells the sprite how much ammo the current
weapon must have for the sprite to be rendered as 'fully active'.
HIDE_AMMO_MIN = To be used with HIDE_AMMO, this variable defines the ammunition value when the sprite is
rendered as fully inactive.
HIDE_BLINK = uses entity eye blinking animation (toggled by ANIMATE_FACE) for hiding instead of entity activation
HIDE_DELAY = delays the hide animation by defined time (negative value applies delays when shutting down)
HIDE_MOVE_X (/Y) = sprite moves defined amount upon activation
HIDE_ROLL = hide rotation animation (angle of rotation in degrees)
HIDE_SCALE = hide animation re-scale in per cents (can be used in tandem with sprite variable SCALE)
HIDE_TIME = amount of milliseconds it takes to perform the “hide” animation (default is 200 milliseconds)
INACTIVE = rendered only when entity is inactive [toggle]
INVERTFACE = draws sprite using inverted face [toggle]

[ 58 / 90 ]
SPRITEVAR <int #1> <string> <int #2>
KICK_ACCURATE = per-shot re-coil calculation toggle [toggle]
KICK_ROLL = recoil rotates sprite by defined angle
KICK_X (/Y) = recoil moves sprite by defined amount
LAYER= use defined image layer instead of sprite graphics (see: LAYER)
LIGHT_OFFSET = apply the sprite offset and angle variations to light position as well [toggle]
LIMB = The segment of the limb the sprite will be rendered as (for use with limbs only, see: LIMB)
LIMB_ANGLE = Define the limb segment that is used for the rendering angle (if not same defined by the above spritevar
LIMB; For use with limbs only, see: LIMB)
NOAMMO = sprite is disabled when the current weapon is out of ammo [toggle]
NOFACE = ignores sprite face (also affects offset coordinates) [toggle]
NOSHADER = disable use of entity shader effects for this sprite (extermination, pain, freeze, etc.) [toggle]
PAN_FACTOR = integer multiplier for the sprite panning
PAN_TERM = replaces default pan with terminal line swap movement (value is length of the movement in 1/1000 scale)
PAN_VEL = replaces default pan values with velocity (value works as a multiplier)
PULSE = pulse animation, value works as speed modifier (for hearts, speakers, etc.)
PULSE_SCALE = custom scale for the pulse scale shift (in per cents)
OFFS_X (/Y) = offsets to alter the sprite frame origin for rotation
OFFSET_HAND1 = sprite movement affects the hand holding handle (in skeletal animation)
OFFSET_HAND2 = sprite movement affects the hand holding the front grip (in skeletal animation)
RANGE_FILL_W (/H) = width (or height) is defined by entity's range element (value is added to the width/height)
RANGE_OFFS_X (/Y) = sprite frame origin offset based on entity's range element (value is added to the width/height)
RANGE_OFFS_FACT = multiplier that tells the engine at which ratio should the entity's range element be used when
altering the sprite offset with RANGE_OFFS_X(/Y) (defaults at 0.5, meaning half the range)
REFLECTION = sprite reflection texture (use -1 to turn pre-existing reflection off; default is off)
RELOAD_ROLL = reload animation angle modifier (angles 360 and -360 will spin during the entire reloading)
RELOAD_STYLE = alternate style of reload animation;
0 = pumping motion (default)
1 = snaps to reload position on firing instead of traditional post-firing reload
RELOAD_X (/Y) = weapon reloading moves sprite by defined amount
RELOCATE_X (/Y) = redefines the sprite location (very useful when cloning entities, see: CLONE)
ROLL = simplistic roll animation
ROLL_GRENADE = grenade throwing rotation [toggle]
SCALE = sprite scale in per cents (default is 100)
SCISSORS = toggles per-sprite scissors (1 turns scissors on, -1 turns them off) (see: SCISSORS)
SNOWBLIND = draws white noise instead of the sprite (value is the default opacity in per cents).
STANDIN = Sprite acts as a stand-in for a group entity (the value is the index of the group object (see: GROUP), i.e. first
group entity is index 0). This also affects other sprite variables, like ALIVE (see above). Note that using stand-
in sprites is slightly more taxing than using stand-in objects (see: OBJECT), so it is recommended to use
these only on boss entities.
USEGROUND = adds ground angle to sprite rendering angle [toggle]
WEAPONMOD = uses entity's firing/not-firing variable to handle all HIDE_* and FADE sprite operations [toggle]

STAT <string> <int>
description: The common way of defining a value for an entity.
syntax: <string> status variable name ; <int> value (not used with variables marked as [toggle]).
notes: Group user (see: GROUP) can have negative value for AI_DEATH_DELAY; This means the group user dies away
instantly, but value delays the death of the group entity. For example, when tank driver is killed, the tank doesn't
blow up immediately, but after a short while.

Status variable references:

AI_ACID = makes entity an acid trip hallucination [toggle]
AI_ACTIVE_MODIFIER = modifier for how entity toggles on / off visually
1/-1 = collective presence
2/-2 = performing a special move (SPECIAL_SLIDE, SPECIAL_DOUBLEJUMP, etc.)
3/-3 = stopped on attacking (see: AI_STOP_ON_FIRING)
4/-4 = attacking
5/-5 = refers to group owner state instead
6/-6 = active when active modifier is larger than 0.5 (works like WEAPONMOD of SPRITEVAR)
7/-7 = active when the main entity is active (for use with sub-entities, see: OBJECT)
8/-8 = active when the player is in Overdose
AI_AIM_INDEPENDENT = friendly AI aiming for player-created aiming entities and allies (see AI_ALLY below)
0 = off (default)
1 = attack closest to self
2 = attack closest to player
3 = attack closest to self, but only acquire the target once
AI_AIM_OWNER = keeps aiming at owner instead of player [toggle]
AI_AIM_TILT = aiming tilts from AI_KEEPANGLE to AI_AIM_TILT (or the other way around)
AI_AIM_VELOCITY = entity aim equals it's velocity [toggle]
AI_AIRBREAK = improves the aerial control of flying enemies (faster acceleration and deceleration)
AI_AKIMBO = makes the weapon dual-wielded (for weapons, see: WEAPON); the value is the x-offset for the off-hand
weapon (from the origin of the main weapon)
AI_ALLY = turns the entity into a friendly NPC fighting alongside the players; to be used in tandem with
AI_AIM_INDEPENDENT (see above) [toggle]
AI_AMMO_ALL = spends all remaining ammo [toggle]
AI_AMMO_PICKUP = can be picked up by pressing [Use], thus adding it's AMMOLIFE to defined weapon slot
AI_AMMO_SPEND = defines how many rounds of ammo the weapon will spend (default is 1)
AI_AMMOLIFE = ammo equals life; When AI_AMMO_PICKUP isn't set, amount is set with AMMO 1 [toggle]
AI_ANTIFREEZE = on enemies, prevents it from freezing when attacked with cryo-attacks (see AI_FREEZE) ; on items

[ 59 / 90 ]
STAT <string> <int>
(see: ITEM, WEAPONITEMS), prevents the the item from spawning if the entity is frozen [toggle]
AI_ASSIST = defines the entity as reinforcements and adds it to the reinforcements list [toggle]
AI_BOSS = defines the entity a boss (boss gauge requires an icon, see: ICON) [toggle]
AI_BOUNCE_COUNT = number of times a bouncy entity can bounce off surfaces before being rendered null (0=infinite)
AI_BURST = amount of rounds to be fired in a burst
AI_BURST_CHARGE = each shot of the burst is charged separately, unlike by default [toggle]
AI_BURST_TIME = time between bursts (in milliseconds)
AI_COLLECTIVE = by default all entities refer to themselves for rendering, but with this value, you can make
AI_CONSTANT group members (see: THINK, GROUP) refer the group owner for main rendering values (like
angles) [toggle]
AI_CONTINUOUS = continuous physics check for fast projectiles (CPU-taxing, don't use on other objects) [toggle]
AI_COPY_PLAYER_GUN = always uses same weapon as player [toggle]
AI_DARKNESS_ACTIVE = when set, entity is active only when theme darkness is equal or less than this value
AI_DISABLE_KILL = group user (GROUP); doesn't tag group dead after being killed (for ALIVE of SPRITEVAR) [toggle]
AI_DISTANCE_MAX = maximum distance entity allows before moving closer (can't be less than minimum distance)
AI_DISTANCE_MIN = minimum distance the entity tries to maintain (no value means attempted collision)
AI_DISTANCE_OWNER = default y-wise distance between drone / member and owner
AI_DISTANCE_RANGE = by default, enemies of TAGAP3 have permission to attack if they can be seen, but this variable
makes them do the classic TAGAP style range test as well, meaning player has to get a little closer before the
enemy attacks [toggle]
AI_DEATH_DELAY = entity doesn't instantly blow up on dying, but lingers for defined time
AI_DEATHJUMP = Super Mario styled dying jump [toggle]
AI_DEATHJUMP_NULL = makes entity perform death jump instead of dying when it expires [toggle]
AI_DISTANCE_MAX / MIN = preferred distance to player the entity tries to maintain
AI_DRONE = entity is defined as player-owned drone [toggle]
AI_DROP_OBJECTS = releases objects upon death or transformation; possible variables are;
0 = off (default)
1 = releases objects on death (entities are primary items of used objects, see: ITEM)
2 = releases objects on death AND transformation (see: TRANSFORM)
3 = drops weapons also on transformation
AI_ENDING = end-level-on-death [toggle]
AI_FINALE = final boss death effects [toggle]
AI_FIRE_ON_ACTIVE = performs an attack on activation [toggle]
AI_FODDER_OPTION = adds the entity to optional cannon fodder list (1=tool; 2=powertool) (see: CANNONFODDER)
AI_FREEZE = attack modifier, freezes entities and objects on impacts (see: Weapon scripting for details) [toggle]
AI_GHOST = entity will use ghost triggers (see: Using Triggers: ghost, TRIGGER); The value is the id that must match
the id value of the trigger field.
AI_GRENADE_TIME = changes MISSILE to grenade and defines the AI interval between throws (in milliseconds)
AI_HIDE = enables hide AI with visibility (time in milliseconds)
AI_HIDE_ANIM = hide movement time (FX_HIDE_MOVE, FX_FULLANGLE_HIDE) (in milliseconds)
AI_HIDE_TIME = hide AI hiding time (in milliseconds)
AI_HOVER = Entity maintains a defined hovering distance between itself and the ground (positive values) or from the
ceiling (negative values), where the value is the hovering distance in pixels. Hovering requires the entity to be
defined as flying (see: FLY of MOVETYPE)
AI_IGNORE_COLLISION = ignores collisions for defined period of time from spawning, value being the time in
milliseconds. Using positive value ignores everything (linedefs and entities), while using a negative value
ignores just linedefs.
AI_IGNORE_ONEUPS = kills the opponent regardless of any one-ups it may have [toggle]
AI_IGNORE_VELOCITY = ignores world velocity (see: VELOCITY) [toggle]
AI_INHERIT_ANGLE = for spawned entities, makes them always user owner's angles [toggle]
AI_INHERIT_FACE = for spawned entities, makes them always use owner's facing [toggle]
AI_INHERIT_OFFSET = inherit full-angle offset and hide from the spawning entity – or, in case of objects (see: OBJECT)
this will copy the object owner's 'fullmodel angle' into the object's aiming angle
AI_INHERIT_STATS = for spawned entities, inherits randomized stats (like armours) [toggle]
AI_INHERIT_TIMERS = for spawned entities, inherits most of the animation related timers [toggle]
AI_INHERT_TRIGGER = for spawning entities;, inherits automatically generated triggers (see: AUTOTRIGGER)
AI_INHERIT_VELOCITY = for spawned entities, inherits the velocity of it's owner [toggle]
AI_INVULACTIVE = invulnerable according active state (1=invulnerable when inactive; 2=invulnerable when active)
AI_INWATER = inserts special AI behaviours related to water
0 = default behaviour
1 = entity stays inside water area
2 = entity is destroyed if it enters water
AI_ITEM_ANGLE = when entity is dropped as an item (see: ITEM), this overrides the engine default throwing angle
AI_ITEM_RANDOMIZER = item entity randomiser value (applies only to the firsts item, see: ITEM)
AI_JUMP = bouncing AI behaviour (value defines the vertical velocity of the jump)
AI_KEEPANGLE = sets constant, user-defined angle (can be used in tandem with entity group settings, see: GROUP)
AI_KEEPANGLE_DISABLE = disables AI_KEEPANGLE [toggle]
AI_KEEPACTIVE = keeps active, ignoring engine deactivation and no-aim [toggle]
AI_KEEPACTIVE_FODDER = toggles AI_KEEPACTIVE if the entity is spawned as cannon fodder [toggle]
AI_KEEPFACE = keeps own or group leader’s face when aiming [toggle]
AI_KEEPFIRING = entity keeps firing, no matter what happens (AI_ZOMBIE only, see: THINK) [toggle]
AI_KILLSWITCH = kills entity away on triggering [toggle]
AI_LINE = use line collision detection instead of default rectangle [toggle]
AI_LINEOFSIGHT = checks line-of-sight for level geometry before firing [toggle]
AI_LIMIT_ANGLE = limits aiming angle
AI_LIST_ALIAS = show entity in non-default entity list (1=actor, 2=item, 3=decoration ; 5=missile)
AI_LOCK_ON_FIRING = stops aiming while attacking [toggle]
AI_MAGNETIZE = magnetises entity or user for defined period of milliseconds
AI_NOBLOW = opposite of AI_NOBOUNCE, this disables blowing up upon contact with solid surfaces [toggle]
AI_NOBOUNCE = makes falling missiles to blow on contact instead of bouncing (see: MOVETYPE) [toggle]
AI_NONBLOCKING = makes entity impact with non-blocking linedefs (see: FLOOR, LINEDEF) [toggle]
AI_NOT_IN_DEMO = removes the entity when entering in-game demo camera (see: Using triggers: focus) [toggle]
AI_NUMB = stays numb on activation (value is numbness time in milliseconds)
AI_NUMB_WAKE = initiates AI_NUMB always when the entity is woken up via AI routines [toggle]

[ 60 / 90 ]
STAT <string> <int>
AI_PEDESTRIAN = pedestrian fodder, player will damage the entity on contact [toggle]
AI_PHYS_IGNORE = ignore default physics manipulation (i.e. water movement, magnetism) [toggle]
AI_PHYS_VEHICLE = ground-based vehicle physics (i.e. motorcycle) [toggle]
AI_PLAYER_TWO = defines entity character for second player character (AI_USER only, see: THINK) [toggle]
AI_PURSUIT = accelerates towards locked-on target while firing (when used by enemies and projectiles) [toggle]
AI_PUSH = attack variable, creates pushing wave from entity origin [toggle]
AI_RAILS = locks entity on rail, capping y-axis movement (for capping x-axis, see: Using Triggers: area) [toggle]
AI_RANDOM_SPEED = walking / flying speed randomiser (in movement units times 100)
AI_RANDOM_TEMPTIME = maximum of random time added to TEMPMISSILE time (in milliseconds)
AI_RANDOM_TRANSFORM = transformation target entity randomiser value (see: TRANSFORM)
AI_RANDOM_TRANSTIME = transformation time randomiser, in milliseconds (see: TRANSFORM)
AI_RANGE = pattern movement definition / range of trace attack (for further pattern creation, see: Using Triggers: area)
AI_RANGE_OWNER = projectile inherits attack range from it's owner [toggle]
AI_RANGE_VERTICAL = makes flying entities obey the trigger areas vertically as well [toggle]
AI_REALTIME = forces some cyclic effects (pan, light dim, etc.) to use real time instead of game time [toggle]
AI_RELOAD = turns weapon missile into a reloading command [toggle]
AI_REPEL = makes zombies turn away from the entity on collision [toggle]
AI_REQUIRE_IMPACT = modifies the ways the entity spawns items on death; for use with projectiles only*
0 = standard actions (drops items and shoots missiles on death; default)
1 = spawn items only on impact
2 = do not launch missiles (see: MISSILE) if the object struck something
AI_SCRAP = defines entity as piece of scrap metal (see: SCRAP of OFFSET) [toggle]
AI_SECURITY = makes the entity part of the security system needed to destroy in order to activate the security trigger
(see: Using Triggers: security) [toggle]
AI_SIZE_IMPACT = volume of the object (affects falling effects and alike.; default is 0)
AI_SIZE_MOVE = mass modifier (affects damage knock back and alike ; default is 0)
AI_SLAVE = Enslaves AI_CONSTANT entity to follow the owner – usually the entity that created this one – as if it was a
member of a group (see: GROUP, THINK).
AI_SPAWN_HORIZON = when entity is spawned as cannon fodder, this value is used as y-offset from parallax guide
AI_SPAWN_LIMIT = maximum amount of entities allowed to be spawned by the current entity
AI_SPAWNER_FX = spawn triggers (spawner, manhole, etc.) can toggle the entity for effects if in vicinity [toggle]
AI_SPINAIM = spins aiming angle and keeps firing
0 = off (default)
1 = spin aim angle 360 degrees and keep firing, instant stop
2 = spin aim angle 360 degrees, keep firing, slows down to halt
AI_SPREAD = spread of attack projectiles (value is the spread angle in degrees)
AI_STANDIN = makes entity act as player standing during sequences (1=player one ; 2=player two)
AI_START_VELOCITY = starting velocity multiplier (in per cents); applied to entity when it is created / spawned
AI_STOP_ON_FIRING = entity stops upon firing for defined period of milliseconds
AI_SUMMON = summons level reinforcements upon dying [toggle]
AI_TEMP_ON_ACTIVE = initiates the missile temporary life span on activation [toggle]
AI_TRANSFORM_ADAPTIVE = delays transformations to adapt to attacks and scripting (see: TRANSFORM)
0 = off (default)
1 = doesn't transform if an attack is in progress
2 = transforms only if the entity has locked onto the target
3 = transforms only if the entity is directly above a player
AI_TRANSFORM_VARIETY = makes sure transformation randomiser (STAT AI_RANDOM_TRANSFORM) provides
variety on every call, preventing random clusters [toggle]
AI_TRIGGER = trigger link override (this is NON-DYNAMIC; if possible, use dynamic entity linking within editor instead)
AI_TRIGGER_DISABLE = disable on-death trigger function if entity runs out of one-ups
AI_VITAL_POINT = vital point for groups (see: GROUP); If all vital parts are killed, rest of the group dies [toggle]
AI_WEAKFIRST = weak point (see: WEAKPOINT) is attack impact priority instead of main entity [toggle]
AI_WEAPON_COUNTER = makes weapon use timer instead of ammo (value is re-charging time in milliseconds)
AI_WEAPON_NOFLIP = designed for player only, prevents weapons from being flipped [toggle]
AI_WEAPON_RESET = weapon animation / burst are reset on transformation (see: TRANSFORM) [toggle]

CHARGE = weapon charging time (in milliseconds)

DAMAGE = amount of direct damage inflicted when attacking
DAMAGE_DIRECT = entity can only be damaged by direct attacks; splash damage (DAMAGE_SPLASH) still hurts the
entity, but not through walls or platforms. Note that with trigger-bound entities (see: guide, table) using this
stat turns the entity invulnerable to everything but explosions [toggle]
DAMAGE_EMP = electromagnetic damage that knocks electric entities out for defined duration (in milliseconds)
DAMAGE_LEECH = leeches health of electric enemies as ammo for the related weapon (player only) [toggle]
DAMAGE_NANO = controls nanite damage attributes;
0 = off (default)
1 = deals extra damage to nano-objects and shuts down nanowalls
2 = repairs nano-objects and reconstructs nanowalls
DAMAGE_NOT_BOSS = doesn't damage boss characters (see: above stat AI_BOSS) [toggle]
DAMAGE_NOT_PLAYER = doesn't damage player characters [toggle]
DAMAGE_ORGANIC = attack damage is inflicted only to bleeding objects [toggle]
DAMAGE_OWNER = makes player missiles damage player also [toggle]
DAMAGE_SHIELD = percent of damage entity takes when attacked (default is 100)
DAMAGE_SHOCK = shows damage as electric shock [toggle]
DAMAGE_SONIC = sonic damage (only dis-orients organics by defined amount of milliseconds, deals double damage to
electronics, insta-gibs fragile)
DAMAGE_SPLASH = Explosion damage blast radius, which can be used without inflicting damage. Using negative blast
radius prevents the splash from causing collateral damage.

FRAG = destroying this entity will count in killing combos
0 = doesn't count as a frag (default)
1 = counts as a frag for combos, stats and AI routines
2 = counts as a frag for stats and AI routines, but not for stats
3 = counts as a frag for AI routines only (doesn't add to stats or combo)

[ 61 / 90 ]
STAT <string> <int>

FX_360 = emits halo-ripples from the entity [toggle]
FX_APPEAR = makes the entity to automatically fade and dim in when being spawned [toggle]
FX_BAZOOKA = back blast smoke on firing, value is the angle of the puff (uses W_OFFS_CASING, see: OFFSET)
FX_BEAM_EFFECT = change beam effect style s(standard light beam is the default 0)
0 = light beam
1 = electric arc
2 = plasma (with both ends crackling with electricity)
3 = plasma (without end electricity)
4 = simplified constant plasma (i.e. pulse gun shot vanishing)
5 = weapon theremin sound waves
6 = constant theremin sound waves
7 = x-ray beam (i.e. Exterminator)
8 = dynamically processed leeching beam
9 = constant leeching beam
10 = constant electricity
FX_BLINK = entity blinks on/off when it's rendered as a trigger [toggle]
FX_BREATHE = makes entity breathing, creating effects when necessary (under water, cold, space, etc.)
0 = no breathing (default)
1 = normal breathing calculated from the head limb origin (see: LIMB)
2 = non-head breathing, offsets calculated from entity origin
FX_BULLET = makes trace attack to be drawn as bullet (not fully supported by impaling attacks) [toggle]
FX_CASING = shell casing type
FX_CHARGE = enables weapon charging glow [toggle]
FX_CHARGE_RECOIL = animates the weapon on charge state in addition to firing [toggle]
FX_DIM = makes the entity light and effects dim in a cycle based on the entity's position; positive and negative values
alter the cyclic speed and direction of the effect cycle
FX_DIM_COLOR = sets entity's colour layer as dim or bright:
-1 = use default
0 = always bright
1 = always dim
FX_DIM_HIDE = entity fades to/from black (value is time in milliseconds; <0=fade in; >0=fade out; 1=stay black; 0=off)
FX_DIM_LITCOLOR = forces entity lights (see: LIGHT, FLASHLIGHT) to obey FX_DIM_COLOR rules (see above)
FX_DISABLE = disables particle and flash effects [toggle]
FX_DROPDEBRIS = drops the death debris instead of throwing [toggle]
FX_ELECTRIC = electricity effect [toggle]
FX_ELECTRIC_LIT = electricity effect bound to light size and colour [toggle]
FX_EXPAND = expands entity towards removal (i.e. flame) [toggle]
FX_EXTERMINATE = adds Exterminator effect to the weapon attack, used with kill effects (see: KILLFX) [toggle]
FX_FADE = fades entity to nothing instead of standard effects [toggle]
FX_FIRE = particle fire trail (value is the size of the particle in per cents)
FX_FIRE_EXACT = particle plasma fire fire trail (value is the size of the particle in per cents)
FX_FIRE_TRAIL = alternate version of FX_FIRE, with sparks (value is the size of the particle in per cents)
FX_FLICKER = flickering light effect [toggle]
FX_FLOAT = adds y-wise floating;
0 = off (default)
1 = normal (obeys entity's activity rules for turning the effect on/off)
2 = always on (normal effect that is always on, regardless of entity's activity rules)
3 = independent from group owner (see: GROUP)
FX_FROZEN = entity is permanently frozen (cannot melt) [toggle]
FX_FULLANGLE_AIM = angle is aim angle (requires FX_FULLMODEL) [toggle]
FX_FULLANGLE_AIMFACE = angle is aim converted from faced weapon aim (requires FX_FULLMODEL) [toggle]
FX_FULLANGLE_BIAS = adds waddle movement to the angle (value is multiplier in per cents)
FX_FULLANGLE_BIASCONST = forces FULLANGLE_BIAS to use fixed waddle instead of entity's waddle movement
FX_FULLANGLE_GROUND = angle is ground alignment (requires FX_FULLMODEL) [toggle]
FX_FULLANGLE_FACTOR = full angle multiplier in per cents (similar to ANGLEFACTOR of SPRITEVAR)
FX_FULLANGLE_HIDE = adds hide-style angle similar to sprite handling (see: HIDE_ROLL of SPRITEVAR)
FX_FULLANGLE_IGNORE = ignores all custom full-angles, useful for objects (see: OBJECT) [toggle]
FX_FULLANGLE_INHERIT = inherit the full-angles of the main entity, useful for objects (see: OBJECT) [toggle]
FX_FULLANGLE_OFFSET = full angle offset
FX_FULLANGLE_RANDOM = applies random angle (see: FX_RANDOM_ANGLE) to the fullmode angle [toggle]
FX_FULLANGLE_ROLL = full angle is constantly rotating (requires FX_FULLMODEL, value is the speed in per cents)
FX_FULLANGLE_TILT = tilts the entire model according to velocities (value is tilt angle, requires FX_FULLMODEL)
FX_FULLANGLE_TILTVEL = modifies tilt angle so that entity faces the direction its moving [toggle]
FX_FULLANGLE_VEL = angle is velocity roll (requires FX_FULLMODEL) [toggle]
FX_FULLMODEL = entire entity is rendered as one object (i. e. weapon sprite) [toggle]
FX_FULLMODEL_KICK = whole fullmodel object reacts to attack kick (value is kick strength in pixels)
FX_FULLMODEL_WEAPON = The fullmodel is cloned from the weapon (see: WEAPON) – or in case of objects, the
owner's weapon. By default this only affects the angle of the, but with objects using a negative value this
affects the object's position as well. Time of the movement can be altered with AI_HIDE_ANIM. Inputs are as
follows;
0 = off, default
1 = offsets fade in based on entity's activation
2 = offsets fade out base on entity's activation
3 = offsets are always at max, no fade
FX_FULLOFFSET = y-wise offset of full model entity (requires FX_FULLMODEL)
FX_GLOBAL_AUDIO = makes all entity sounds audible everywhere [toggle]
FX_GLITTER = glitter glitter [toggle]
FX_GRENADE_ANGLE = angle of weapon when throwing a grenade (set for primary projectile)
FX_GROUNDFIX = amount pixels used to fix entity position y-wise while placed on sloped surfaces
FX_HEAD_ANGLE = how much entity head follows the actual aiming angle, in per cents (default = 33)
FX_IDLEBOB = amount of idle bobbing to simulate taking a breather
FX_IDLEDISTANCE = audibility distance of idle and/or loop sounds in per cents (default is 40)
FX_KEEP_ANIMATING = keeps limbs animating even when entity is inactive [toggle]

[ 62 / 90 ]
STAT <string> <int>
FX_KEEP_EFFECTS = render effects even when entity is inactive [toggle]
FX_KEEP_PAN = keep sprite pan animation going even when entity is inactive [toggle]
FX_LEAVES = drops leaves (value is the type of leaves, -1 = off)
FX_LIGHT_FADE = fades lights on / off instead of pulse toggle (0=off; 1=on; -1=inverted fade)
FX_LIGHT_LIGHTNING = last entity light becomes custom bloom effect when the environment flashes [toggle]
FX_LIGHT_ON_OFF = makes second entity light appear as first light when entity is inactive [toggle]
FX_LIGHT_OFFSET = forces entity functions to use light offsets (see: LIGHT_OFFSET of SPRITEVAR) [toggle]
FX_MAGNETIC = make the entity magnetized by default; this makes the entity generate the magnetic effects usually
associated with AI_MAGNETIZE, while also disabling the said AI_MAGNETIZE from having an effect [toggle]
FX_MOVE_LOOP = S_LOOP (see: SOUND) is used as movement sound, variables are;
0 = off, loop isn't related to movement at all(default)
1 = aiming movement; sound is emitted only when entity shifts aim
2 = standard movement; if entity moves, it emits a sound
3 = constant movement sound; sound can be heard even when entity is stopped, but as low pitched
FX_MOVE_ROLL = Speed modifier for rolling movement based on entity's velocity (see: FX_FULLANGLE_VEL,
ANIM_ROLLVEL of SPRITE). The value is in per cents and defaults to 100.
FX_MULTITORCH = multiplies the flashlight effect
FX_MUZZLE_FREEZE = frost steam post-firing muzzle effect effect (value is time in milliseconds)
FX_MUZZLE_ELECTRIC = electric sizzle post-firing muzzle effect (value is time in milliseconds)
FX_MUZZLE_POWDER = smoke and sparks post-firing muzzle effect effect (value is time in milliseconds)
FX_NANITES = entity sheds nanite debris as it goes [toggle]
FX_NOENV_FX = disables environmental effects light glare and rain [toggle]
FX_NOFACE = ignores facing changes [toggle]
FX_NOSOUND = disables automatic (non-user-defined) sounds [toggle]
FX_OBJECTS_TO_FRONT = bring all front objects to overlay layer (see: OBJECT) [toggle]
FX_OFFHAND = For mêlée entities (see: AI_MELEE of THINK); makes the entity use the off-hand for mêlée attacks (the
and that doesn't hold an object) (see: HOLDOBJECT of OBJECT). If this is used in connection with a weapon
entity (see: WEAPON), enabling this prevents from the entity's hands (see: LIMB, FRAME_ATTACH of
SPRITEVAR) from attaching to the weapon [toggle]
FX_PAIN = generates particle effects only when taking or waddling by damage (see TAKEDAMAGE_WADDLE) [toggle]
FX_PANSCENE = uses constant velocity for screen panning (see: VELOCITY) [toggle]
FX_PANSPEED = sprite panning speed for entity (in per cents from default)
FX_PIXELS = entity generates pixels based on the entity's colours (see: COLOR) [toggle]
FX_PLASMA = spawns sparks referring to entity light colour and offsets [toggle]
FX_PLASMA_ANGLE = default angle of plasma trail (if no angle is set, aim angle of entity is used instead)
FX_PLASMA_LENGTH = plasma trail length (if none is defined, speed of the entity is used instead)
FX_PLASMA_TRAIL = plasma trail set up according to entity lights (see: LIGHT, value defines the texture of the trail)
0 = electricity
1 = plasma effect
2 = fading sound wave
3 = solid sound wave
4 = x-ray
FX_POSE_ATTACK = uses the pose (see: POSESET) of weapon's hand-held entity (see: WEAPON, GUNENTITY) as
an attack stance [toggle]
FX_POWERUP_SIZE = defines the size of power-up effects (default is collision sphere size)
FX_PUSHUP = recoil pushes weapon upwards when firing [toggle]
FX_RANDOM_ANGLE = creates a random angle for the entity (for use, see ANGLE_RANDOM of SPRITEVAR or
FX_FULLANGLE_RANDOM above, or FX_RANDOM_WADDLE below)
FX_RANDOM_BLEEDVARS = bleed randomised values to entity based triggers the entity is inside of [toggle]
FX_RANDOM_FACE = creates a random sprite flag for the entity (for use, see FACE_RANDOM of SPRITEVAR) [toggle]
FX_RANDOM_FULLANGLE = random angle added to entities tagged as FX_FULLMODEL
FX_RANDOM_POSE = randomises the order of pose frames in a pose animation (see: POSEANIM)
0 = off (default)
1 = randomise only the starting point (rest of the animation plays in linear fashion)
2 = pick every frame on random
FX_RANDOM_WADDLE = use FX_RANDOM_ANGLE to randomise bias movement (toggle)
FX_RELOAD = enables weapon cocking animation (works only with weapon slots, see: WEAPON) [toggle]
FX_RELOAD_BURST = forces weapon cocking animation to play out only at the end of burst [toggle]
FX_RENDERFIRST = renders the entity before actual, sorted entity list [toggle]
FX_RENDERPOST = renders the entity in post processing, over the entire scene (sequences only) [toggle]
FX_SCISSORS = enables leader-based scissors in case of entity groups (see: COLLECTIVE, GROUP) [toggle]
FX_SHOWER = shoots out liquid particles to aiming direction (value is stream size in per cents)
FX_SHOWER_COLOR = defines the colour of FX_SHOWER particles (values -1 to 6)
-1 = blood
0 = clear water (default)
1 = brown, muddy water
2 = radioactive slime
3 = purple clone embryo liquid
4 = lava
5 = cryogenic nitrogen
6 = poison
FX_SMOKE_ALPHA = maximum smoke alpha transparency (in per cents, default is 100)
FX_SMOKE_ANGLE = override angle for FX_SHOWER, FX_SMOKE_SHOOT, FX_STEAM and FX_WATER_BUBBLE
FX_SMOKE_FLOOR = particle smoke from ground when moving (value is smoke size in per cents)
FX_SMOKE_SHOOT = shoots out smoke to aiming direction (value is smoke size in per cents)
FX_SMOKE_SPEED = smoke puff / water bubble velocity modifier (in per cents from the default size-based velocity);
Using a negative value creates a suction-type effect
FX_SOAP = entity emits soap bubbles as it goes about [toggle]
FX_SOUND_DIM = Makes the sound loop (see: S_LOOP of SOUND) obey the positional effect dimming (see: FX_DIM
above) [toggle]. Rules are as follows;
0 = off (default)
1 = uses entity's own dimming only
2 = uses only the dimming of the entity's objects (see: OBJECT)
3 = uses combination of both the entity's own dim and those of the objects

[ 63 / 90 ]
STAT <string> <int>
FX_SOUND_ON_FIRST = plays attack sound only on the first round of a burst [toggle]
FX_SOUND_PITCH_BEND = bends sound loop (see: S_LOOP of SOUND) pitch according to special rules;
0 = default pitch
1 = pitch according to aiming angle (higher the entity aims, higher the pitch)
FX_SPARKS = adds particle sparks [toggle]
FX_SPARKS_TRAIL = trail of sparks (i.e. rocket tail smoke) [toggle]
FX_SPIN_CHARGE = spin weapon by following rules;
0 = off (default)
1 = on charge, use 90° spin instead of charge glow
2 = on attack, use 360° spin upon attacking
FX_STEAM = shoots out steam using smoke variables (works exactly like FX_SMOKE_SHOOT)
FX_TELEATTACK = applies teleport attack effect for missiles
FX_TRANSITION = makes S_SONG_DIE (see: SOUND) to use transitions;
0 = hard cut (default)
1 = long power down
2 = fade out
3 = short power down
FX_USERANGE = forces lights (see: LIGHT), plasma trails and masks (see: STENCILMASK) to use dynamic object size
and offsets. Rules are;
0 = dynamic object size off (default)
1 = uses horizontal size for masks
2 = uses vertical size for masks
3 = apply the size to the origin of the light effect as well as AREA_GLASS* effects (see: EFFECT)
FX_WADDLE = rapid waddle bias on death [toggle]
FX_WADDLE_AIM = constant aim waddling range
FX_WADDLE_ATTACK = applies aim waddle only when attacking (requires FX_WADDLE_AIM) [toggle]
FX_WADDLE_CONSTANT = constant waddling speed (per-entity, for per-sprite bias see: SPRITEVAR); Using value '1'
will force the entity to neutralize the waddle upon toggle
FX_WADDLE_FLY = forces the entity to use flying waddle dynamics, even if it's ground based [toggle]
FX_WADDLE_KEEP = complete override, directly re-set the bias value
FX_WADDLE_SPEED = waddle speed multiplier (per cents) for cases where you can't use FX_WADDLE_CONSTANT
FX_WADDLE_WALK = forces the entity to use walking waddle dynamics, even when flying [toggle]
FX_WALK_SHAKE = room shaking applied upon movement (shake multiplier in per cents)
FX_WATER_BUBBLE = generates water bubbles in way similar to FX_SMOKE_SHOOT [toggle]
FX_WATER_WAVES = generates water waves when near water surface [toggle]
FX_WEAPON_EFFECT = disables elements of default weapon handling animations according to the following rules;
0 = all effects on (default)
1 = all effects on, reversed rotation and pan
2 = accurate weapon mod (based on weapon kick instead of weapon animation timer)
3 = weapon mod is based on weapon timer (see: AI_WEAPON_COUNTER)
4 = no weapon pan / no weapon roll
5 = no weapon mod (see: WEAPONMOD of SPRITEVAR)
6 = no weapon pan / no weapon roll / no weapon mod
7 = no weapon pan / no weapon roll / no weapon mod / no weapon kick
FX_WEAPON_LAYER = defines how the weapon objects (see: GUNENTITY, WEAPON) are rendered;
0 = normal rendering (back objects back, front objects front, default)
1 = all weapon objects are rendered behind the entity
2 = all weapon objects are rendered in front of the entity
3 = disable rendering of the weapon objects
FX_WEAPON_MOUNT = mounts weapon, preventing spin, full kick and using alternate fullmodel angles [toggle]
HIGHROF = super rate-of-fire (multiple shots per real-time frame)
IMPALE = number of entities trace attack will blow through
INVISIBLE = Makes the entity invisible under specific conditions. When the entity as a whole is invisible, it cannot be
touched by physics or damaged by attacks. If you want to create an entity that is invisible but with which you
can still interact normally, either set the entity not to have sprites and effects or render the sprites invisible
(see: ALPHA 0 of SPRITEVAR). Also, if the entity-turned-visible is an owner of a group (see: GROUP), the
group entities will be rendered invisible according to the owner rules.
0 = always invisible (default)
1 = invisible when entity is inactive
2 = always invisible, even when the entity is active
MISSILE_OFFSETRADIUS = projectile launching radial offset
MISSILE_OFFSETWADDLE = makes projectile offset waddle by defined pixels
MISSILE_RANDOMIZER = projectile entity randomiser value (see: MISSILE)
MULTISHOT = makes weapon shoot multiple rounds at a time (value is the quantity of projectiles shot)
MULTISHOT_SPREAD = spread of the multishot projectiles (in degrees), just in case the default doesn't suit your needs
NOLIST = doesn’t show entity in editor (useful for groups, scripts, etc.) [toggle]

S_AR_BODY = body armour element (note that armour is added to health)
S_AR_HANDS = arm armour elements (note that armour is added to health)
S_AR_LEGS = armoured boots, triple jump and gravity stomp (note that armour is added to health)
S_AR_RANDOM = random armour pieces up to the defined amount (0-4, note that armour is added to health)
S_AR_SHOULDER = shoulder armour elements (note that armour is added to health)
S_EXTRALIFE = extra life quantity
S_FREELOAD = freeloader time (in integer seconds)
S_GRENADE1 = grenade #1 quantity
S_GRENADE2 = grenade #2 quantity
S_GRENADE3 = grenade #3 quantity
S_GRENADE4 = grenade #4 quantity
S_HEALTH = entity life points to be used in single player game
S_HEALTH_COOP = entity life points to be used in cooperative game (useful for balancing boss fights for two players)
S_IDDQD = gives invulnerability time (in integer seconds)
S_KEY = keycard quantity
S_OVERDOSE = gives instant overdose time (in integer seconds)
S_QUAD = quad damage time (in integer seconds)

[ 64 / 90 ]
STAT <string> <int>
S_REVIVE = restores players to full health
S_REGEN = gives health regeneration boost time (in integer seconds)
S_WEAPON = weapon slot index

SPECIAL_BOOST = enables speed boost move on use (for player use only, applied to the weapon entity) [toggle]
SPECIAL_DOUBLEJUMP = allows double jump move (player entities only) [toggle]
SPECIAL_ITEMS = enables the use of off-hand items (grenades etc.)
0 = off (default)
1 = use off-hand items
2 = use off-hand items even if attack type is set to NONE (see: THINK)
SPECIAL_NOJUMP = disables jumping (player entities only) [toggle]
SPECIAL_NOMAP = disables automap display (player entities only) [toggle]
SPECIAL_SLIDE = allows sliding move (player entities only) [toggle]
SPECIAL_STOMP = allows stomp move
0 = off (default)
1 = normal stomp (activates stomp for players; enemies stomp if player is beneath them)
2 = constant stomp (activates stomp for players; enemies stomp regardless of player positioning)
SPECIAL_SWIM = the entity (player or NPC alike) can swim in water; In practice a walking entity (see: MOVETYPE) with
this ability turns into a flying entity while it's submerged in water [toggle]
SPECIAL_TOKEN = token tag for multi-part, to-be-assembled weapon [toggle]
SPECIAL_TRIPLEJUMP = allows triple jump move with S_AR_LEGS equipped (player entities only); Also upgrades the
basic stomp into a gravity-stomp; requires SPECIAL_DOUBLEJUMP, too (obviously) [toggle]

TAKEDAMAGE_BLEED = bleeds and takes damage [toggle]
TAKEDAMAGE_DIRECT = entity can only be damaged by direct attacks; splash damage (DAMAGE_SPLASH) still hurts
the entity, but not through walls or platforms. Note that with trigger-bound entities (see: guide, table) using this
stat turns the entity invulnerable to everything but explosions [toggle]
TAKEDAMAGE_ELECTRIC = non-organic, sparkles, extra damage from electricity and is vulnerable to EMP [toggle]
TAKEDAMAGE_EMP = is vulnerable to EMP [toggle]
TAKEDAMAGE_EMP_FRAG = EMP becomes lethal on the very first shot [toggle]
TAKEDAMAGE_ENERGY = bleeds sparks based on entity colour
TAKEDAMAGE_ENV = takes damage like environmental texture objects [toggle]
TAKEDAMAGE_FIRE = is vulnerable only to AI_FREEZE [toggle]
TAKEDAMAGE_FRAGILE = fragile entity, gets instant-killed by DAMAGE_SONIC [toggle]
TAKEDAMAGE_MISSILE = only takes damage from non-explosive projectiles and actual explosions [toggle]
TAKEDAMAGE_NANITE = entity is made of nano-glass [toggle]
TAKEDAMAGE_NONE = doesn’t take damage (same as default, toggle)
TAKEDAMAGE_PIXEL = entity is made of retro pixels [toggle]
TAKEDAMAGE_PLAYER = the entity can only be damaged by player (or player drone) attacks [toggle]
TAKEDAMAGE_SONIC = entity can only be damaged by sonic attacks (see: DAMAGE_SONIC)
TAKEDAMAGE_STONE = non-organic but takes damage (as stone) [toggle]
TAKEDAMAGE_SURFACE = non-organic but takes damage (as metal) [toggle]
TAKEDAMAGE_UNBREAKABLE = unbreakable, solid, can’t be damaged [toggle]
TAKEDAMAGE_WADDLE = waddles according damage for defined time (negative time changes direction for impact)
TAKEDAMAGE_WEAK_DAMAGE = weakpoint damage multiplier [toggle]
TAKEDAMAGE_WEAK_ELECTRIC = weakpoint works as TAKEDAMAGE_ELECTRIC [toggle]
TAKEDAMAGE_WEAK_NANITE = weakpoint works as TAKEDAMAGE_NANITE [toggle]
TAKEDAMAGE_WEAK_NONE = defaults weakpoint damage system (see: WEAKPOINT) [toggle]
TAKEDAMAGE_WEAK_SONIC = weakpoint works as TAKEDAMAGE_SONIC [toggle]

TEMPMISSILE = life span when fired as a missile (in integer milliseconds)

STENCILMASK <int #1> <int #2> <int #3> <int #4> <bool>
description: Adds customizable stencil mask that will cut out portions of the entity that are outside the stencil area.
syntax: <int #1> area origin x-offset ; <int #2> area origin y-offset ; <int #3> horizontal radius ; <int #4> vertical radius ;
<bool> toggle between square (0) and rounded stencil
notes: Entity cut-away tool more deliberate and customizable than the classic scissors (see: SCISSORS). Whereas
scissors crudely cut away portions outside an axis-aligned rectangle, stencil masks are entity-aligned, i.e. entity's
full model angle affects the stencil orientation as well.

Usage of stencil mask is toggled with STAT FX_SCISSOR (in case of group entities, see: STAT) or with sprite
variable SCISSORS (on per-sprite basis, see: SPRITEVAR). If entity is part of a group, stencil mask of the group
originator is used instead.

TEXPOLY <string> <int>
description: Adds a texture block for entities defined in map itself (doesn't apply to entities spawned in-game).
syntax: <string> texture image filename ; <int> y axis offset (from entity's origin)
notes: Being mainly designed for making background mount for static actors like turrets, this command is not that practical
with moving entities. If the texture name begins with '(' the texture remains exclusive and doesn't show up in the
editor's texture list. If you wish, you can clone it (see: TEXCLONE) to list it. Also texpolys can have assigned entities
(see: TEXLITE), but it's not very practical since these are already entity-bound. Remember, though, that these types
of textures are always loaded to memory, so if this entity of yours appears rarely and/or is huge, you'd better use

[ 65 / 90 ]
TEXPOLY <string> <int>
either a layer or trigger entity with dynamically loaded graphics (see: TRIGGER, LAYER).

Also worth noting is the fact that entities that have texture polygon defined are moved to the front of the rendering
cue (i.e. to the back); They're supposed to be connected to a piece of static wall artwork, after all. This means if you
want an entity to appear in the background but don't want to resort to using FX_RENDERFIRST (see: STAT), you
can do it by setting the entity's texture polygon to “(fade)”. This is the fade-to-black texture tool used in the editor,
but in case of entity-generated polygons it is ignored – however, the entity is moved to the background regardless.

THINK <string #1> <float #1> <string #2> <float #2>
description: Defines the AI routine used for the entity.
syntax: <string #1> main AI routine reference ; <float #1> speed modifier ; <string #2> attack AI function reference ; <float
#2> delay between attacks (in seconds)
notes: If no main AI reference is defined the entity will be handled as a static decoration. By default AI_USER is 'player one
character'; To make it 'player two', you'll need to set AI_PLAYER_TWO stat flag (see: STAT). AI reference
AI_MISSILE applies the attack method AI_BLOW by default. Possible main AI references:
AI_AIM = constantly aims at the player, aim affects flying direction
AI_CONSTANT = Keeps constant distance to the leader of a group, or in case of AI_SLAVE (see: STAT).
AI_FOLLOW = follows the player until reaches attack range
AI_ITEM = an item
AI_MISSILE = weapon projectile
AI_USER = player-controlled
AI_WANDER = flying entity which wanders around it’s owner
AI_WARP = entity warps
AI_ZOMBIE = walks straight until hits wall or dies
NONE = static entity

Possible attack references:
AI_FIRE = fires a missile
AI_BLOW = acts like missile on impact
AI_MELEE = attacks when player is within touch; with entities that have procedural hands (see: LIMB), attacking will
trigger an automatic, procedural mêlée animation
NONE = no attack

TRANSFORM <string> <int>
description: Defines an entity into which the current entity will transform after defined period of time
syntax: <string> name of the entity to be used; <int> delay of transformation from activation (in milliseconds)
notes: Entity must be defined before it can be used. However, you can get around this by using TRANSFORM_DIRECT,
which uses numeral index offsets instead of entity name to define the transformation target. Using negative delay
value (i. e. -1) will set the transformation to happen on death. All the in-game variables (angles, velocities, health,
etc.) will be preserved beyond transformation if their defaults are the same on both the original entity and the
transformation. You can randomize the target entity with AI_RANDOM_TRANSFORM and the transformation time
with AI_RANDOM_TRANSTIME (see: STAT). If you want the transformed entity to appear in different point, set offset
value TRANSFORM (see: OFFSET) for the target entity.

By default, transformations rigidly follow the transformation timer. However, in some cases this isn't ideal and can
break the entity's attack cycle in a not-so-smooth manner. To avoid this, use AI_TRANSFORM_ADAPTIVE (see: STAT).
Adaptive transformations delay the transformation if the entity is in middle of an attack (i.e. just acquired lock-on and is charging the
weapon, see: CHARGE of STAT).

Take note that group entities won't transform according to their own timers – the transformation happens in tandem
with the group owner entity. Using entity name NONE disables transformation (useful with cloned entities, see:
CLONE).

TRANSFORM_DIRECT <int #1> <int #2>
description: Defines an entity into which the current entity will transform after defined period of time
syntax: <int #1> index offset value; <int #2> delay of transformation from activation (in milliseconds)
notes: Index offset based variation of TRANSFORM; It works exactly the same, except it uses index offset value to define
the transformation. This way you can transform directly into entities that are set further down the script (read; that
are not yet defined). For example; Using offset value 1 would transform the current entity to the next entity in the
script.

UNLOCK <string>
description: Killing the entity unlocks a specific Database entry (see: UNLOCKABLE).
syntax: <string> entry name

[ 66 / 90 ]
UNLOCK <string>
notes: Killing entity means that player frags an opponent or picks-up an item. Only one database entry can be unlocked
per entity.

VISBOX <int #1> <int #2> <int #3>
description: Defines the visual bounding box for an entity. The box is used to measure if the entity is on screen or not.
syntax: <int #1> horizontal radius of the box (from origin) ; <int #2> bottom of the box (from origin) ; <int #3> top of the box
(from origin)
notes: Default size of the visual bounding box '24 24 24' (24 pixels to left, right, down and up from the entity's origin). With
trigger-based entities (i.e. 'guide', see: Using Triggers: guide, TRIGGER), if the trigger field is larger than the visual
box, the trigger field dimensions override those of the entity's.

Setting up the rendering box is a must in TAGAP 3; If the box is too small, the entity will flicker in and out of
existence when it's near the edge of the screen. And if the box is larger than needed GPU and CPU cycles will go a
waste for attempting process something that can't be seen. Previous TAGAP engines measured the entity visibility
on the fly, but with all that's going on in TAGAP 3 rendering engine, having user-defined visual bounding boxes
saves everyone's time – including the computer's.

Also worth noting is the fact that physical size (see: SIZE of OFFSET) is NOT the same thing visual bounding box.
Many properties affect to the area in which the entity is visible, including (but not limited to) limbs (see: LIMB), lights
(see: LIGHT, FLASHLIGHT), plasma trails (see: FX_PLASMA_TRAIL of STAT) and sub-entity objects (see:
OBJECT, GUNENTITY). If the object has a full model angle (see: FX_FULLMODEL, FX_FULLANGLE* of STAT) or
is a corpse (see: CORPSE), the entity will rotate up to 360 degrees on its axis, meaning ALL dimensions should be
larger-or-equal to the largest dimensions defined.

VOICE <string>
description: Adds a sample into player voice over group (see: VOICEOVER, VOICEOVER_END).
syntax: <string> sample name
notes: Samples are loaded from data/sound/voiceover folder.

VOICEOVER <string> <int>
description: Starts defining player voice over group.
syntax: <string> group name ; <int> modifier
notes: Keeps parsing voice over samples until group is closed (see: VOICE, END). Group name is used to determine
which group to play. You can name them how you please, except for the first group, which has to be “NULL” for
compatibility. Possible modifiers:
0 = normal voiceover
1 = play once flag
-1 = appear as plain subtitles
-2 = appear as a title card

The “play once” prevents the group from playing multiple times in a row – that group won't be played again until
some other group is played in between. “Subtitle” option makes the option the message appear as simplified
subtitle as opposed to comic book speech bubble.

You can define death comments for entities (see: SOUND) or use trigger “dialogue” to create even more specific
voice over events (see: Using Triggers: dialogue, TRIGGER). Obviously group must've been defined before it can
be assigned to anything. You can also define an icon to be displayed when voiceover is used with a dialog (see:
ICON).

WEAKPOINT <int #1> <int #2> <int #3>
description: Defines a weak spot for an entity otherwise invulnerable.
syntax: <int #1> spot x-offset ; <int #2> spot y-offset ; <int #3> spot damage area radius
notes: By default, all attacks will impact to main entity's physical frame before weak point, but in some cases, i.e. when
weak spot is located inside a large, solid entity, yous'll have to make weak spot a priority for impact checks; In these
cases, use AI_WEAKFIRST (see: STAT). Weak point also obeys AI_INVULACTIVE (see: STAT). Player entities
can't have weak points. By default, weak point is metal, equal to TAKEDAMAGE_SURFACE. However, you can
modify the nature of the weak point via TAKEDAMAGE_WEAK_NONE/ELECTRONIC/SONIC modifiers (see:
STAT).

[ 67 / 90 ]
WEAPON_RESPONSE <int #1> <int #2>
description: Responds to player's weapon by switching own weapon according to the scripting.
syntax: <int #1> weapon slot to respond to (0-9) ; <int #2> weapon to use against player's gun
notes: Entity's weapon response can be any of the available weapon slots (see: WEAPON). If there's no scripted response
for player's weapon, the entity's default weapon (S_WEAPON, see: STAT) will be used. If you want the entity to
always use same weapon as the player, use AI_COPY_PLAYER_GUN (see: STAT); That way you need to add
weapon response details only for slots you don't want the entity to access.

To turn turn off all weapon responses for cloned entities (see: CLONE), use player weapon slot reference '-1'.

Limb commands

LIMB <string #1> <string #2> <float #1> <float #2> <bool #1> <bool #1>
description: Starts parsing a limb for an entity
syntax: <string #1> limb name ; <string #2> limb program ; <float #1> start joint origin x-coordinate ; <float #2> start joint
origin y-coordinate ; <bool #1> background flag ( 1 = render behind base entity ; 0 = render in front of base entity) ;
<bool #1> attachment by default ( 1 = attached, 0 = not attached)
notes: Keeps parsing limb variables until limb is closed (see: END). The engine creates an internal database from limb
names and uses them to validate limb commands for poses (see: POSE). You can modify existing limbs of cloned
entities (see: CLONE) with MODIFYLIMB.

Possible programs;
NULL = No program; Remains as-is until animated specifically
BODY = Echo of the core entity (copies full-angle values, see: FX_FULLMODEL and FX_FULLANGLE_* of STAT)
ECHO = Echo of the first limb in the same entity with the same name; Copies both the origin and angles
EYE1 / EYE2 = Eyes ; Anchored to HEAD – if no head is defined, eyes are anchored to body origin
EYEBROW = Eyebrow ; Anchored to HEAD – if no head is defined, eyes are anchored to body origin
HAND1 = Front hand (i.e. the one that holds the weapon grip)
HAND2 = Background hand (the one that holds the weapon stock/handle and throws grenades)
HAND3 = Additional arm, when attached this one tries to hold casing offset
HAND4 = Background hand specifically positioning itself for akimbo weapons (see: AI_AKIMBO of STAT)
HAND1_LOOSE / HAND2_LOOSE = Alternate versions of the HAND1/HAND2 that will never attach to the weapon
HEAD = Head; Used as an anchoring limb for eyes and eyebrow
HEAD_ECHO = Echo of the first HEAD in the same entity; Copies the angles, but uses its own origin
LEG1 / LEG2 = Legs; When walking and jumping, LEG1 and LEG2 move into opposite directions
LEG3 = Same as LEG1, except this one doesn't move when walking
LEG4 = Same as LEG3, only this one rotates according to roll angle (see: ANIM_ROLLVEL of SPRITE)

Limb commands (to be put between “LIMB and END”);
ANGLEFACTOR <float> = multiplies the actual angle of the limb by this amount when rendering it
BOB <float>
INVERT <bool>

MODIFYLIMB <limbid> <bool> <float #1> <float #2> <float #3>
description: Modify an existing limb.
syntax: <int> index of the limb ; <bool> attachment (1 = attached, 0 = not attached) ; <floats> the default angles of the limb
elements
notes: Modifies the default values of an existing limb, designed to be used in tandem with cloned entities (see: CLONE). A
good example of this would be the standard 'zombie' enemies; the default orientation of their hands is 'pointing
downwards'. This gives the hands a full range of movement when the 'zombie' walks. However, when a tool variant
of it is created (see: HOLDOBJECT of OBJECT), it's better to bring the tool-holding hand ahead – this gives it less
wide swing and shows the tool better. In this case, rather than being forced to re-create the entity from scratch, you
can do it like this (this an actual entity script from TAGAP 3 in full, with comments):

ENTITY z_t_hammer
// clone the 'zombie' entity
CLONE zombie_1
// add new description
DESCRIBE Tool_(hammer)
// make the first limb (arm) point less downwards as default
MODIFYLIMB 0 1 -30 0 0
// change the attack sound
SOUND DYNAMIC S_ATTACK dynamic/weapon_melee_tool 20
// give the entity an object to hold
OBJECT 1 tool_hammer 0 0 HOLDOBJECT 0 0 0
// expand visibilty box to include the object
VISBOX 64 32 88
// make the entity available as a cannon fodder option

[ 68 / 90 ]
MODIFYLIMB <limbid> <bool> <float #1> <float #2> <float #3>
STAT AI_FODDER_OPTION 1
END

POSE <string> <bool>
description: Keeps parsing pose variables until the pose is closed (see: END).
syntax: <string> name of the limb; <bool> attachment (1 = attached, 0 = not attached)
notes: This command is designed for creation of separate pose scripts that can be loaded dynamically or statically and
used by entities (see: POSESET), triggers (see: Using Triggers: pose) and animations (see: POSEANIM) alike. The
main purpose of pose scripts is to allow creation of complex custom animations that can be flushed from memory
when no longer needed – as opposed to creating static entities for every 'frame' as things where done with the
earlier TAGAP engines.

It's worth noting that the name of the limb refers to the user-given name, NOT the name of the limb program (see:
LIMB). This way an entity have, say, multiple legs that can also be animated separately if the arises.

Each pose script file typically features multiple POSEs – one for every LIMB the script will affect – and each POSE
consists of commands for every ELEMENT of the said limb (for example, a hand of the player character has three
elements). For example, this script detaches players hand from the weapon and slowly rises it straight up;

POSE weapon_hand1 0
POSE_ELEMENT 90 5
POSE_ELEMENT 0 5
POSE_ELEMENT 0 5
END

For commands used to manipulate the elements, see: POSE_ELEMENT, POSE_DEFAULT and POSE_RANDOM.

POSE_DEFAULT <float>
description: Sets the limb to move to its default position by user-defined speed. Used in pose scripts (see: POSE).
syntax: <float> speed of the movement
notes: Automation command that sets the entire limb to move to its default pose defined in the entity script (see: LIMB).
With POSE_DEFAULT, there is no need to set each element; it affects the entire limb.

POSE_ELEMENT <float #1> <float #2>
description: Adds a command for an element of a limb. Used in pose scripts (see: POSE).
syntax: <float #1> target angle (in degrees) ; <float #2> speed of the movement
notes: This commands tells the limb segment to move to the target angle at the speed defined. Note, however, that if the
limb attachment is set to 'attached' in the pose script (see: POSE), user-defined angles are obviously ignored (i.e. in
case of a hand, it would move to 'hold a gun' pose at the user-defined speed).

Target angles of the poses are set in relation to their parent element. For example, see this script;

POSE weapon_hand1 0
POSE_ELEMENT -45 5
POSE_ELEMENT 90 5
POSE_ELEMENT 0 5
END

The first segment is in 45° angle. The first element has no parent, so this means the hand moves, by the shoulder,
downwards in 45°. Second element has 90° angle, so it will be in 90° angle in relation to the first element. The third
element has 0° angle, so it has the same exact angle as the second element.

There are no limb segment pointers needed for pose scripts; First POSE_ELEMENT affects the first element,
second the second element and so on.

A couple of the limb types function differently from the norm, having a different syntax:

EYE1, EYE2 = eyes don't have an angle or speed; instead the values represent x and y offsets measured from -1 to 1
(i.e. “POSE_ELEMENT 0 1” would make the character look up)
EYEBROW = eyebrows aren't measured by angle, but by the frown ranging from -1 to 1; -1 would be frowning, 1 would
be the opposite, while 0 is the default expression.

[ 69 / 90 ]
POSE_RANDOM <float>
description: Sets the limb to move to a random position by user-defined speed. Used in pose scripts (see: POSE).
syntax: <float> speed of the movement
notes: Automation command that sets the entire limb to move to a random position, limited by the ranges defined in the
entity script (see: LIMB). With POSE_RANDOM, there is no need to set each element; it affects the entire limb.

POSE_SOUND <string> <int>
description: Defines an optional sound sample to be played on the animation frame. Used in pose definition scripts (see:
POSE).
syntax: <string> sample name ; <int> maximum allowed variation of the sound pitch (in per cents)
notes: Sound is played when-ever that pose frame is activated, whether it's directly (see: POSESET) or via animation
(see: POSEANIM). The sound sample is considered 'foley sound', meaning the fall-off is based on
FX_IDLEDISTANCE (see: STAT). Note that unlike with entity sounds (see: SOUND) there is no need to define
whether the sound is dynamic or not, since pose frames themselves are dynamic in nature; If the pose frame isn't
one defined for the engine, it and it's contents are dynamic and loaded when needed.

POSEANIM <boolean #1> / <string> <boolean #2>
description: There are two uses for this command. In animation scripts, this command defines a pre-set animation loaded
dynamically, using a set of poses on a timer. In entity scripts, it tells which animation to load for the said entity.
syntax: <boolean #1> animation loop flag (0 = run through once; 1 = constant loop) (animation scripts) / <string> name of
the animation script (entity scripts) ; <boolean #2> flag whether to animate the entity even when it is inactive or not
(0 = animate entity only when active; 1 = animate even when the entity is inactive) (entity scripts)
notes: In animation scripts: Keeps parsing animation frames until animation is closed (see: END). Variables that are used
to create the animation are POSEFRAME and POSERANDOM.

In entity scripts: By default, the entity starts with the first frame in the animation script and then goes through the
animation frames linearly. However, you randomise the animation frame order with FX_RANDOM_POSE (see:
STAT).

POSEFRAME <string> <int>
description: Adds a pose as a frame in an animation script.
syntax: <string> name of the pose script file used as the animation frame ; <int> time it takes for the frame to activate
notes: The time defined relates to how long it will take the animation move from the previous frame to the one in question.
You can randomise the time via using POSERANDOM. There is no need to define the frames as static or dynamic,
the engine will sort this out automatically.

POSERANDOM <int>
description: Adds randomisation to an animation. Used in animation scripts (see: POSEANIM).
syntax: <int> maximum amount of time added to the animation frequency (in milliseconds)
notes: Randomisation is added to the previously defined animation frame (see: POSEFRAME). The randomisation ranges
from 0 to defined milliseconds.

POSESET <string #1> <string #2>
description: Tells an entity to use a specific pose. Used in entity scripts.
syntax: <string #1> loading parameter (STATIC or DYNAMIC); <string #2> name of the pose script file
notes: The default frame of the entity is used when the entity is created – either by the map loading, the entity being
spawned or when an entity transforms into the entity in question.

SPRITELIMBVAR <int #1> <int#2> <string> <int #3>
description: Alternate version of SPRITEVAR that affects sprites defined within a limb (see: LIMB). Used in entity scripts outside
limb definition segment.
syntax: <int #1> index of the limb ; <int #2> index of the sprite ; <string> variable name ; <int #3> value
notes: The main use for SPRITELIMBVAR is when you want to modify sprite variables for an already-defined limb, i.e. with
entity clones (see: CLONE). Apart from needing to define the limb in which the to-be-affected sprite is, the syntax is
exactly the same as in normal sprite variables (see: SPRITEVAR).

[ 70 / 90 ]
Definition commands
BACKGROUND_TO_DIM
description: Makes on-background (dimmed) portions of the screen to use background colour shifting instead of the default front
shifting. Used in map themes (see: THEME).
syntax: –
notes: Always active in case of overdose effect themes.

BLOOM <int>
description: xx. Used in map themes (see: THEME).
syntax: <int> intensity of the bloom effect (from -100 to 100, default is 0)
notes: Associates a bloom effect with the current theme. Negative bloom is a simple bloom halo, while positive bloom is a
more dynamic one with light rays (similar to the acid trip effect). Not supported by overdose effects. Also note that in
sequences, bloom effects associated with map themes are not used; Instead, in sequences the bloom control is
bound to camera cut controls (see: SEQCUT).

CANNONFODDER <string #1> <string #2>
description: Defines a cannon fodder list entry.
syntax: <string #1> name of the fodder list ; <string #2> name of the entity to add
notes: To-be-spawned entity is picked random from the chosen list. Name “NONE” is reserved for “no fodder”. To add
optional fodder slots – level- or area-specific entities that whose usage is defined within the editor – simply replace
the entity name with either FODDER_OPTION1, FODDER_OPTION2 or FODDER_OPTION3 (which is the power
tool option). To tag entities to be available as optional fodder, see AI_FODDER_OPTION of STAT. Cannon fodder
lists are used in level configuration (see: Appendix C: Configuration Variables, CVAR) and by certain triggers (see:
FODDER, MANHOLE).

CUSTOMENTS <string>
description: Starts parsing a custom entity list.
syntax: <string> name of the custom entity list
notes: Custom entity lists are, well, customizable lists of entities. These lists are referred to when the engine generates
entities – like for example when the player receives combo rewards. The idea is that regardless of how you theme
your level, you can have a fitting set of entities generated within it.

For syntax, just add the defining line and below it, the entities, each on it's own line. The entities have to be listed in
the following order;

Reinforcements / assistance entity
Health item that is rewarded for combos and whose item (see ITEM) is spawned when being used from inventory
Reward for 100 frags
Reward for 200 frags
Extra life
Key item (mainly used when spawned via the developer cheats menu)

Removing the default list – called NONE – is not advisable, as that is the default list the engine always reverts to.

Keeps parsing values until the list is closed (see: END). Custom entity lists are used in level configuration (see:
Appendix C: Configuration Variables, CVAR).

COLOR <bool #1> <bool #2> <byte #1> <byte #2> <byte #3>
description: Defines the lighting colours for a theme. Used in map themes (see: THEME).
syntax: <bool #1> part to affect (0=world; 1=backgrounds; 2=background objects); <bool #2> shift state to define (0=base;
1=target value of colour shift); <bytes> colour in RGB format
notes: If no background object colours (value 2) are defined, background colours are used instead (value 1). Theme
colours can be static or made to shift in various ways (see: SHIFT).

CVAR <string #1> <int / string #2>
description: Stands for configuration variable and is used for storing engine configurations.

[ 71 / 90 ]
CVAR <string #1> <int / string #2>
syntax: <string #1> variable name; <int> numerical value; <string #2> string value
notes: Use either numerical or string value, not both. There are two types of CVars – those that are automatically stored
into user configuration and those that are used for game scripting. See Configuration Variables for Game Editing for
editing variables and “Troubleshooting Handbook” for system configuration variables as well as command line
usage. CVars are registered engine-side, so you cannot create new CVars through scripting.

DARKNESS <int #1> <int #2>
description: Defines the intensity of the darkness effect. Used in map themes (see: THEME).
syntax: <int #1> base darkness; <int #2> shifted darkness
notes: Darkness intensity ranges from 0 (over bright) to 3 (pitch black). Normal darkness is 1. Shifted darkness is only
used by DELAY shifting (see: SHIFT). Not supported by overdose effects, they always refer to values defined of
currently active theme.

ENVIRONMENT<string>
description: Defines the environment style for theme. Used in map themes (see: THEME).
syntax: <string> environment style
notes: Not supported by overdose effects. Possible environment styles:
COLD = breezing cold with visible breath
RAIN_ACID = acid rain
RAIN_BLOOD = heavy blood rain
RAIN_BLOOD_LIGHT = light blood rain
RAIN_LIGHT = light exterior rain
RAIN_HEAVY = heavy exterior rain
RAIN_INT = interior with heavy rain falling outside
SNOW = calm snowing
UNDERWATER = completely flooded underwater setting

FLOOR <string #1> <string #2> <string #3> <int #1> <int #2> <int #3>
description: Sets up a floor style to be assigned for linedefs (see: LINEDEF).
syntax: <string #1> style name; <string #2> floor texture name; <string #3> ceiling texture name; <int #1> floor impact style;
<int #2> wall and ceiling impact style; <int #3> customization variable
notes: The texture files used are named “(world-*)” and “(world-*-point)”, * being the texture name. The order in which the
floor styles are defined is the same as the rendering order – further it is in the list, further back it will be rendered.
Using texture name “CLEAR” and “NONE” means the floor won't have a texture, where “CLEAR” is still rendered
into the automap as a wall/ceiling/floor, while “NONE” is completely invisible.

Possible impact type values:
0 = stone, concrete, etc.
1 = solid metal
2 = ice (floor that is always frozen, both effectively and visually)
3 = wood
4 = bleeding flesh
5 = nanites
6 = pixels
7 = snow

Possible customization values;
0 = normal linedef, no effects
1 = floor grows grass
-1 = floor is non-blocking, allowing impacts only with entities with AI_NONBLOCKING tag (see: STAT)
-2 = floor is a bouncer; a bumper object only affecting zombie cannon fodder (see: CANNONFODDER, THINK)

FONTW <int #1> <int #2 – #17>
description: Defines width of font characters per line in font textures. Used in game definition script.
syntax: <int #1> line in texture (0-5); <int #2 – #17> character widths in pixels
notes: Character width is one of a character in texture. It is strongly recommended, though not required, that all the
numerals are of equal width, as different width results slight but visible fluctuation in status display counters, which
doesn't look good. Width of numeral characters in default font is 21 pixels.

GRAVITY <int>
description: Defines gravity for theme. Used in map themes (see: THEME).

[ 72 / 90 ]
GRAVITY <int>
syntax: <int> gravity in per cents of normal
notes: You don't need to define gravity if it's the default 100%. Not supported by overdose effects.

GUISTR <string #1> <string #2> <string #3> <string #4>
description: Defines string to be used in GUI. Used in GUI scripts.
syntax: <string #1> string reference id; <string #2> item name; <string #3> help line; <string #4> help line
notes: Menu ids must start with character '_', editor strings with '*' and sequence strings with '+'. This way you can have
same id with different content (i.e. “_save” and “*save”). String id must not be longer than 16 characters. Though
used ids of menu and editor strings are fixed in-engine, you can make your own strings for sequences (see:
SEQUENCE).

INCLUDE <string>
description: Includes a new script file to be loaded on start-up. Used in game definition script.
syntax: <string> name of the script file to include
notes: Scripts will be loaded in the order specified.

INTERIOR_AMBIENCE
description: Toggles interior ambience sound system on. Used in map themes (see: THEME).
syntax: –
notes: In practice this option makes all global ambient sounds (see: SHIFTSOUND, STREAM) sound they came from
outside. For example the sounds are audible when standing next to window and even more so once you break the
said window. Not supported by overdose effects.

SHIFT <bool> <string> <int #1> <int #2>
description: Defines colour shifting for the level theme. Used in map themes (see: THEME).
syntax: <bool> part to affect (0=world; 1=backgrounds); <string> style; <ints> speed modifiers for the shifting cycle
notes: DELAY and FLASH shifting intervals can be randomized (see: SHIFTRAND) and/or it can make a sound (see:
SHIFTSOUND). Note that entities can have custom bloom effects rendered when the environments flashes with
FLASH shifting (see: FX_LIGHT_LIGHTNING of STAT). Styles:
NONE = static
PULSATE = pulsating
DELAY = delayed sharp-cutting shifting (modifiers equal time delay in milliseconds)
FLASH = practically the same as delay, except this one adds global flash when when switching between colors

SHIFTRAND <bool> <int #1> <int #2>
description: Randomizes theme colour shifting modifiers. Used in map themes (see: THEME).
syntax: <bool> part to affect (0=world; 1=backgrounds); <ints> max random value added to speed modifiers
notes: Supported only by DELAY colour shifting (see: SHIFT).

SHIFTSOUND <string #1> <string #2> <int>
description: Sound played during theme colour shifting (i.e. a thunder strike). Used in map themes (see: THEME).
syntax: <string #1> sound loading parameter (STATIC or DYNAMIC); <string #2> sample name; <int> maximum allowed
variation of the sound pitch (in per cents)
notes: Shifting sound is only played by DELAY shifting (see: SHIFT). Not supported by overdose effects. For more
information what the sound variation does and how it works, see the entity sound function (see: SOUND).

SOUNDEQ
description: Toggles the EQ nullification for the theme. Used in map themes (see: THEME).
syntax: –
notes: EQ nullification creates the space vacuum sound effect.

[ 73 / 90 ]
SOUNDLOOP <string #1> <string #2> <string #3> <boolean>
description: Defines a sound loop for sound trigger field to choose from.
syntax: <string #1> sound loading parameter (STATIC or DYNAMIC); <string #2> sound loop reference name; <string #3>
loop sample name; <boolean> random starting point flag (0 = off; 1= on)
notes: It's not recommended to use sounds that are defined as non-looping as looping and vice versa. Like with entity
sounds (see: SOUND), the sound loops can also be set to be loaded dynamically only when needed, just make
sure you don't try to define static, engine-side loops again as dynamic. Usage of OGG Vorbis format is strongly
recommended in case of long loops because of smaller files. Once loop is defined it can be used with trigger
“sound” (see: TRIGGER, sound).

New to TAGAP 3 is the ability define whether the loop will have a random starting point or not. What this means in
practice is that when the playback starts for a sound loop, it can start either from the beginning of the sound, or from
a random position. For example, if two sound sources playing the same sound are within earshot, randomisation
prevents them from sounding like an unnatural, pre-programmed choir.

As rule-of-thumb sounds should always start from random position, unless it's specifically not desired. Good
example from this scenario would be a sound of an alarm; Using randomized start could end up starting the sound
in the middle of the klaxon blow and that never sounds good.

STREAM <string>
description: Defines background audio stream to be played. Used in map themes (see: THEME).
syntax: <string> stream name
notes: All stream loops are streamed from “sound/stream” folder. Streamed audio should be full stereo. Not supported by
overdose effects. Doesn't affect sequences to avoid conflicts with sequence streams.

TEXBRIGHT <string>
description: Makes texture completely fullbright without need of adding separate fullbright texture.
syntax: <string> name of the texture
notes: Comes very handy in creating light sings etc. without wasting memory for nothing.

TEXCLONE <string #1> <string #2> <bool>
description: Clones a texture.
syntax: <string #1> name of the clone ; <string #2> name of the texture to clone ; <bool> toggles full bright of original
texture for the clone
notes: Mainly used in creating effect-free versions of already lit or entity-assigned textures. Always create a clone instead
of duplicating the image file, thus avoiding needless memory wasting. You can also clone engine-defined textures
and entity texpolys (see: TEXPOLY) to be used in editor; In this case the texture has to be defined before creating a
clone.

TEXDAMAGE <string #1> <string #2>
description: Defines a damaged equivalent for a texture.
syntax: <string #1> name of the texture ; <string #2> name of the damage texture
notes: Designed for use with trigger “envdamage” (see: TRIGGER, envdamage). Unlike with the previous versions of
TAGAP engine, TAGAP 3 supports dynamic damage textures as well (see: TEXDYNAMIC).

TEXDYNAMIC <string #1>
description: Adds a dynamic texture to the texture list.
syntax: <string #1> name of the texture
notes: Always name dynamic textures with square brackets (i.e. “[metal4]”), otherwise it'll be loaded as static texture
instead. In the game dynamic textures are loaded on per-need basis, while in editor all of them are loaded at once
for smooth editing experience. Keeping this in mind, if you'll need to add a block of some specific texture that is
used only once or twice in the entire project, consider using layers and texture tags (see: LAYER, textag) instead to
speed-up the swapping between the game and the editor.

TEXLITE <string #1> <string #2> <int #1> <int #2> <int #3> <int #4>
description: Adds an entity to a texture polygon.

[ 74 / 90 ]
TEXLITE <string #1> <string #2> <int #1> <int #2> <int #3> <int #4>
syntax: <string #1> texture name ; <string #2> entity name ; <int #1> entity x-offset (in pixels from left) ; <int #2> entity y-
offset (in pixels from the bottom) ; <int #3> width of the texture image (in pixels) ; <int #4> height of the texture
image (in pixels)
notes: The coordinates and dimensions give refer to the coordinates and dimensions of the texture image (if the image is
64x64 pixels, center coordinates would read '32 32 64 64'). Both the texture and entity have to be defined before
using this command. This was originally designed to add texture lights, but it works with all entities, i.e. particle
generators. Use texture clones (see: TEXCLONE) to add different effect variations – to do this, create a clone
before assigning any entity to the original texture. You can also add entities to texture clones and entity texpolys
(see: TEXPOLY).

Unlike in previous versions of TAGAP Engine, in TAGAP 3 you can add texture entities to dynamic textures as well.
However, to achieve this you now have to input all the texture dimensions too, as the actual dynamic texture image
is loaded after the entities have been placed.

And in case you were wondering, the name of this command originates from the first TAGAP, where the main usage
for it was to create textures with simple light entities attached.

TEXMODULATE <string> <int #1> <int #2> <int #3>
description: Fullbright texture is rendered as an energy flow using the fullbright image as alpha mask.
syntax: <string> name of the texture ; <int #1> effect texture ; <int #2> flow direction ; <int #3> speed of the flow
notes: The texture must naturally have a fullbright overlay in order to get the modulation to work. Directions are: 0 = up, 1
= down, 2 = right, 3 = left. Modulation works for all sorts of texture objects and works in same way as the sprite
variables ENERGY, ENERGY_FLOW and ENERGY_SPEED (see: SPRITEVAR).

TEXREFLECT <string> <int>
description: Adds reflection to texture.
syntax: <string> texture name ; <int> reflection type
notes: Both the texture and entity have to be defined before using this command. If you want to disable a reflection for a
cloned texture (see: TEXCLONE), set reflection type to -1.

THEME <string>
description: Starts defining a level theme.
syntax: <string> name of the theme
notes: Keeps parsing values until theme is closed (see: END). If the name starts with '_' it will be handled as overdose
effect instead of level theme.

TIMEFLUX <float #1> <float #2>
description: Forces passage of time to fluctuate from real time to slow-motion. Used in map themes (see: THEME).
syntax: <float #1> the minimum multiplier for the fluctuation ; <float #2> speed modifier
notes: Fluctuation is based on sin of real time modified by the speed multiplier. For example, minimum multiplier of 0.5
means that at the lowest peak of sin-wave, one second actually lasts seconds. Not supported by overdose effects.

UNLOCKABLE <string #1> <string #2> <bool> <byte>
description: Defines an unlockable entry to the Database.
syntax: <string #1> entry name ; <string #2> description ; <bool> set to one if you want this entry to be available in the
Database from the beginning ; <byte> the category to which the entry belongs to
notes: Entry name doubles as a reference to the entry file name. File names are in format “script/gui/txt_<string #1>.txt”. If
said file is accessed via an InfoComp (see: TRIGGER, infocomp), the related entry is automatically unlocked in
Database. If you want the entry to be unlocked via an entity interaction (via fraggin' or picking up an item), use entity
command “UNLOCK” (see: UNLOCK).

Category defines in which Database list the entry will be logged down into. Using categories 250 and higher will be
considered as gameplay tip splash screens – they are marked down as read and won't be shown again. File name
format for gameplay tips is “script/gui/hint_<string #1>.txt”. You can have the unlockable appear as both the
Database entry and gameplay hint simply by having both the Database and tip files present. Other default
meanings of the categories in TAGAP 3 are as follows:
0 = gameplay tips and environment info
1 = guns, gadgets and vehicles

[ 75 / 90 ]
UNLOCKABLE <string #1> <string #2> <bool> <byte>
2 = characters and enemies
3 = location specific computer entries
250+ = gameplay tips not visible in the Database

VELOCITY <float #1> <float #2>
description: Defines the constant velocity values for a theme. Used in map themes (see: THEME).
syntax: <float #1> x-axis velocity ; <float #2> y-axis velocity
notes: Used to great sensation of high speed or windy conditions. You can set entities to ignore world velocity with
AI_IGNORE_VELOCITY (see: STAT). Also, you can replace procedural entity pan with world velocity pan by using
FX_PANSCENE (see: STAT). Not supported by overdose effects.

WEAPON <int #1> <int #2> <string #1> <string #2>
description: Defines a weapon slot.
syntax: <int #1> weapon slot (0-255) ; <int #2> maximum ammunition for automatic ammo generation ; <string #1> primary
weapon entity name ; <string #2> secondary weapon entity name
notes: Keeps parsing weapon variables until entity is closed (see: END). Weapon entities must be defined before the
weapon itself. Use status variable S_WEAPON to define active weapon slot for an actor entity (see: STAT) or use
weapon response scripting (see: WEAPON_RESPONSE). Player can use weapons 0-9 if ammunition is available
(see: AMMO), so use slots 10 and beyond for non-player weapons. The offsets for skeletal animation system and
projectile generation are defined with the command OFFSET (see: the weapon values of OFFSET).

As new feature to TAGAP 3, the enemies can use the secondary fire as well. This happens if the entity has a
weapon with a secondary attack different from the primary and the entity uses bursts (see: AI_BURST of STAT). In
this case, the entity will alternate between burst firing with the primary and attacking with the secondary fire.

Note that unlike in original TAGAP, you don't define weapon display names with this command in TAGAP 3;
Description of the primary weapon entity is used instead (see: DESCRIBE).

WEAPONITEMS <int> string #1> <string #2>
description: Defines the entities that are used as the weapon when it is dropped by the owner entity. Used in weapon definition
scripts (see: WEAPON).
syntax: <int> player's equivalent weapon slot ; <string #1> entity dropped when player doesn't have the weapon yet ;
<string #2> entity dropped when the player already has the weapon
notes: Entities must have been defined before they can be assigned into a weapon. Use “NONE NONE” as entity strings
to clear whatever items were defined earlier (this is mainly for use with weapon clones, see: CLONE). Checks about
whether player has the weapon or not refer to the weapon slot defined with 'player equivalent slot'; This way you
can create custom AI variants of weapons and still drop them for player to pick.

Scripting commands
ENTITY_SET <string> <int #1> <int #2> <int #3> <bool> <int #4>
description: Adds a new entity into a desired location.
syntax: <string> entity name ; <int #1> entity x coordinates ; <int #2> entity y coordinates ; <int #3> entity facing or angle ;
<bool> activity state (0 = active ; 1 = inactive) ; <int #4> trigger index (0 = no trigger linked)
notes: In case of AI_AIM entity facing is actually the default aiming angle in integer degrees, otherwise it's boolean
representing left/right). In case of player character, setting entity inactive makes it “teleport in” - or come through a
portal if player is inside one - in the beginning of the level and/or sequence. If trigger index is defined, the
corresponding trigger is fired when entity is killed or picked up. Player entities can't be linked to triggers.

LAYER <int #1> <int #2> <int #3> <int #4> <string> <int #5>
description: Adds a image layer that can be used as parallax background, static image or even sprite. Used in level and
sequence scripts.
syntax: <int #1> scrolling speed multiplier ; <int #2> layer y-axis offset from the top of the screen ; <int #3> x-wise
movement speed ; <int #4> y-wise movement speed ; <string> texture filename <int #5> in-game rendering flag
notes: Use status variable FX_LAYER_SPRITE to use specific image layer as a sprite (see: STAT). Use movement speed
0 for still images. In case of sequence script the scrolling speed multiplier works as a x-axis offset. Sequence
images are manipulated with SEQFLAGs (see: SEQFLAG). Use 32 bit parallaxes only when absolutely necessary –
large ones are major slowdown on older video cards with poor fill rate.

[ 76 / 90 ]
LAYER <int #1> <int #2> <int #3> <int #4> <string> <int #5>

Alternatively you can use formats other than TGA with PICTURE command (see: PICTURE), though thanks to
longer longer and initialization times using it is only recommended for non-in-game content such as extras and
intermission screens

LINEDEF <int #1> <int #2> <int #3> <int #4> <bool> <string>
description: Stands for “line definition” and adds a new geometry line into the map.
syntax: <int #1> starting point x coordinate ; <int #2> starting point y coordinate ; <int #3> ending point x coordinate ; <int
#4> ending point y coordinate ; <int #5> ceiling flag; <string> floor style
notes: Linedefs are used as floors, ceilings and walls for physics calculations. Style flag defines the linedef facing (0 = floor
or facing left ; 1 = ceiling or facing right). Incorrect face may result incorrect entity movement and awkward collision
events. Floors style defines linedef's appearance and behavior when being shot at (see: FLOOR).

LINK <int> <string>
description: Adds a multitap link. Used in level multitaps (see: MULTITAP).
syntax: <int> target index ; <string> link class
notes: Link class LNK_NONE is disabled from multitaps as a complete waste-of-space. Possible link classes are
LNK_ENTITY (entity link) and LNK_TRIGGER (trigger link). For safety reasons multitaps cannot be linked to other
multitaps by class LNK_MTAP, like triggers.

MESSAGE
description: Starts parsing info message.
syntax: –
notes: Keeps parsing message lines until message is closed (see: END). Messages are referred to by trigger “dialogue”
(see: TRIGGER, dialogue).

MESSAGE_LINE <string>
description: Adds a line into current message. Used in message scripts (see: MESSAGE).
syntax: <string> message line
notes: –

MULTITAP
description: Starts parsing multitap controller.
syntax: –
notes: Keeps parsing multitap links (see: LINK) until the device is closed (see: END).

PICTURE <int #1> <int #2> <string>
description: Creates an image layer, only from a non-TGA picture. Used in sequence scripts.
syntax: <int #1> x-offset ; <int #2> y-offset ; <string> texture file name (complete with file type suffix)
notes: This is essentially a simplified, stripped-down version of the TGA layers (see: LAYER), but using any file format
supported by Windows (JPEG, GIF, PNG, BMP). Once loaded, the layer can be manipulated in the same way as
the standard layers (see: SEQFLAG, FX_LAYER_SPRITE of STAT).

Using PICTURE is only recommended for very specific sequences (i.e. extras), since throwing image loading for
Windows and post-converting them for OpenGL is actually slower than TAGAP's own TGA loader – double so when
initializing the IPicture loader for the first time. So, in non-programmer's terms; Use LAYER if you want to minimize
load times and use PICTURE for non-time-sensitive, potentially JPEG-compressed content.

POLYGON <string> <int> <bool #1> <bool #2> <byte> <bool #3>
description: Starts parsing a polygonal texture shape.
syntax: <string> texture name ; <int> polygon point used as the texture offset ; <bool #1> texture shading (on/off) ; <bool
#2> texture alignment (on/off) ; <byte> texture tag (off/texture/overlay) ; <bool #3> horizontal texture flip flag

[ 77 / 90 ]
POLYGON <string> <int> <bool #1> <bool #2> <byte> <bool #3>
notes: Keeps parsing polygonal shape until the shape is closed (see: POLYPOINT, END). The order of polygons in the
script equals to the order they are drawn to the world. Texture tag is used to mark those textures that are
manipulated by textag triggers (see: Using Triggers: textag, TRIGGER).

POLYPOINT <float #1> <float #2>
description: Adds a new point to the current texture polygon. Used in polygons (see: POLYGON).
syntax: <float #1> point x coordinate ; <float #2> point y coordinate
notes: Polygon must have at least three points to be valid.

SEQCOOP <bool>
description: Forces the script parser to ignore the next line in the script if the player count doesn't match the required game
mode. Used in sequence scripts.
syntax: <bool> required game mode for the next line (1=coop ; 0=single player).
notes: Instead of being forced to create alternate intermission and cutscene sequences for both single player and co-op,
you can use SEQCOOP to modify alter the scripting depending on the game mode. The best way to explain the
usage is via an example;

SEQCOOP 1
SEQUENCE TIMER 1000 SEQ coop_intermission
SEQCOOP 0
SEQUENCE TIMER 1000 SEQ intermission

The example above will load sequence “intermission” after 1 second if you are in a single player and
“coop_intermission” if you are in cooperative. Note that this isn't like if-state of C-programming, instead only
affecting the next line in the script.

SEQCUT <int #1> <int #2> <int #3>
description: Sequence camera position and zoom cut; Keeps parsing attributes for the camera until it's wrapped up with END.
Used in sequence scripts.
syntax: <int #1> camera position (x); <int #2> camera position (y); <int #3> time the cut is initiated (in milliseconds)
notes: Allows you to do cuts within the same sequence script without the need of loading a new one. To set the default
starting camera position, set the time of the cut to 0.

This function has become much more prominent when compared to older TAGAP titles. Majority camera handling
has been moved SEQFLAG to SEQCUT, streamlining the entire process significantly.

Trickiest of these commands to get the hang of might be TRACK, the object tracking camera. It is used to focus the
camera on moving objects (in example, Pablo zooming ahead in a tram tunnel). To set it up, create a trigger (like
always, see: Using triggers: always) that is linked to the object you want to track. Then simply give the cut 'TRACK
<index of the trigger>' and the engine will do the rest. Note that when tracking is used, the cut camera position
refers to offsets from the entity's origin as opposed to absolute coordinates.

Camera variables:
BLOOM <int> <int> = Camera bloom effect (<bloom value from -100 to 100> <bloom transition speed>); Use speed 0 for
instant bloom style change.
FOCUS <int> <int> = Camera focus (<focus from -200 to 200> <focus speed>); Use speed 0 for instant focus change
MOVE <int> = Speed of the camera when it moves to the new position (if no move is defined, the cut is instant)
MOVE_ZOOM <bool> = Ties camera movement speed to the zoom level – making zooming in/out far while moving the
camera a smoother (toggle).
QUAKE <int> = Camera shaking multiplier (in per cents); Useful for, say, lessening the shaking for close-ups – or
disabling the sake altogether between cuts (use value -100 for this).
TRACK <int> = Object-tracking camera which refers to a trigger index; Cut coordinates are used as offsets from the
entity origin as opposed to absolute coordinates.
TRIGGER <int> = Trigger that is toggled upon a cut (value is the index of the trigger); Very useful for cutting between
scenes using different themes (see: Using triggers: theme) when use of local themes isn't an option.
ZOOM <int> <int> = Zoom with linear zoom speed (<zoom in per cents> <zoom speed>); Use speed 0 for instant zoom
ZOOM_EXP <int> <int> = Zoom with exponential zoom speed (input is the same as with ZOOM)

SEQCVAR <string #1> <string #2> <int>
description: Replaces an previously defined sequence item (see: SEQUENCE) if the specified CVar (see: Editing Variables,
CVAR). Used in sequence scripts.
syntax: <string #1> the CVar to refer to ; <string #2> replacement string ; <int> item layer
notes: This command always alters the previous defined item in the specified layer. If the item is altered, it is always
changed into TEXT_WHITE_DIM (see: notes of SEQUENCE).

[ 78 / 90 ]
SEQFLAG <int> <string> <float #1> <float #2> <float #3> <float #4>
description: Adds sequence image layer rendering flag. Used in sequence scripts.
syntax: <int> index of affected image ; <string> flag id ; <float #1> amount ; <float #2> transformation time ; <float #3>
transformation delay ; <float #4> start value
notes: Used to animate sequence images (see: LAYER, PICTURE). Index is the layer to be affected (use negative index -1
to manipulate global flags). Transformation time is the time it takes for the transformation to complete (i.e. how long
it takes for the image to move from one position to another). Transformation delay is well, the delay for the
transformation. Start value is a starting point for the transformation, (i.e. setting starting value of ANGLE to 45
means the image starts rotation from 45 degree angle). Note that you can reverse the effects by setting
transformation time to negative.

Creating picture box BUTTON requires two images (normal and mouse hover version). Sequence flags are private
for each sequence script, so when keeping images in memory during multiple sequences (see: “noreload” in Editing
Variables, CVAR), they can be manipulated independently on each frame.

Note that unlike in previous TAGAP titles, in TAGAP 3 majority of camera operations (movement, positioning,
zooms, etc.) are no longer handled with SEQFLAG, but with the streamlined SEQCUT. There are still a couple of
SEQFLAGS that can be set to affect the scene (like FADE), but everything else is handled with cuts.

Possible global flag ids:
ACID = acid trip overlay bloom
FADE = fade-to-and-from-black
GLARE = fade-to-and-from white

Possible layer flag ids:

ALPHA = transparency controls ( 0 = invisible, 1 = fully visible)
ANGLE = angle of the image (in degrees)
BUTTON = transforms GUI item into button (offset is image state 1 or 2, amount is GUI item index)
FRONT = level on which layer is rendered (from -1 = behind the scene to 4 = over everything in scene)
ENERGY = adds energy effects to image similar to sprites (see: SPRITEVAR)
HARDLIGHT = hard light rendering
MOVEX / MOVEY = image movement
RELOCATE = relocates layer image that has been loaded in previous sequence
SCALE = scale of the image (as multiplier)

SEQSELECT <int>
description: Automatically selects a dynamic item (see: SEQUENCE) other the default when entering a sequence script. Used in
sequence scripts.
syntax: <int> index of the item to be selected
notes: This feature is ignored if the cursor – real or virtual – is already over an item when entering the sequence.

SEQSOUND <int #1> <int #2>
description: Defines a sound to be played for sequence button item.
syntax: <int #1> button item index ; <int #2> sound index
notes: Sound will be played when active button item is used. Basic user interface sounds are indexed from 0 to 6. Only
sounds defined in-engine can be used (user-defined in-game samples aren't available).

SEQUENCE <string #1> <int #1 / float> <int #2 / string #2> <string #3> <int #3> <string #4>
description: General sequence scripting command with two different possible syntaxes. Used in sequence scripts.
syntax: <string #1> command id ; <int #1> x-wise offset ; <float> timer time (in milliseconds) ; <int #2> y-wise offset ; <string
#2> timer command id ; <string #3> output text string / timer command string value <int #3> item layer (non-timer) ;
<string #4> hyperlink (non-timer)
notes: Possible timer commands are MAP (go to the next map) and SEQ (activate another sequence). Use “TIMER”
command id to activate timer parsing. See LAYER and PICTURE for sequence image handling. Item layer 0 means
it will be drawn into sequence itself and it is affected by all fade and glare effects. Layer 1 is for active items, which
are never faded or glared. Remember to define a hyperlink even for non-hyperlinks to avoid parser errors (use “_”).
For text items use negative layer value for alternate alignment (-1 = left, -2 = center, -3 = front center). To use GUI
strings with hover help, use output text (see: GUISTR). Possible command ids:
COUNTER = a simple time counter that keeps track of time passage until the maximum value is reached
HEADER = large header with a scrolling background; If you set the y-axis offset as 0, the header will be automatically
aligned to the top edge of the screen.
MAP = go to the next map
NEWGAME = start a new game

[ 79 / 90 ]
SEQUENCE <string #1> <int #1 / float> <int #2 / string #2> <string #3> <int #3> <string #4>
NOITEMS = disables all interactive items until the timer has run out (timer only)
RESTART = restart from beginning of the previous level
SAVE = brings up the save game list for saving
SCORE = prints the current contents of a Cvar (use hyperlink value)
SEQ = activate another sequence
STOPSOUND = stops all sound effects (timer only)
STOPSTREAM = stops audio stream nut music and effects will continue (timer only)
TEXT = bright text string
TEXT_DIM = darkened text string
TEXT_LARGE = large, bright text string
TEXT_LARGE_DIM = large, darkened text string
TEXT_WHITE = white, null text string
TEXT_WHITE_DIM = darkened white text string
TIMER = sets a timer
TRIGGER = fires a trigger (defined as an index number as hyperlink)

SEQTIMER <int> <float>
description: Sequence trigger timer. Used in sequence scripts.
syntax: <int> index pointer of the trigger to be fired ; <float> time to firing the trigger (in seconds)
notes: Each timer will fire only once.

TRIGGER <int #1> <int #2> <int #3> <int #4> <int #5> <string #1> <string #2> <string #3> <int #6> <int #7>
description: Adds a trigger field.
syntax: <int #1> top-left x coordinate ; <int #2> top-left y coordinate ; <int #3> bottom-right x coordinate ; <int #4> bottom-
right y coordinate ; <int #5> target index reference or modifier value ; <string #1> trigger name ; <string #2> trigger
string ; <string #3> link class ; <int #6-7> additional variable value
notes: Triggers with other field names will be ignored. Field must have both height and width to become valid. Triggers can
be linked to entities, usable trigger fields and multitaps. To learn more about triggers and to view all possible trigger
names, see: Creating Levels: Triggers and Using Triggers. Possible link classes:
LNK_ENTITY = entity link
LNK_MTAP = multitap link
LNK_TRIGGER = trigger link
NONE = no link

[ 80 / 90 ]
Appendix C: Configuration variables
Configuration variables (commonly referred to as “Cvars”, see: CVAR) are what the name
suggests; global variables registered to the engine and used to setup and adjust both system and
the game. You can go and tweak these from within the script-, level-, and configuration files
manually.

Setup variables
input_autoswitch Toggles automatic switching into new weapons (1=on, default ; 0=off). Stored in configuration file.
input_gamepad Switches controls between standard keyboard/mouse setting and gamepad controller
(1=gamepad ; 0=keyboard/mouse, default). This applies to player #1 only – player #2 will always
use gamepad.
input_keyleft, In-game keyboard configurations. Values refer to DirectInput keyboard constants. Stored in
input_keyright, configuration file.
input_keydown,
input_keyload,
input_keyjump,
input_keynext,
input_keygren,
input_keyprev,
input_keypeek
input_mousespeed Mouse speed modifier as a byte. Stored in configuration file.
input_mousesens Mouse wheel sensitivity modifier, as a byte. Stored in configuration file.
input_peak Switches peaking mode between toggle and hold (1=toggle ; 0=hold). Stored in configuration file.
nosound Disable all sounds (1=disable sounds). Ignores completely the sound calls so the game can be
run even without sound card, like on workstation computer. Command line only.
safemode Use value 1 to revert all game settings to defaults. Command line only.
snd_dsound Toggles DirectSound driver for sound (1=on, default ; 0=off). When DirectSound is turned off
Windows Multimedia driver will be used instead. Though DirectSound is generally faster and has
better compatibility, some older soundcards may have incompatible drivers, resulting stuttering
playback. If so, use Windows Multimedia drivers instead. Stored in configuration file.
snd_musicvol, Sound effects and music volumes in bytes (0–255).
snd_soundvol
snd_voiceover Toggles player voice over (1=on, default ; 0=off).
user_cheats Toggles ”Cheats” menu access on/off (1=on ; 0=off). Command line only. Game can't be saved
and achievements can't be unlocked while cheat mode is on.
user_hijack Permanently hijacks another user name to be associated with the current Windows log-in name.
All configurations, achievements and saved games are stored according to user name, so after
changing user name you'll need to use this variable. Note that all progress made under current
Windows log-in name will be lost during an account hijack. To use another account on per-
session basis without removing current progress, use “user_name” override. Command line only.
user_maxhud Toggles between “Contextual” (0) and “Full” (1) heads-up displays.
user_name Overrides user name. User name is by default the same as user's Windows log-in name (with
caps replaced with “_”). The override user name is used for that session only; To permanently
hijack an account use variable "user_hijack”. Command line only.
vid_aspect Defines the aspect ratio of the screen (0=4:3 ; 1=16:9 ; 2=16:10). Aspect ratio should match the
resolution provided by vid_width and vid_height, otherwise the image isn't up-scaled properly.
vid_fullscreen Toggles the screen mode:
0 = standard window
1 = full screen
2 = borderless window
You can get the full screen experience either with full screen or using a borderless window
together with 'Use desktop resolution'.
vid_maxfps Maximum refresh rate for the game. To avoid excessive screen tearing, it's best not to use a
maximum frame rate higher than your screen refresh rate. Also note that higher the maximum
frame rate, the harder your computer has to work for it – which leads to heavy CPU and GPU
usage and, in case of laptops, heavy battery drain.

Performance wise, if your system can't handle 60 FPS, it might be better to use 30 FPS instead.
While it doesn't sound like it, the game will actually seem smoother since the frame rate doesn't

[ 81 / 90 ]
take a nose-dive when the action gets hectic.

Note that there are scenarios where changing the maximum refresh rate doesn't apply. There are
two reasons for this. Firstly, there's vertical sync (see: vid_vsync below) that, depending on your
system, can lock the refresh rate to that of your monitor regardless of your chosen settings. Also,
in case of some video cards, Windows control panel settings may be set to override the software
settings, including refresh rate and the afore-mentioned vertical sync.
vid_noflush For streaming and video capture purposes, this command disables OpenGL flushing (0=off,
defualt ; 1=on).. In layman's terms; when the engine flushes the scene, it overrides the rendering
order of the driver and ensures everything rendered until that point, is processed before
processing continues. Whilst this ensures the unconventional 3D-for-2D engine is rendered
properly regardless of the hardware, it can interfere with some video capture and streaming
programs.

So, this essentially trades video capture compatibility for potential minor rendering glitches (like
minor object flickering) on some hardware combinations. So, unless you are streaming or
recording gameplay AND you are having technical issues (i.e. crashes), you don't need this
option. This is the same as 'Stream Safe Mode' shortcut created on installation. Command line
only.
vid_postprocess Toggles scene post-processing warping effects (water waving, real-time blurs, etc.) (1=on in
single player, off in splitscreen ; 2=always on ; 0=off). Turning post-processing off improves
performance significantly on slower systems and integrated graphics cards.

For those coming from old TAGAP modding, this variable used to be called 'vid_warp', but there
are now plenty of other post-processing tricks going on than just water distortions, hence the
name change.
vid_width, vid_height Obviously the screen dimensions, or in case of windowed more, the window size. If you edit
these variables from within the configuration file, also remember to set the proper aspect ratio
with “vid_aspect”.

Note that while the first two TAGAP games were rendered natively in 800ˣ600 and stretched to fit
the screen, TAGAP 3 renders everything as-is; Higher the resolutions, more detail you'll get out of
it but it'll also require more horsepower. For the best results, use the native resolution of your
display.
vid_vsync Toggles screen vertical sync (1=on ; 0=off). Using vertical sync prevents screen tearing, but can
cause slight performance dibs on more obsolete video cards. Take note that your Windows
control panel settings may be set to override the settings of the applications.

TAGAP 3 also supports adaptive vertical sync for improved syncing. The availability of adaptive
vertical sync is detected automatically – if your video card supports it, it will be used.
whitebox Toggles white box fix (1=on ; 0=off, default). The hardware support for the extension
GL_ARB_texture_rectangle is checked automatically, but if the support test for some reason
returns a false positive, you can override it with this command. Command line only.

Editing variables
map_backitems Normally all text items (see: SEQUENCE) are rendered on top of everything else, including those
in so called 'inactive items' layer. This means they aren't affected by cuts or pans (see: SEQCUT,
SEQFLAG). Turning “map_backitems” on (1=on ; 0=off, default) renders the items into the scene
itself instead, allowing you to do things like, say, the scrolling end credits or multiple title cards in
one sequence. This value reverts to default for every sequence script.
map_cannonfodder Defines cannon fodder to summon (see: CANNONFODDER).
map_customents Defines the set of custom entities used for run-time entity generation – called-in reinforcements,
spawned rewards, extra lives and the like (see: CUSTOMENTS for more details on custom entity
lists).
map_fodderopt1, Optional fodder entities used to spice up basic cannon fodder. Variables “map_fodderopt1” and
map_fodderopt2, “map_fodderopt2” are the basic 'tool' fodder, while “map_fodderopt3” is referred to as 'power tool'
map_fodderopt3 fodder. You can also choose not to use optional fodder by setting the variable to “NONE”. Used in
level scripts.
map_fodderrain Toggles fodders falling from the sky (1=on ; 2=sides and sky ; 3=restricted version of standard
rain, for specific co-op situations calling for it ; 0=off).
map_fodderspeed Defines cannon fodder speed ranging from 1 to 20.
map_guide Defines the parallax guide plane y-coordinate (0=default). To simply sum it up, the guide defines
the y-offset below which the layers rendered as parallax background (see: LAYER) no longer
follow the camera movement.
map_background Defines how the layers are rendered as the level background;
0 = interior backgrounds (no layers)

[ 82 / 90 ]
1 = vortex parallax backgrounds
2 = standard parallax backgrounds

map_nodeathrun For measuring no-death-runs (used in sequence scripts). Input values;
0 = default (no change)
-1 = reset and start a new run (called in the episode intro sequence)
-2 = unceremonious stop to the run (with no rewards given)
1 and above = run is considered a success (called in episode ending sequence)

map_nextmap File name of the next map loaded when the level is completed. When used from command line
the “next map” is loaded on start-up – use this to load custom levels.
map_progress Progress marker gained from completing the level, in capital letters A-Z. An example; Player with
progress of “ABCD” completes a level with a marker “E”. After this player's progress is “ABCDE”.
For more information on progress and how it relates to creating levels, see: Using Triggers: state.
map_nosave Toggles possibility to save on/off (1=on ; 0=off). Designed for use in sequence scripts only, but
works in-game, too.
map_recallreq Progress markers required in order to access the hub recall feature (PTB). For example, if the
requirement string reads “AB”, player needs to have markers “A” and “B” before he/she/it can use
the recall feature in the current map.
map_scheme Defines the default environmental theme of the level.
map_sequence File name of the sequence loaded when the level is completed or proper sequence event is
initiated. Use name “none” if you want to load the next level straight on exit. When used from
command line the sequence is loaded on start-up.
map_title Title of the level. Mainly used in level scripts. Title “Untitled” won’t be printed on loading a level.
map_visexpand Expands the area of a single visibility data slice for the current sequence. By default, this is
turned off (value '0').

In order to understand anything that means, you need to understand how the engine works. In
layman's terms; In order to optimise rendering, upon loading a level or sequence, the map
information is split into slices of visibility information. In other words, it tells the renderer 'if player
stands at this spot, what should be try to render'. By default, the visibility data system assumes
that the camera doesn't zoom out further than '100%'. If you want the camera to pull back further
(say, 50%), you can see the scenery literary cut out before the edges of the screen.

This is where this command comes in; Say you have a sequence that has a cut that zooms far
back to 50% (see: ZOOM of SEQCUT). In order to avoid the scenery being cut off prematurely,
set “map_visexpand” to '50'.

Used in sequence scripts.
noreload Prevents dynamically loaded graphics data from being flushed between sequences (1=for loader
script; 2=rest of the scripts in the sequence chain; 0=off, default). If you want your sequence to
be timed perfectly and synced with streams without falling behind on slower machines, use this.
When turned on, it affects the next sequence swap and is reverted off again; You must define it
for each sequence script independently.
snd_noloop When toggled (1=on ; 0=off, default) the in-song loop points are ignored and the song is looped
from the beginning to the end. Used only in sequence scripts, this value is reset back to “off” on
every level and sequence load.
snd_pausesong When toggled (1=on ; 0=off, default) pausing the game or using the menu won't pause the music;
Comes handy in sequences featuring cinematic score. This variable is reset back to “off” on every
level and sequence load.
snd_song File name of the default song to be streamed. Use name ”off” for no default music. When the
music resumes, like after a boss fight, this is the song that'll be played.
snd_stream File name of the sequence audio to be streamed. This variable is turned to ”off” before loading a
sequence, so to continue streaming current audio, you'll have to define the same stream for the
follow sequence, too. Usable only in sequence scripts.
user_bbox Toggles entity bounding box display on/off (1=on ; 0=off). Ideal for testing collisions and offsets.
Only in developer mode.
user_color_gui_r/g/b, Text color definitions in RGB bytes. Used in game definition script.
user_color_text_r/g/b
user_developer Toggles developer mode on with value 1. Command line only. When toggled on you can access
the level editor through the main menu and in-game editor shortcuts are enabled. Game can't be
saved and achievements can't be unlocked while developer mode is on.
user_fps Toggles frames-per-second display (1=on). Amount of rendered frames-per-second will be shown
at the top-right corner of the screen. Only in developer mode.
user_game Defines the game mod to be loaded. Command line only. Mods are loaded from ”mods” directory.
user_grenade1, Defines the entities used as off-hand items (i.e. grenades). In the past TAGAP Engines the

[ 83 / 90 ]
user_grenade2, grenade thrown was defined by entity missile, but since there now are multiple off-hand items to
user_grenade3, use, they are now defined in this manner. Used in game definition script.
user_grenade4
user_log Toggles detailed developer log output on/off (1=detailed ; 0=basic, default). While basic mode
reports only the main engine events (initialization calls, errors occurred, etc.) the detailed mode
also reports most file events. Detailed mode is mainly intended for bug-hunting and development.
user_map_hub File name definition of the map that is loaded when the player presses the hub recall button
(PTB). Used in game definition script.
user_map_start File name definition of the map that is loaded when a new game is started. Used in game
definition script.
user_mapdir Defines the level directory for mod (default is ”data/script/maps”). This way you can make mods
that can be used in TAGAP's original maps. Used in game definition script.
user_player Name of the entity that holds all the default values for player characters (default is “player”). Used
in game definition script.
user_promo Enables promo screen capture mode on/off (1=disable GUIs ; 2=disable player and AI ; 0=off).
When toggled on, no status display, messages or player effects will be drawn, making it easier to
take environmental screenshots or capture demo reel video. Command line only.
user_seq_start File name definition of the sequence automatically loaded on start-up. Note that variables
“user_seq_gameover” and “user_seq_newgame” used in the first TAGAP no longer exist; Level
intro sequences are loaded automatically if they exist and 'game over' is loaded based whether
the game is co-op or not. Used in game definition script.
user_sfx_master Master volume for sound effects in percents (default is 75). Use this to tune the default balance of
music and sound effects according to what kind of custom music you are using. Used in game
definition script.
user_soundcpu Toggles sound engine's CPU usage display (1=on). This variable was meant for system testing
and debugging during the engine development, but it also works fine to determine possible
glitches created by sound overflows. Only in developer mode.
user_startsave Toggles whether or not the current level will be saved automatically when you launch it from the
editor. Saved in configuration file.
user_tex_base Filename of the texture definitions for base textures used by editor and rendering engine. Used in
game definition script.
user_vo1, user_vo2 Voiceovers (see: VOICEOVER) played when trying to open a lock without a key. First one is used
for player #1 and the second for player #2. Used in game definition script.

[ 84 / 90 ]
Appendix D: Essential Software
Retail software
Let's face it; You'll need to buy some software if you want to get your game done. It's simply an
undeniable fact that some software suites, like Adobe Photoshop or Cakewalk Sonar, have been
tuned to tiniest detail in terms of user interface, compatibility and efficiency. Though they cost a lot
of money, they'll eventually pay themselves up in speed and reliability.

All software listed here just happened to be the ones we were using. The companies behind these
programs are not condoning or supporting Penguin DT or TAGAP in any way, shape or form. We
just want to give a shout out to all these utilities with which we created TAGAP 3.

Adobe Photoshop CS3
The one and only graphics software and the best 800€ I've ever spent.
Unequalled on every level, Adobe Photoshop has been created to answer all
the needs of 2D artist of both pro and amateurs alike. You might need
Photoshop 7.0 legacy file plug-ins for best Targa TGA handling, though. Note
that Photoshop CS series is not to be confused with Adobe Photoshop
www.adobe.com/photoshop Elements line-up, which is budget solution for photo processing and can't be
used to create CGI from scratch.

I also use Photoshop CS6 occasionally. Whilst it's sturdier and has more
helpful tools – the content-aware fill is pure magic, I tell you – but since it is no
longer compatible with work-flow easing legacy file format plug-ins, I mainline
with CS3 still.

Photoshop CS series is no more, sadly; All that remains is the online-
connected Creative Cloud – or CC – family of products. This is one of those
subscription based systems that I'm not willing to endorse, especially after
spending over 1000€ in the said software family already. That said, Photoshop
CC is still the same solid beast underneath and it's what Petja uses for his
digital paintings.

Microsoft Visual Studio 2008 Standard Edition
Let's face it; Microsoft Visual Studio is the number one of the programming tools. While
the base of the engine – the original TAGAP – was all coded with the free Express
Edition, we've since moved to commercial Standard Edition. This was for several
reasons, but in the end it's one of those rare programs I have nothing bad to say about,
so in the end it was money well spent.
msdn.microsoft.com
If you are not ready to dish out a couple of hundred credits for the
programming tools, remember that Microsoft offers the free Express Editions of
the whole Visual Studio package. For more information on those, check out the
Free software section.

Some may be wonder, 'why are they using almost a decade old version of
Visual Studio?'. Well, the answer to this is simple; When I started looking into
upgrades, to my horror I realised that Microsoft, too, has moved to online-
connected subscription model with all of their software. And hey, using Visual
Studio 2008 means TAGAP 3 should be Windows XP compatible, in case you
are still using that for your retro gaming.

[ 85 / 90 ]
Cakewalk Sonar
Cakewalk Sonar is what Petja uses to create the great TAGAP soundtracks.
Sonar is a complete package that has pretty much everything you could
possibly need, all the way from composing to production, mastering and even
web publishing. And in case it doesn't have a particular feature, it sure as heck
will be available as a plug-in or a virtual instrument.
www.cakewalk.com
Not only did Petja use Sonar for the music, but we also recorded our penguin
voices with it. With its ease of use and multitrack recording capabilities, we
didn't have to spend any time worrying how to set things up.

Also worth noting is that, unlike with most programs, buying a lower end
version and gradually upgrading to more pro-ones is actually financially sane;
Petja started with Home Studio back in the days of the first TAGAP and has
since gradually upgraded to his Platinum.

Sony/MAGIX Sound Forge Pro 11
For TAGAP 3, one my biggest investments was an audio waveform editing
suite that could speed up the bigger scale audio mixing the game required and
come with enough editing proves to enhance the experience for the end user.
After months of going through different sound editing tools, I ended up
selecting Sound Forge Pro 11.
www.magix.com/int/sound-
forge/ Whilst most of the actions of Sound Forge can be done with Audacity, here
they are ready out of the box and with more user-friendly interface. It's a bit like
going to Photoshop after working with GIMP; you may have not known the
difference before the change, but you for sure notice it afterwards.

Only reason I can't recommend Sound Forge Pro without hesitation is that I
honestly don't know what the fate of the software suite is. About a month after I
purchasing my license, Sony sold most of their software development, brands
and assets – and Sound Forge family ended up with MAGIX. Whilst the Sound
Forge Audio Studio – the 'lite version' of the software – is still being developed,
at least for now MAGIX seems to have left the Pro version 'as-is'. Which is a
shame; I've tried dozens of suites like this and Sound Forge Pro is easily my
favourite. A stability/compatibility tweak or two, and it would be perfect.

Filter Forge
Filter Forge is both a stand-alone program and Photoshop plug-in designed to
apply customizable filters on an image, in effect either editing the source or
creating brand new patterns and textures from scratch. The program is so fast
and easy to use I curse myself for not discovering this until late 2010.

www.filterforge.com Whether you want to create a basis for a texture or add a specific kind of detail
filter onto an existing one, Filter Forge is your tool. In fact, I'd go as far as to
say that most of the textures seen in TAGAP 3 has gone through Filter Forge at
some point.

[ 86 / 90 ]
Fraps
The trusty tool we used to record our very first trailers with, beepa's Fraps has
been hard at work for TAGAP 3. Not only are all of our videos captured with it,
we also used it to capture the action shots and recap scenes by recording
them as video and using Premiere to save the best screens as pictures. At its
low price it's almost a steal, especially considering how it also works as a
www.fraps.com benchmarking gadget.

Only downside to Fraps is that it's a super-resource-hog. Since the video it
captures is almost uncompressed in order to preserve the image quality, this
means the files it records are kaiju-sized, especially in 1080p60. Not only does
this mean you'll need a LOT of hard disk space, that disk also has to be a darn
fast SSD in order to keep up with all the data dumped on it in real-time.

Adobe Premiere Elements
Very likely the best non-linear video editing software around. Unlike with
Adobe's Photoshop, in case of Premiere I found Elements version better than
the full product; While it lacks some of the cooler effects and alike, Elements is
slicker and faster. Basically if your raw material is good and you don't need to
add special effects galore, you won't need anything more complex. Besides,
www.adobe.com/products/pre costing around 80€ it won't bankrupt you either.
miere-elements.html
One of the few programs I upgraded specifically for TAGAP 3 development
was Premiere Elements; whilst his original 3.0 was still perfectly fine for editing
and worked properly under modern operating systems, it didn't support
1080p60 output – the standard for video game footage these days. So, simply
for sake of having 60 FPS trailers, I now use 13 – though as of writing this
manual, Elements has already reached version 15.

Free software
These days it's common belief that game development is too expensive for hobbyists unless you
do warez. Wrong! It's relatively cheap, as there are many freeware and/or open source tools out
there. Here are the of most useful freeware programs Penguin DT used to craft TAGAP 3.

Audacity
Free, cross-platform sound editor that, feature wise, can stand neck-to-neck to
its commercial competitors, featuring much-needed options like multi-track
editing and project workspace feature. You can do a lot with it out-of-the-zip,
but the ability to customize it with all the available plug-ins ensures only your
imagination is the limit.
audacity.sourceforge.net
Though I no longer use Audacity as my main audio suite (see Sound Forge Pro
above), I still clean up our audio recordings with its great noise remover. Also
remember that all the sound effect mixing for the first two TAGAP games done
using Audacity.

[ 87 / 90 ]
FMOD
While FMOD is more middleware than a development utility, it just has to be
mentioned. FMOD is the sound engine that, well, handles all sounds in TAGAP.
The brilliance of FMOD lays in its flexibility and ease of use; it's super simple to
set up and once you do, you can do anything from playing mono samples to
having complex 3D audio soundscapes and streams.
www.fmod.com
The previous two TAGAPs used the older FMOD Ex system, which was free to
use for non-commercial projects. TAGAP 3, however, uses the new FMOD,
which comes with a new indie license similar to what you see with Unity. You
may have not realised this, but FMOD can be heard in many super-heavy-hitter
titles – like World of WarCraft, Crysis series and BioShock, to name a couple.

GIMP: GNU Image Manipulation Program
Though Adobe Photoshop is the undeniable king of 2D graphics software,
GIMP is an excellent freeware contender. In terms of TAGAP, it has proven
itself handy in several graphics tasks, like in creating texture patterns. It's
available for every platform under the sun and is very flexible. That said, its
user interface is about as far from intuitive as it can get, which can be an
www.gimp.org impassable obstacle for many – especially if they are already used to
Photoshop.

jEdit: Programmer's Text Editor
Life-saver tool and like the name says, designed for programming. It
recognizes most programming language syntaxes and it's quit fast. But the
best part is its find-and-replace capability; just type in the changes and it does
it all for you, even in thousands of files. Though I like standard Notepad-like
software better, all large-scale script updating, website layout changes and
www.jedit.org database tweaks were done with jEdit. It requires Java 2 virtual machine to
operate.

LibreOffice
Open source alternative and replacement for Microsoft's Office suite. Though
LibreOffice Writer requires more orientation than Word, it's more powerful,
supports more formats and can produce fluent .pdf and .html files with a single
click of a button. Writer was used to create all the documentation of TAGAP 3,
including the handbook you are just reading.
www.libreoffice.org
In case you were wondering, 'weren't you using OpenOffice before?'. Well, yes,
we did. However, the team behind OpenOffice split, with the core team
continuing as LibreOffice while OpenOffice went down its own path. I liked the
direction of LibreOffice more and went with that instead.

Microsoft Visual C++ Express Editions
Simply put; The “One-And-Only Programming Tool” as free lite version. Sure,
there are some features missing compared to retail editions, most importantly
resource editor, but nothing hobbyist can't live without and/or find a work-
around. While TAGAP 2 and TAGAP 3 was all programmed with the
commercial Visual Studio 2008 Standard Edition, the first game was all done
msdn.microsoft.com with Express Edition. So yes, Microsoft's freebie version of Visual Studio is
complete suite, for sure.

[ 88 / 90 ]
Mp3Tag: Universal Tag Editor
Every song in the game has loop points defining the looping segment in in-
game songs. Set up with custom tags LOOPSTART, LOOPEND and AUTO,
setting them up would be a lot more complicated without Mp3Tag. With it,
however, all you need to do is to add the custom tags to Mp3Tag layout, select
a song, type in the values and hit 'save'. And hey, it's brilliant in properly
www.mp3tag.de/en tagging and sorting out your music collection as well!

NSIS: Nullsoft Scriptable Install System
Open source install system that was used to create TAGAP, TAGAP 2 and
TAGAP 3 installers and updaters. It's from Nullsoft, developers of famous
WinAmp and it's widely used. Distributing your software in an installer package
makes things way more user-friendly and it speaks of something that NSIS has
been adopted by the likes of (pre-UPlay) Ubisoft, NCsoft and Google.
nsis.sourceforge.net

OggDrop
Another small utility that defines the phrase “less is more”. Just drag your
uncompressed audio files and drop 'em to OggDrop – and you have the entire
game soundtrack and/or sound effects archive encoded to OGG Vorbis format
in a matter of seconds. Why make it harder?

www.vorbis.com Also worth pointing is that unlike many 'mass converters', you can customise
the encoding settings to the tiniest degree, so you don't have to worry about
the output being randomly lossy or garbage. What you set it to do is what you
get.

Win32Pad
There are dozens of Notepad replacements out there, but I think this is the
best one. It features Infinite undo, unlimited file size, yet it's light-weight and
doesn't waste any extra memory. This gadget was used for both TAGAP_Script
creation and website composition (yes, I'm one those dozen people who still do
www.gena01.com/win32pad their websites with a text editor).

Appendix E: Glossary
While majority of TAGAP Engine functions are named according accepted game industry norms,
some labels used are a bit quirky, antiquated or just weird. Thus, new to TAGAP 3 version of this
document, comes the glossary.

bouncer – A type of linedef that only affects zombie cannon fodder.

cannon fodder – Cannon fodder is the nickname given to the randomly (by user defined rules)
generated enemies that keep spawning to the level from the edges of the screen.

cvar – Short for configuration variable – naming convention adopted from id Software's Quake
games. Cvars are global values that are used for storing player's chosen settings, global map data,
sequence script settings and the like. For full list of cvars, see Appendix C: Configuration variables.

entity – Almost all in-game objects, whether they are actors, effect generators, set pieces or just
window dressing, are built upon entity structure. To quote Wikipedia; “An entity is something that
exists by itself, although it need not be of material existence”. That pretty much sums it up; entity
can be anything or nothing, it all depends on what you need as a developer.

[ 89 / 90 ]
fodder – see: cannon fodder

limb – A limb in the skeletal animation system. Limbs can have up to three segments and they can
be animated either automatically by predetermined behaviour – or manually, segment by segment,
via pose scripts. For more information, see: Basics of Scripting: Skeletal limb system.

linedef – Physical vectors representing walls, floors and ceilings of the game world are called
linedefs, short for 'line definitions'. Term was adapted from the inner engine workings of DOOM by
id Software.

multitap – Basically a list of triggers that are to be executed at once. Most triggers that execute
something upon triggering can be linked to either an entity, another trigger or a multitap.
Understanding multitaps is quite essential for creating more complex scripted events. Named after
classic Nintendo peripheral that allowed single console to have more controllers plugged in – which
is kind of what multitap does in TAGAP.

pose – A script that has information for posing the limbs of an entity. For more information on, see:
Basics of Scripting: Skeletal limb system as well as the script syntaxes POSE and
POSE_ELEMENT.

sequence – All in-engine, not-in-game cut-scenes in TAGAP engine are called 'sequences' are
defined in sequence scripts. For more information on sequences, see: Basics of Scripting:
Sequences.

trigger – Triggers are customizable in-game areas that, like entities, can serve multiple purposes
and function in various ways. However, all triggers are rectangular fields. For more information on
triggers, see: Creating Levels: Triggers and Using Triggers.

zombie – The standard type of cannon fodder is zombie; a simple enemy that just walks forward
and attacks if the player happens to be in front of it or touches it. Also, unless set-up to behave
otherwise, zombies always turn away from walls and dropped nanoshields, adding a slight tactical
element into handling zombie hordes.

[ 90 / 90 ]