From FreeSpace Wiki
Revision as of 08:49, 18 April 2010 by Zookeeper (talk | contribs) (Clarified how the $Mission condition works)
Jump to: navigation, search

This feature requires SCP

The scripting table is used for scripting special features like alternate HUDs or ship viewer into the game.

Usefull references:

General Info

  • Scripting table consist of several sections
  • All sections and most of the entries are optional
  • All sections end with #End
  • No scripting hooks are not executed on a separate thread, at least as of this writing. They are executed at given points in the code, and all other execution will not take place until a scripting hook has finished. This means that, in theory, a large and complicated enough script will cause noticeable lag or slowdown when executed.
  • Information in this document applies only to the HEAD branch. Scripting in 3.6.9, or in any builds based on 3.6.9, is considered unsupported.



One of the most important things to understand when reading this guide is the concept of "frames". (Experienced modders can probably skip this part) In gameplay, motion is achieved by making incremental changes every fraction of a second. A ship will be moved slightly, and then drawn to the screen. This happens 30-120 times a second; anything lower, and the game will become choppy and difficult to play.

There is also a difference in the moving of objects in-game, and the moving of objects onscreen. All ships are first "moved", in memory. This probably consists of physics calculations, that change the ship's position based on if their engines are turned on, or if they run into another object. After this, the game then renders the now-moved ships to what is referred to as a "backbuffer" - a place in memory that takes the place of the computer screen. Once rendering has finished, the backbuffer is instantly drawn to the screen. This prevents objects from flickering as they are drawn. You do not have to worry about flipping the backbuffer in scripting; FS2_Open will take care of that for you.

For scripting, it is important to understand that each block of code will therefore be executed several times a second, but only once per frame. However, the exact number of times per second will depend on how much work the computer has to do (And therefore how much time it takes) for each frame. To determine how much time you should consider to have passed, you must use the ba.getFrametime() function; which will return the approximate time the frame will take, in seconds. In addition, if you "move" a ship after it has already been rendered, the change will not become apparent until the next frame.

This does mean that if you want to make a block of text move across the screen, at a rate of 5 pixels per second, all you have to do is multiply the speed by the frametime:

