Script Trigger Functions - SWG-Source/swg-main GitHub Wiki
This document provides information on and example usage for script functions in the dsrc. It is written from the perspective that you are either (a) trying to determine what is evoking specific triggers and what they do or (b) writing a script and looking for programmatic examples of triggers. If that isn't you, this won't be the best resource unless you just like to learn.
- Introduction
- Before We Begin
- Script Functions for Scripts Themselves
- Script Functions for Players
- Script Functions for Objects
- Script Functions for Combat
- Instructions for Adding New Script Functions
Script functions are used in the SWG Code Base as a trigger to send information from the src
(engine) to the dsrc
(scripts) when specific actions occur. All script functions are defined in ScriptFunctionTable.cpp. We won't cover every script function here (there's more than 300) as some were developed for a singular use-case, however, most commonly used functions are explained to get you started.
Note: This document covers script functions only, which (excluding the return code) are one-way [src > dsrc]
. It is not documentation for all of the JNI calls that the dsrc
can execute to send commands back to the engine.
- Introduction to the SWG Server Environment
- The Game World and Universe: Constructing a Galaxy
- Scripting Overview
- Common Class Constructors (SRC/DSRC)
A couple of generally applicable notes for all triggers that add context now but will make more sense later:
IMPORTANT: Consistent with working on a code base whose development began in 1999 and ended in 2011, there are a number of "modern day" priniples you will be counciled against and some logic of these systems may not make sense. While several amazing contributors have helped modernize many components of this code base, archaic ideology and usage remains at its core. Thus, be sure to read this section beacuse there are a number of nuances that can leave you with broken code and hours of debugging for simple mistakes.
- All script functions are implemented in the dsrc as
public int
and mustthrows InterruptedException
. - The
src
listens for the a return code (int) inside each script function which use constants defined base_class.java that tell the engine how to proceed. Do not exit a script function with any other return statement.-
return SCRIPT_CONTINUE;
exits the method and continues (this is the method you will see and use 90% of the time). -
return SCRIPT_OVERRIDE;
exits the method and blocks the contemplated action (only applicable in certain scenarios). For example, if you return with SCRIPT_OVERRIDE in theOnAboutToBeTransferred
script function, it will block the transfer of the item, whereas SCRIPT_CONTINUE would allow it to move forward. Either one will exit the method. -
return SCRIPT_DEFAULT;
is deprecated and only used in conversation scripts.
-
- Different triggers pass different information, but the one constant will always be that the first parameter of any script function will be
obj_id self
so you have the network ID of the object the script is running on. And importantly, if you add a new script function, note that you do NOT need to include this as one of the parameters passed, it is included automatically. - Script functions are NOT static and shouldn't be declared as static (they won't work). If you have a block of code in a script function that you may need to execute or reach more than once, you should put it in a separate method and send a
messageTo
that method whenever you need to access it.messageTo
requires specific formatting and there are other considerations, see: LINK Methods for Object Communication, Time/Synchronization, and Loops (DSRC). - Remember that any script function will be run regardless of what script the function is in if that function is in a script attached to an object and that object receives the trigger. As noted in the overview of scripts, when a trigger is sent by the src, in almost all cases the script function is executed as a
trigAllScripts
on every script attached to that object. This makes sense, for instance, because if a player has theOnLogin
script function enumerated in two scripts attached to the player that handle separate things, like veteran rewards and PvP, both would need to update when the player logs in. In some rare circumstances, this can be problematic based on the use-case, in which case you may need to add a new script function that uses thetrigOneScript
approach instead. - A lot of script functions contain a parameter
dictionary params
(see class contructors) or other unused parameters which are routinely null (but may pass certain information as well, depending on the method or application). Importantly, though, script functions will not get executed if they are missing parameters, even if they won't be used. Always use the exact template and parameters as prescribed in ScriptFunctionTable.cpp, even if they aren't used.
public int OnAttach(obj_id self) throws InterruptedException { }
OnAttach is triggered when the script is attached to an object (see GameScriptEngine.cpp#229). This includes the following scenarios:
-
GameScriptObject::attachScript
is executed in the src -
attachScript(obj_id object, String script)
is executed in the dsrc -
/script attach <oid> <script>
is executed in-game
Tip: A general practice across the source is to replicate the code in OnAttach
also in OnInitialize
due to the variability in how/if these functions may be triggered based on how the world object is generated (buildouts, scripts, spawners, etc.).
The systems.turrent.turret_ai script is attached to turrets when they are placed in faction perk bases. When it is attached, it uses the turret library to activate itself and it sets itself as attackable.
public int OnAttach(obj_id self) throws InterruptedException {
turret.activateTurret(self);
ai_lib.setAttackable(self, true);
return SCRIPT_CONTINUE;
}
public int OnDetach(obj_id self) throws InterruptedException { }
OnDetach is triggered when the script is detached from the object. As this is simply the opposite of OnAttach, we have not expanded further.
public int OnInitialize(obj_id self) throws InterruptedException { }
OnInitialize is triggered when the server starts, unless the scene/terrain the object with the script is on isn't running, or the zone/object is unloaded, in which case it will be ran the first time it does load. For player objects (characters), OnInitialize is triggered when they login (see: GameScriptObject.cpp#L189).
The event.holiday_controller script is what handles starting the special events that run in the game, such as Life Day or the Galactic Moon Festival. It is attached to a hidden god object in the buildout of Mos Eisley (which you can see with god mode on just outside the spaceport). Each time the server launches, the holiday controller uses a messageTo to signal that the holiday events should be started.
public int OnInitialize(obj_id self) throws InterruptedException {
messageTo(self, "halloweenServerStart", null, 600.0f, false);
} // additional code omitted for example purposes only