#Global Hooks
$Global: [
   --If the g_WheeXPosition variable does not exist,
   --it means we are on the first frame.
   --If that is the case, set it to zero.
   if not g_WheeXPosition then
      g_WheeXPosition = 0

   --Move the text
   g_WheeXPosition = g_WheeXPosition + (5 * ba.getFrametime())

   --Draw "WHEE!!!"
   gr.drawString("WHEE!!!", g_WheeXPosition, 10)


Scripting "hooks" form the basis of the scripting system. A "hook" simply refers to a point in the code where code to execute scripting has been added. The hook may then be added to a table, or added to a SEXP. In general usage, "hook" refers to an entry in scripting.tbl.

All hooks take the form of an identifer (such as $Global:), followed by brackets to determine what type of scripting is being executed. A lack of brackets also indicates a type of scripting execution. All current bracket configurations are listed below. Note that "$Hook:" is used merely as a placeholder, and should be replaced with the actual hook name ($Global:, $HUD:, $On Frame:, etc).

  1. $Hook: scripting
    Specifies one line of LUA scripting. In addition, the return value of that line will be passed to the interpreter and used (if applicable). Specifying a variable or value on this line will result in it being returned, as well.
  2. $Hook: [scripting]
    A single set of brackets specifies a block of LUA scripting. Does not return a value unless explicitly specified. (Explicit specification is not possible at this time; but may be implemented in the future if/when more future hooks take a return value.)
  3. $Hook: [[scriptfilename.lua]]
    Double brackets specify a file. This file is read out of the data/scripts directory, and must include the file extension. You may specify a compiled lua file as a target as well; this may result in crossplatform issues for a mod, however.


Some hooks additionally take a +Override: field. This field uses the same bracket configurations as above. If a hook includes a +Override field, this hook always determines whether the default FS2_Open behavior that the hook is associated with will function, or will be disabled. This should be used in cases where scripting will replace the original FS2_Open behavior. For example:

$HUD: [
    gr.setColor(255, 255, 255, 255)
    gr.drawString("HUD Disabled", 50, 50)
    +Override: true

Additionally, override hooks are (by convention) executed before FS2_Open behavior. The HUD hook override, for example, is executed before any part of the HUD is actually drawn.


  • #Global Hooks
  • #State Hooks (3.6.9)
  • #Conditional Hooks (HEAD)

#Global Hooks

Global hooks are the simplest form of scripting hooks available. They are at preset locations in the code, and are generally executed every time that point is reached. Exceptions to this rule (such as the HUD hook) only depend on one or two variables to determine execution. All other scripting execution is determined by the modder. Note that, as with other tables, the game expects these entries in precisely the order given here; if this is not followed, the parser will throw an error.


Script in this section is executed almost immediately before each frame is drawn. This means that any scripting elements will be drawn, or take effect, after everything else, except for the "On Frame" conditional hook. It is not used with the standalone server. In addition, note that use of this hook should generally be avoided, since all scripting will have to be processed every frame.
This hook is executed once, when the splash images (PreLoad and PreLoadLogo) would be drawn. This hook should generally be used only for drawing the splash screen; any initialization could should be placed in GameInit. This hook is executed before virtually any other subsystem has been loaded, aside from the graphics and filesystem subsystems, so scripting elements such as the table and mission libraries will be nonfunctional.
  • +Override:
    Executed just before default splash images are loaded and displayed. Note that the frame is still drawn regardless; it is not necessary to flip the backbuffer manually.
This hook is executed once, after all of the Freespace2 subsystems have been initialized. It is executed before the game switches to the main hall or, in the case of standalone server mode, begins the game.
This hook is executed only during missions. It is executed after all damage, movement, physics, SEXPs, and other "physical" in-game changes have been applied. It is executed before anything has been rendered. This hook should be used only for damage, movement, and physics related scripting, as if the game needs to be rendered without any in-game time having been passed, this function will not be called.
The HUD hook is executed after the HUD has been drawn. Note that if the HUD is turned off, this hook will be disabled as well, until the HUD is turned back on.
  • +Override:
    Executed immediately before anything on the HUD is drawn, and controls whether the default FS2_Open is drawn.

#State Hooks

In Freespace2, a "state" more or less refers to a room. It may also refer to a separate mode - playing a mission is the GS_STATE_GAME_PLAY state. The main menu is the GS_STATE_MAIN_MENU state. This section should only exist in 3.6.9. It is included here for the sake of documentation; it has since been removed and superseded by the conditional hook system.


Specifies the state name. A full list of states is located here: List of Game States
  • $Hook:
    Executed after all of the state code has been executed, but before the game frame is actually drawn.
    • +Override:
      Determines whether the specified state is handled at all by Freespace. If true, then none of the loading or exit code for the state will be specified as well.

#Conditional Hooks

Scripting hooks are only available in HEAD builds. They consist of any number of conditions, followed by any number of actions. All available conditions and actions are located in the file generated by -output_scripting.

One way to think of conditional scripting is like this: The condition specifies the object that the action will apply to, or the place that the action will occur in. All conditions must be met for their associated actions to execute. Actions are associated with a set of conditions by simply adding them after that set of conditions. (Obviously, you may want to space out each pair of action/condition sets in the TBL to make it easier to read.)

The flexibility of conditional scripting comes in due to its inherent scalability. If you specify a mission and ship condition with a warpin action, that script will only be executed when the ship warps in on that particular mission. Removing the mission field will make that warpin scripting apply to the ship for all missions; or removing the ship field will make the warpin scripting apply to all ships in that mission.

This prompts the question: if this is all conditional scripting does, why not just use the global hook?

  1. Organization - conditional scripting is generally easier to read and modify because it is grouped in a standardized manner.
  2. Speed - All conditions can be evaluated by FS2_Open itself, without invoking the Lua interpreter at all.
  3. Scalability - As of the time of this writing, you can only have one global hook. Modular tables will simply replace it. With conditional scripting, if you want to specify additional actions for a set of conditions in a modular table file, you may do so.


Where "$Condition:" is one of several conditions specified in scripting.html, such as $State: or $Ship:. Takes a value representing the object the condition should be checked against (such as a state, ship, or mission name)
Where "$Action:" is one of several actions specified in scripting.html, such as $On Frame or $On Warp In. Takes a scripting hook, using the bracket configuration outlined at the top of this article.

A brief description of all Conditions and Actions at the time of this writing:


Controls execution based on what state FS2_Open is in, such as the main hall, options screen, or in a mission. The full list of states can be found here: List of Game States
Controls execution based on the current campaign's filename. (It is under consideration to change this to the campaign's name, instead).
Controls execution based on the filename of the last mission to have started. This condition will remain true even after the mission has been exited until another mission is started.
Object Type
Defines a specific object type that the action will apply for, such as a "Ship", "Asteroid", or "Jump Node".
Defines a specific ship (name) that the action will apply for.
Ship class
Defines a specific ship class (name) that the action will apply for.
Ship type
Defines a specific ship type (name) that the action will apply for.
Weapon class
Defines a specific weapon class (name) that the action will apply for.


On Game Init
Executes immediately after game has been started.
  • No associated hook variables.
On Splash Screen
Executes when initial game splash screen is shown
  • No associated hook variables.
On State Start
Executed when specified game state starts
  • No associated hook variables.
On Frame
Executes immediately after the global scripting hook, which is right before the frame is drawn.
  • No associated hook variables.
On Key Pressed
Executed when specified key is pressed
  • Key, The pressed key
On Key Released
Executed when specified key is released
  • Key, The released key
On Mouse Moved
Executed when mouse is moved
  • No associated hook variables.
On Mouse Pressed
Executed when mouse button is pressed
  • No associated hook variables.
On Mouse Released
Executed when mouse button is released
  • No associated hook variables.
On State End
Executed when specified game state ends
  • No associated hook variables.
On Mission Start
Executed when mission starts
  • No associated hook variables.
On HUD Draw
Executed after the HUD has been drawn. Note that if the HUD is turned off, this hook will be disabled as well, until the HUD is turned back on
  • Self, the viewer (object)
On Ship Collision
Executes when the specified object collides with a ship. Sets a handle in the HookVariables library with the name of the object type ("Weapon", "Debris", and so on) with the type of the object. If both objects are ships, the other object gains the name "ShipB". (If both ship objects define a collision hook, the variables will be swapped for the other ship, so the ship that the script is executing for will always be called "Script".) The override will disable FS2_Open code, as well as the other object's collision code. If both objects have an override set, only one of the objects' hooks will be used (Chosen arbitrarily). Note that the override receives the same variables.
  • When colliding something other than other ship:
    • Ship, the ship (object)
    • Debris, Asteroid, Weapon, depending what it collided with (object)
    • Self, the object referred by the condition (object)
    • Object, the ship (object)
  • When colliding with other ship:
    • Ship, the ship (object) referred by the condition (object)
    • ShipB, the other ship (object)
    • Self, the ship (object) referred by the condition (object)
    • Object, the other ship (object)
On Weapon Collision
Like the ship collision hook, but for weapons.
  • When colliding something other than other weapon:
    • Weapon, the weapon (object)
    • Debris, Asteroid, Ship, depending what it collided with (object)
    • Self, the object the weapon collided with (object)
    • Object, the weapon (object)
  • When colliding with other weapon:
    • Weapon, the weapon (object) referred by the condition
    • WeaponB, the other weapon (object)
    • Self, the weapon (object) referred by the condition
    • Object, the other weapon (object)
On Debris Collision
Like the ship collision hook, except for debris.
  • Debris, the debris (object)
  • Weapon, Ship, depending what it collided with (object)
  • Self, the object the debris collided with (object)
  • Object, the debris (object)
On Asteroid Collision
Like the ship collision hook, only for asteroids.
  • Asteroid, the asteroid (object)
  • Weapon, Ship, depending what it collided with (object)
  • Self, the object the asteroid collided with (object)
  • Object, the asteroid (object)
On Object Render
Executes when the specified object is rendered. The override is run before the object is rendered, and both the hook and its override receive an "Object" variable of the object to be rendered.
  • Self, the object rendered (object)
On Warp In
Run when a ship has begun warping in, immediately after everything has been set up for per-frame processing. This hook is only executed once, when the ship begins warping in. An override will disable _all_ behavior related to warpin. Both the hook and an override receive an "Object" handle in the HookVariables library, with the type of the object that is warping in.
  • Self, the object warping in (object)
On Warp Out
Same as warping in, except for warping out.
  • Self, the object warping out (object)
On Death
On Death: Currently only valid for ships. Receives "Self" and "Killer" variables of the object and killer, respectively. Overriding it will override all default death behavior.
  • For asteroids:
    • Self, the asteroid (object)
  • For ships:
    • Self, the ship (object)
    • Killer, the other object (object) - NOTE, not guaranteed to exists
On Mission End
Run on mission end.
  • No associated hook variables.

Other hook variables
  • Viewer, active if (non-player) viewing object is valid
  • Player, active if player obj is valid


See Scripting Examples category