How to mod forts
How to mod forts
How to mod Forts
Overview
The official guide on how to create mods for Forts to add new devices, weapons, materials, change balance, visuals and effects.
Learning Lua
Forts uses Lua to configure the game. By writing your own Lua scripts you can change and add to Forts. Lua is a powerful and easy to learn scripting language. You can pick up a lot by reading the scripts included in Forts, but to get a more structured introduction I recommend the tutorials found at lua-users:
The first 8 tutorials are enough to do everything needed to mod Forts effectively.
You can use any text editor to edit Lua scripts, such as Notepad, which comes with Windows. Something more sophisticated such as Notepad++ [notepad-plus-plus.org] or Sublime Text [www.sublimetext.com] will make life easier, however. To support localisation into some non-English languages the editor will need to support UTF-16 Unicode encoding.
Game configuration
Forts’ data can be browsed as ordinary files. You can find it by right clicking on Forts in Steam, then properties, then local files. You will see the data directory there.
The data is divided into subdirectories according to their purpose. For example there is a directory for devices, weapons and materials. You can browse these folders to learn about how the game is set up. The game looks for specific plain text Lua files in order to get the parameters and asset filenames it needs to load and run the game.
The scripts most important to modding include:
During the loading of a battle, the game will read these files and look for certain tables and variables within them. If you open weapon_list.lua, you’ll see a table called Weapons. The game looks through this table to find the weapons to be used for this battle, what they are called internally (SaveName), how much they cost, build duration, etc.
Each weapon entry has a value called FileName. This points to a Lua file with detailed data about the appearance and behavior of the weapon. It sets the effects used while firing, reloading, being destroyed etc. It also has a value called Projectile. This value references the SaveName of an entry in the Projectiles table of the projectile_list.lua file, and so specifies which projectile to create when the weapon fires. Devices are similar to weapons but don’t need parameters relating to firing. Materials have all of their configuration data in building_materials.lua, and their appearance is in the Sprites table, including damage levels.
You can browse this material, device, weapon and projectile data to see what parameters, texture files and effects are needed to make up the game. There is quite a lot, but everything is named well and you can ask us if something doesn’t make sense. Understanding the game configuration is essential for modding the game correctly.
Mods replicate part of the file structure
In the data directory you’ll see a folder called ‘mods’. If you browse that you’ll see subdirectories. Each of these is a mod. If you browse some of these mods (such as weapon_pack) you’ll see some folders and Lua files that are the same as in the base data directory.
The way mods work in Forts is that the base Lua file is loaded first, and then for each of the mods that are active, the game looks for the same Lua file in the mod’s directory and loads that on top of what’s been loaded already. So each mod can change the variables and tables of the base game. They can also change images, projectiles, and effects. They can add completely new items, disable existing items, or remove them altogether.
If you are changing a variable it is often better to multiply it by a factor, or add or subtract, instead of setting an absolute value. We make balancing changes from time to time, and an absolute change may be off the mark afterwards.
Warning: never make changes to the base game files or included mod folders. Doing so will change your experience, make the game unstable, and cause desyncs in multiplayer and when watching older replays. If you need to revert a change you can right click on Forts in Steam, then properties, then local files. Select Verify Integrity of Game Files.
A simple mod: changing a value
Let’s take a simple example of setting gravity to zero. The value that controls gravity is in db/constants.lua, in the table called Physics, and the variable is Gravity. By default this is 981, the value of acceleration under Earth’s gravity in game units per second per second.
The first step is to create a folder under mods, let’s call it zerog. Then we create a subdirectory called db, and within that a blank text file called constants.lua. It should look like the original file containing the variable we want to mod, but under our own mod directory instead.
Now we can’t use the same format in the base constants.lua file, because that would wipe all the other values in the Physics table. Instead we can reference a value within the table like so:
(in file mods/zerog/db/constants.lua)
You also need to create a mod.lua file in mods/zerog and add the following lines:
Run Forts and go to Sandbox. Start a map and go to the Player tab. You should see under the Physics category the name of the mod folder. Select that, start the Sandbox and watch things float about. Congratulations! You’ve made your first mod.
As you know we’ve already made a zero gravity mod, and the mod name is zerogravity. We found that setting the gravity to zero wasn’t the only change needed. We also reduced the drag so ships could move faster and the maximum angle at which a strut will accept a device, and changed a few other things. You might also find that making a mod requires more changes than you anticipated.
The order of application
Because there can be any number of mods active, the data being modified is not necessarily what is in the base game. The base file is loaded, then the first mod, then the next mod, and so on. Each mod is applied to the changes made by the mods before it.
The order that mods are applied in is influenced by the optional Priority value in the mod.lua file. Lower values are applied first. Higher values are applied last, and so tend to have the final say. The expected range is 1 to 10, and the default is 5. If two mods have the same priority the order is alphabetical according to the mod name (or Workshop published id).
If a mod should make a change to every item, it should have a high value for Priority so it is applied last. The fast-build mod, for example, has a building_material.lua file which iterates the material items, including any that came from mods applied before it, and adjusts their build and scrap time like so:
Also, don’t be dependent on the data being untouched. If you want your new weapon to appear in a particular location you need to look for the position of the weapon you want it to appear after and insert it after that. Examples can be found in the weapon_pack mod. The Rocket is positioned after the EMP Rocket:
The ApplyMod function
This function is called once all mods have been applied, so you can do processing, calculations and call functions you’ve written yourself which may not be possible during normal script loading call. Keep in mind that earlier mods may have defined this function, so to prevent blocking them you should chain your calls. Make sure you save the previous function in a uniquely named variable, or else you could overwrite a previous mod’s value. For example, by incorporating the name of your mod. You can use it like so, where mymod is the name of your mod:
Adding a device with included textures
We created the Large Sandbags mod as a comprehensive example of how to add a new device to Forts. Once you are subscribed, navigate to your Steam library and then steamappsworkshopcontent4109001293804859. This is an example of where a Workshop mod ends up after you upload it and someone subscribes to it. The original folder name is changed to a number, but everything else is the same. The change of location is why prefixing filenames with the path variable is so important – more below.
The critical file in this mod is devices/device_list.lua. The first part of this script creates new sprites based on the included textures, found in ui/textures/HUD. The DetailSprite and ButtonSprite helper functions are defined in data/ui/uihelper.lua, and the Sprites table is read by the game to create any sprites defined by the configuration script. The ‘path’ variable is set by the game to the relative or absolute path of the mod (in the case of a subscribed mod), allowing it to reference new texture assets stored in the mod’s directory. You don’t need to understand exactly how this works, but if you keep your texture files in the same location and update the names it should work.
Moving down a bit, you’ll see where the new device is added to the Devices table.
The IndexOfDevice function allows us to put the new device in a sensible position (after the original sandbag). The third parameter is the new item we’re adding. We define the SaveName, the FileName which sets the detailed configuration of the device, the Icon and Detail HUD sprites, which we defined at the top, the prerequisite tech structure – the Upgrade Centre, and several other basic parameters (build time, cost and reclaim settings).
You can open devices/sandbags_large.lua to see what detailed parameters are set. This is where you would make the device behave different to other devices. You can look at the devices included with the game and the weapon_pack mod to see what variables to change and what values would be appropriate. It’s a good idea to play around with the values to see what feels good, rather than just using the first values that occur to you. Testing with friends helps to get feedback.
In the middle of the file you’ll see a new Sprites table, which sets the single-frame sprite of the sandbag to the included texture /devices/SandbagsLarge.tga. Note the use of the path variable again. The following forward slash is important as it’s not included in the path variable.
Further down you’ll see the Root table, which configures how multiple sprites fit together to make a single device. This can be a complex set of nested tables for a weapon, as there are multiple parts and a pivot where the gun rotates. This structure specifies where projectiles and beams are emitted from by creating a “Hardpoint0” child node (with no Sprite value set). If you want to create a new weapon it’s best to copy an existing one and experiment with Root until you understand how it works. The Angle, Pivot and PivotOffset values determine how child nodes are positioned relative to the parent. UserData is set to the percentage of construction at which the node will appear (or disappear on scrap).
The other gameplay related change the Large Sandbags mod does is reduce the damage the 20mm cannon does to it. You’ll find this in modsweapon_packweaponsprojectile_list.lua. This is a mod of a mod (or a nested mod). It’s changing the way the weapon_pack works because the damage multiplier versus a device is associated with the projectile. It is set like this:
Device Upgrades
Devices (and weapons) can have one or more upgrades, with optional prerequisites (see the Prerequisites section below). This is achieved by adding an Upgrades table to the device in device_list.lua (or weapon_list.lua for weapons).
The entries in this table set the SaveName and cost of the upgrade, and can also set a button sprite for the context menu. Although the detail sprite of the device will be shown on rollover, when there are multiple upgrades custom buttons are recommended so the player can tell them apart easily.
The ButtonSprite helper function can be used to make the button sprite so it has disabled, rollover and pressed states. The built-in textures with path ui/textures/context/HUD-Buttons-Blank-*.tga can be copied and edited to create new buttons.
Upgrades can be disabled at start by setting Enabled = false, and later enabled by mission or mod script by using the EnableDeviceUpgrade or EnableWeaponUpgrade functions.
If you are modding an existing device then make sure to insert your upgrades rather than setting the table from scratch, to prevent the loss of the existing upgrades, or those added by other mods.
Prerequisites
By default materials and devices can be built if the player has enough resources. It’s possible, however, to add a requirement to build a certain device or a combination of devices first. This is how the ‘tech’ buildings operate to restrict construction.
Both materials and devices (which includes weapons) have the same syntax for the Prerequisites variable. If it is left as nil, then it can always be built.
If assigned to a string then at least one device with that SaveName must be built before the material or device can be constructed:
There is an obsolete method of setting an alternative required device, but we recommend you use the more flexible syntax below. In the following example the item can be built if the workshop or the armoury has been built.
You can also set up a list of combinations of device SaveNames for complex requirements. If any one of the combinations is satisfied then the item can be built. In the following example, the item can be built if the workshop and the upgrade centre is built, or the factory alone is built. This list of combinations can be as long as you like.
Device upgrades can have their own prerequisites set in the same way. If the upgrade’s Prerequisite variable is not set then it defaults to the prerequisites of the target device of the upgrade.
Material Conversions
Right clicking on a strut will bring up a context menu, including a number of buttons with material icons. These buttons can be used to convert the strut into a different material. By default this list of materials is set to the contents of the DefaultConversions table in the base building_materials.lua file:
This list can be modified like anything, but it’s also possible to customise it for a specific material by setting the Conversions table. It’s best to merge any new materials with the DefaultConversions table, to keep the changes introduced by other mods. To allow a material to be convertible to a portal in the context menu, for example:
In order for this to work the material to be included must have the Context variable set to the name of a valid sprite. The ButtonSprite function from ui/uihelper.lua must be provided with a path in order for it to find the textures within the mod’s ui/textures folder:
See the ‘bracing’ material in the base building_materials.lua file for an example.
Adding effects and audio
You can add custom effects to your mods such as explosions, muzzle flashes, and projectile trails. These can including new textures and sound effects, or instead use existing assets from the game. Reference these new effects from your other scripts using the file’s name relative to your mod’s ‘path’, for example in a device script:
Effect scripts take the following general format, for example:
The following effect types are available:
Creates a single textured quad that can move, rotate, scale and blend between two colours. See example above.
Creates a series of bursts made up of sprites with rules about how they are positioned, sized and rotated depending on the direction they are emitted.
Creates a textured streamer which follows the position of the effect.
Makes the camera move rapidly depending on how close it is to the effect.
There are many variables associated with each of these. Please use the Forts/data/mods/weapon_pack/effects folder as a basis to learn from. You can copy and edit the scripts to make your own.
Localisation
In Forts all languages are implemented as mods. You can inspect the base string tables in the Forts/data/mods/language-* folders to see what files are available for modding. In order to change or extend string tables for your mod you need to mod these language mods. Using the Large Sandbags mod as a reference again, you will see the following folder structure (with English expanded as an example):
If you opened mods/language-English/devices/strings.lua, you will see:
This shows how the strings describing the new device are merged into the sub-string table called Device. The string ids, like “sandbags_large”, and “sandbags_largeTip2”, are automatically generated from each device SaveName to look for the strings to show.
If you are replacing an existing string, you can just overwrite it, as in the Scattershot commander string.lua example:
If a particular language is missing for a particular string id then it will be blank for tips, but in most cases it will appear as the string id. This makes it easier to find string ids that are missing translations.
Moonshot Only Features
A few features were introduced with the Moonshot DLC that are not available in the base game. If you wish to make use of these features then your mod becomes dependent on Moonshot, and can only be activated when the host of the game has it installed (which is always you in single player games). These mods are displayed with a blue Moonshot icon in the mod selection screen.
When you make a Moonshot dependent mod, you must add a flag to your mod.lua file so the game can quickly identify it as such. You may get an error message if you try to publish a mod that depends on moonshot and does not have this flag:
The features and their associated keywords which trigger dependency are outlined below. Note that if these words are found anywhere in the appropriate file it will become dependent, even if it’s out of place or in a comment.
The keyword Portal in building_materials.lua triggers dependency. This allows a material to teleport projectiles and beams when two such struts are linked by the player.
The keyword MaxBursts in a weapon script, or weapon_list.lua will trigger dependency. When used in a weapon script (e.g. machinegun.lua) the weapon will self destruct after firing that many times. This is used on the Moonshot only Buzzsaw weapon.
The keyword RayDamage in the projectile_list.lua file will trigger dependency. This is used in combination with a few other variables to create damage in a straight line when a projectile collides with a strut. The buzzsaw projectile, for example:
The keyword FieldRadius in the projectile_list.lua will trigger dependency. This is used in combination with a few other variables to create a field for various purposes. It is used to implement smoke and to attract projectiles to the magnabeam point of impact. For example, the smoke projectile uses it like so:
The options for FieldType are:
Dynamic Scripting
By adding a script.lua file in their root folder, mods can have arbitrary Lua script executed based on events triggered by the game, including projectile impacts, destruction of devices and weapons, ownership changes and user input. There are also events for the initial load, physics frame, display frame, and restart. Functions can also be scheduled to execute at a specific time in the future. They behave identically to mission scripts, but are not tied to a specific map.
In response to these events the mod script can perform a host of changes to the game state, create effects, or show controls on the screen. It can also track any state it wishes in the ‘data’ table, which will automatically be serialised for the purpose of replays and players joining a battle.
The details of this dynamic mod scripting can be found at the Forts Scripting API Reference [www.earthworkgames.com] page, which is generated directly from the Forts source code with mark up to provide descriptions.
Mod categories
To make your mod easy to find on the Steam Workshop and in the game’s mod selection screen, we recommend you put it into a category. This is set in the (optional) mod.lua file you put in the mod’s base folder. This will apply a tag to the item in the Workshop, useful for searching for those of interest. In the game it will put the mod into a branch of a tree view which can be collapsed for quick browsing.
An example mod.lua would be
If mod.lua is missing, the Category variable is not specified, or it’s invalid then the mod is placed in the Misc category. Valid categories are:
Publishing and testing
Once you are happy with how your mod is working locally, you can upload it to the Steam Workshop. Before you do this you need to create a preview.jpg file in the mod’s folder which will represent it in Forts and on Steam Workshop. The size isn’t so important, but the aspect ratio should be 16:9 so it appears correctly in Forts. The map previews are 1024*576, for example. This is fine for mods too.
Now to publish the mod, go to the main menu and then enter the Workshop menu. Go to the Upload tab and select the mod you’ve been working on. Click on the Upload button, and then Yes. After a short while it will open the new item in the workshop. You should be subscribed to it automatically, and you should make it either hidden or visible to friends only for testing. To make sure the mod will work for others, you should get a friend to subscribe to it and run the game with it. Otherwise you should rename your mod folder and run the Workshop version of the mod. This will bring to light any asset path problems that had been missed during development. Change the folder name of you mod back to edit and update once the problems are fixed.
Forcing a mod in a map
You can force a Workshop mod on in your custom map, in the same way as a built-in mod. In your map’s mission script, add or edit the Mods table to include the published file id. For example, to make sure Large Sandbags are available in your map:
To make it easier to understand, you could write it like this instead:
This is vital if your map includes new materials, devices or weapons added by a mod at the start.
How to mod forts
3,913 | уникальных посетителей |
119 | добавили в избранное |
Forts uses Lua to configure the game. By writing your own Lua scripts you can change and add to Forts. Lua is a powerful and easy to learn scripting language. You can pick up a lot by reading the scripts included in Forts, but to get a more structured introduction I recommend the tutorials found at lua-users:
The first 8 tutorials are enough to do everything needed to mod Forts effectively.
You can use any text editor to edit Lua scripts, such as Notepad, which comes with Windows. Something more sophisticated such as Notepad++ [notepad-plus-plus.org] or Sublime Text [www.sublimetext.com] will make life easier, however. To support localisation into some non-English languages the editor will need to support UTF-16 Unicode encoding.
Forts’ data can be browsed as ordinary files. You can find it by right clicking on Forts in Steam, then properties, then local files. You will see the data directory there.
The data is divided into subdirectories according to their purpose. For example there is a directory for devices, weapons and materials. You can browse these folders to learn about how the game is set up. The game looks for specific plain text Lua files in order to get the parameters and asset filenames it needs to load and run the game.
Each weapon entry has a value called FileName. This points to a Lua file with detailed data about the appearance and behavior of the weapon. It sets the effects used while firing, reloading, being destroyed etc. It also has a value called Projectile. This value references the SaveName of an entry in the Projectiles table of the projectile_list.lua file, and so specifies which projectile to create when the weapon fires. Devices are similar to weapons but don’t need parameters relating to firing. Materials have all of their configuration data in building_materials.lua, and their appearance is in the Sprites table, including damage levels.
You can browse this material, device, weapon and projectile data to see what parameters, texture files and effects are needed to make up the game. There is quite a lot, but everything is named well and you can ask us if something doesn’t make sense. Understanding the game configuration is essential for modding the game correctly.
In the data directory you’ll see a folder called ‘mods’. If you browse that you’ll see subdirectories. Each of these is a mod. If you browse some of these mods (such as weapon_pack) you’ll see some folders and Lua files that are the same as in the base data directory.
The way mods work in Forts is that the base Lua file is loaded first, and then for each of the mods that are active, the game looks for the same Lua file in the mod’s directory and loads that on top of what’s been loaded already. So each mod can change the variables and tables of the base game. They can also change images, projectiles, and effects. They can add completely new items, disable existing items, or remove them altogether.
If you are changing a variable it is often better to multiply it by a factor, or add or subtract, instead of setting an absolute value. We make balancing changes from time to time, and an absolute change may be off the mark afterwards.
Warning: never make changes to the base game files or included mod folders. Doing so will change your experience, make the game unstable, and cause desyncs in multiplayer and when watching older replays. If you need to revert a change you can right click on Forts in Steam, then properties, then local files. Select Verify Integrity of Game Files.
Let’s take a simple example of setting gravity to zero. The value that controls gravity is in db/constants.lua, in the table called Physics, and the variable is Gravity. By default this is 981, the value of acceleration under Earth’s gravity in game units per second per second.
The first step is to create a folder under mods, let’s call it zerog. Then we create a subdirectory called db, and within that a blank text file called constants.lua. It should look like the original file containing the variable we want to mod, but under our own mod directory instead.
Now we can’t use the same format in the base constants.lua file, because that would wipe all the other values in the Physics table. Instead we can reference a value within the table like so:
(in file mods/zerog/db/constants.lua)
You also need to create a mod.lua file in mods/zerog and add the following lines:
Run Forts and go to Sandbox. Start a map and go to the Player tab. You should see under the Physics category the name of the mod folder. Select that, start the Sandbox and watch things float about. Congratulations! You’ve made your first mod.
As you know we’ve already made a zero gravity mod, and the mod name is zerogravity. We found that setting the gravity to zero wasn’t the only change needed. We also reduced the drag so ships could move faster and the maximum angle at which a strut will accept a device, and changed a few other things. You might also find that making a mod requires more changes than you anticipated.
Because there can be any number of mods active, the data being modified is not necessarily what is in the base game. The base file is loaded, then the first mod, then the next mod, and so on. Each mod is applied to the changes made by the mods before it.
The order that mods are applied in is influenced by the optional Priority value in the mod.lua file. Lower values are applied first. Higher values are applied last, and so tend to have the final say. The expected range is 1 to 10, and the default is 5. If two mods have the same priority the order is alphabetical according to the mod name (or Workshop published id).
If a mod should make a change to every item, it should have a high value for Priority so it is applied last. The fast-build mod, for example, has a building_material.lua file which iterates the material items, including any that came from mods applied before it, and adjusts their build and scrap time like so:
Also, don’t be dependent on the data being untouched. If you want your new weapon to appear in a particular location you need to look for the position of the weapon you want it to appear after and insert it after that. Examples can be found in the weapon_pack mod. The Rocket is positioned after the EMP Rocket:
This works in practically all configuration scripts. In a specific device configuration script, or device.lua, to double production, for example:
Commanders use this system to apply changes to modded devices, weapons, materials, projectiles, and more. For example, Architect reduces build times in weapon_list.lua with a named function, like so:
= «upgrade» then device.BuildTimeComplete = 0.25*device.BuildTimeComplete end end end RegisterApplyMod(CommanderApplyModBase)
All commander ‘ApplyMod’ functions have the same name. If you are modding a commander and want to prevent this from functioning, you can remove it using the DeregisterApplyMod function:
You are free to name your own functions so that other mods can remove yours, just keep in mind that earlier mods may have defined such a function too. Make sure you give them a unique name, or you could overwrite a previous mod’s value.
NOTE: The older ApplyMod system is deprecated. It is still functional but we don’t recommend using it, and we may remove it at some point in the future.
The critical file in this mod is devices/device_list.lua. The first part of this script creates new sprites based on the included textures, found in ui/textures/HUD. The DetailSprite and ButtonSprite helper functions are defined in data/ui/uihelper.lua, and the Sprites table is read by the game to create any sprites defined by the configuration script. The ‘path’ variable is set by the game to the relative or absolute path of the mod (in the case of a subscribed mod), allowing it to reference new texture assets stored in the mod’s directory. You don’t need to understand exactly how this works, but if you keep your texture files in the same location and update the names it should work.
Moving down a bit, you’ll see where the new device is added to the Devices table.
You can open devices/sandbags_large.lua to see what detailed parameters are set. This is where you would make the device behave different to other devices. You can look at the devices included with the game and the weapon_pack mod to see what variables to change and what values would be appropriate. It’s a good idea to play around with the values to see what feels good, rather than just using the first values that occur to you. Testing with friends helps to get feedback.
In the middle of the file you’ll see a new Sprites table, which sets the single-frame sprite of the sandbag to the included texture /devices/SandbagsLarge.tga. Note the use of the path variable again. The following forward slash is important as it’s not included in the path variable.
Further down you’ll see the Root table, which configures how multiple sprites fit together to make a single device. This can be a complex set of nested tables for a weapon, as there are multiple parts and a pivot where the gun rotates. This structure specifies where projectiles and beams are emitted from by creating a «Hardpoint0» child node (with no Sprite value set). If you want to create a new weapon it’s best to copy an existing one and experiment with Root until you understand how it works. The Angle, Pivot and PivotOffset values determine how child nodes are positioned relative to the parent. UserData is set to the percentage of construction at which the node will appear (or disappear on scrap).
The other gameplay related change the Large Sandbags mod does is reduce the damage the 20mm cannon does to it. You’ll find this in mods\weapon_pack\weapons\projectile_list.lua. This is a mod of a mod (or a nested mod). It’s changing the way the weapon_pack works because the damage multiplier versus a device is associated with the projectile. It is set like this:
Devices (and weapons) can have one or more upgrades, with optional prerequisites (see the Prerequisites section below). This is achieved by adding an Upgrades table to the device in device_list.lua (or weapon_list.lua for weapons).
The entries in this table set the SaveName and cost of the upgrade, and can also set a button sprite for the context menu. Although the detail sprite of the device will be shown on rollover, when there are multiple upgrades custom buttons are recommended so the player can tell them apart easily.
The ButtonSprite helper function can be used to make the button sprite so it has disabled, rollover and pressed states. The built-in textures with path ui/textures/context/HUD-Buttons-Blank-*.tga can be copied and edited to create new buttons.
Upgrades can be disabled at start by setting Enabled = false, and later enabled by mission or mod script by using the EnableDeviceUpgrade or EnableWeaponUpgrade functions.
If you are modding an existing device then make sure to insert your upgrades rather than setting the table from scratch, to prevent the loss of the existing upgrades, or those added by other mods.
By default materials and devices can be built if the player has enough resources. It’s possible, however, to add a requirement to build a certain device or a combination of devices first. This is how the ‘tech’ buildings operate to restrict construction.
Both materials and devices (which includes weapons) have the same syntax for the Prerequisites variable. If it is left as nil, then it can always be built.
If assigned to a string then at least one device with that SaveName must be built before the material or device can be constructed:
There is an obsolete method of setting an alternative required device, but we recommend you use the more flexible syntax below. In the following example the item can be built if the workshop or the armoury has been built.
You can also set up a list of combinations of device SaveNames for complex requirements. If any one of the combinations is satisfied then the item can be built. In the following example, the item can be built if the workshop and the upgrade centre is built, or the factory alone is built. This list of combinations can be as long as you like.
Device upgrades can have their own prerequisites set in the same way. If the upgrade’s Prerequisite variable is not set then it defaults to the prerequisites of the target device of the upgrade.
Beams operate over a period of time, set by the BeamDuration variable of the weapon, and so have configuration options that projectile weapons don’t. The simplest way of setting up their width and damage is with the ProjectileThickness and ProjectileDamage variables in the weapons/projectile_list.lua item, which remain constant. ProjectileDamage for beams means ‘hitpoints per second’.
In addition, beams can have time functions for thickness and damage. This is to allow more dramatic wind up, wind down and oscillation. To achieve this you can implement the BeamThickness and BeamDamage functions in your weapon configuration script. They take a time value (relative to the end of FireDelay), and return a value which represents the instantaneous thickness and damage (still in hitpoints per second) of the beam.
Within the weapon configuration script, the constant variables and the result of the functions can both be modified with BeamThicknessMultiplier and BeamDamageMultiplier. They default to 1.
Here is part of the Plasma Laser weapon configuration script as an example. To allow more intuitive tuning of the beam we organise the data in a time-keyed table, BeamTable, and then use InterpolateTable to calculate intermediate values.
With the High Seas DLC update in March 2022, the ability to specify these functions as part of the projectile item was introduced. This was necessary because the Ammo system allowed a weapon to produce multiple beams. Also added was a new sprite which tracks the collision end point of the beam, described below. The Orbital Sweep projectile gives an example:
WARNING: name your beam table something unique to your mod. Using the same table name will overwrite previous values and change the behaviour of other beams.
Prior to High Seas, beams could only have one visual layer. Now it’s possible to have multiple layers, each with their own thickness functions, scroll rate, tile rate, and additive value.
They could also only have an effect produced at collision points. We needed more control of this, so we added an optional sprite with its own thickness function. It will exactly track the endpoint of the beam, even if it moves rapidly.
The sprites for each beam layer should specify «repeatS = true,» to make the texture tile along the length of the beam.
The Orbital Sweep beam is an example:
The High Seas update also introduced the concept of beams having a maximum distance of travel, which continues through reflections and when passing portals (which add no distance themselves). The beam will stop abruptly after this distance has been reached, like a light saber. It can be adjusted by setting the BeamMaxTravel variable of the projectile item. It defaults to a large number, so will not affect legacy beams.
Right clicking on a strut will bring up a context menu, including a number of buttons with material icons. These buttons can be used to convert the strut into a different material. By default this list of materials is set to the contents of the DefaultConversions table in the base building_materials.lua file:
This list can be modified like anything, but it’s also possible to customise it for a specific material by setting the Conversions table. It’s best to merge any new materials with the DefaultConversions table, to keep the changes introduced by other mods. To allow a material to be convertible to a portal in the context menu, for example:
In order for this to work the material to be included must have the Context variable set to the name of a valid sprite. The ButtonSprite function from ui/uihelper.lua must be provided with a path in order for it to find the textures within the mod’s ui/textures folder:
You can add custom effects to your mods such as explosions, muzzle flashes, and projectile trails. These can including new textures and sound effects, or instead use existing assets from the game. Reference these new effects from your other scripts using the file’s name relative to your mod’s ‘path’, for example in a device script:
Effect scripts take the following general format, for example:
The following effect types are available:
Creates a single textured quad that can move, rotate, scale and blend between two colours. See example above.
Creates a series of bursts made up of sprites with rules about how they are positioned, sized and rotated depending on the direction they are emitted.
Creates a textured streamer which follows the position of the effect.
Makes the camera move rapidly depending on how close it is to the effect.
In Forts all languages are implemented as mods. You can inspect the base string tables in the Forts/data/mods/language-* folders to see what files are available for modding. In order to change or extend string tables for your mod you need to mod these language mods. Using the Large Sandbags mod as a reference again, you will see the following folder structure (with English expanded as an example):
If you opened mods/language-English/devices/strings.lua, you will see:
This shows how the strings describing the new device are merged into the sub-string table called Device. The string ids, like «sandbags_large», and «sandbags_largeTip2», are automatically generated from each device SaveName to look for the strings to show.
If you are replacing an existing string, you can just overwrite it, as in the Scattershot commander string.lua example:
A few features were introduced with the Moonshot DLC that are not available in the base game. If you wish to make use of these features then your mod becomes dependent on Moonshot, and can only be activated when the host of the game has it installed (which is always you in single player games). These mods are displayed with a blue Moonshot icon in the mod selection screen.
When you make a Moonshot dependent mod, you must add a flag to your mod.lua file so the game can quickly identify it as such. You may get an error message if you try to publish a mod that depends on moonshot and does not have this flag:
The features and their associated keywords which trigger dependency are outlined below. Note that if these words are found anywhere in the appropriate file it will become dependent, even if it’s out of place or in a comment.
If you want to make use of Moonshot features when they’re available, but still allow your mod to run without them working if Moonshot is not available, then use this flag instead:
The game will automatically set two variables, dlc1Var_Active and dlc1Var_Value. These are set to true and 1 if Moonshot is available, and false and 0 if it’s not, respectively. You can use these to prevent the addition of weapons which don’t make sense, for example.
The keyword Portal in building_materials.lua triggers dependency. This allows a material to teleport projectiles and beams when two such struts are linked by the player.
The keyword MaxBursts in a weapon script, or weapon_list.lua will trigger dependency. When used in a weapon script (e.g. machinegun.lua) the weapon will self destruct after firing that many times. This is used on the Moonshot only Buzzsaw weapon.
The keyword RayDamage in the projectile_list.lua file will trigger dependency. This is used in combination with a few other variables to create damage in a straight line when a projectile collides with a strut. The buzzsaw projectile, for example:
The keyword FieldRadius in the projectile_list.lua will trigger dependency. This is used in combination with a few other variables to create a field for various purposes. It is used to implement smoke and to attract projectiles to the magnabeam point of impact. For example, the smoke projectile uses it like so:
The options for FieldType are:
By adding a script.lua file in their root folder, mods can have arbitrary Lua script executed based on events triggered by the game, including projectile impacts, destruction of devices and weapons, ownership changes and user input. There are also events for the initial load, physics frame, display frame, and restart. Functions can also be scheduled to execute at a specific time in the future. They behave identically to mission scripts, but are not tied to a specific map.
In response to these events the mod script can perform a host of changes to the game state, create effects, or show controls on the screen. It can also track any state it wishes in the ‘data’ table, which will automatically be serialised for the purpose of replays and players joining a battle.
The details of this dynamic mod scripting can be found at the Forts Scripting API Reference [www.earthworkgames.com] page, which is generated directly from the Forts source code with mark up to provide descriptions.
To make your mod easy to find on the Steam Workshop and in the game’s mod selection screen, we recommend you put it into a category. This is set in the (optional) mod.lua file you put in the mod’s base folder. This will apply a tag to the item in the Workshop, useful for searching for those of interest. In the game it will put the mod into a branch of a tree view which can be collapsed for quick browsing.
An example mod.lua would be
If mod.lua is missing, the Category variable is not specified, or it’s invalid then the mod is placed in the Misc category. Valid categories are:
Once you are happy with how your mod is working locally, you can upload it to the Steam Workshop. Before you do this you need to create a preview.jpg file in the mod’s folder which will represent it in Forts and on Steam Workshop. The size isn’t so important, but the aspect ratio should be 16:9 so it appears correctly in Forts. The map previews are 1024*576, for example. This is fine for mods too.
Now to publish the mod, go to the main menu and then enter the Workshop menu. Go to the Upload tab and select the mod you’ve been working on. Click on the Upload button, and then Yes. After a short while it will open the new item in the workshop. You should be subscribed to it automatically, and you should make it either hidden or visible to friends only for testing. To make sure the mod will work for others, you should get a friend to subscribe to it and run the game with it. Otherwise you should rename your mod folder and run the Workshop version of the mod. This will bring to light any asset path problems that had been missed during development. Change the folder name of you mod back to edit and update once the problems are fixed.
You can force a Workshop mod on in your custom map, in the same way as a built-in mod. In your map’s mission script, add or edit the Mods table to include the published file id. For example, to make sure Large Sandbags are available in your map:
To make it easier to understand, you could write it like this instead:
How to mod forts
The Forts Workshop is where players can create, publish, and download maps and mods for Forts on Steam.
Maps and mods can be downloaded directly from multiplayer lobbies. Look for a red download arrow next to the map and mod menus to download the selected options for the current game. A red arrow will also appear next to items suggested by other players in chat.
You can also download items directly from the Steam Workshop:
https://steamcommunity.com/app/410900/workshop/
Once you have downloaded a Workshop map or mod, you will need to enable it for your current game. To select a Workshop item, click on the «Player» tab in the map or mods menu to see your Workshop downloads.
Note: Not every Workshop item supports all game modes. For example, in order to support Skirmish mode, the mapmaker must have recorded an AI base and flagged the map as being Skirmish compatible. Some items, such as capture maps or portal mods, may also require the Moonshot DLC in order to be selected.
Tanya’s-Mod is currently the most subscribed item on the Forts Workshop. It is one of the oldest and most comprehensive Forts mods with a complete commander rework and dozens of new weapons, materials, and devices. It also introduces new physics and projectile interactions, including lighter-than-air materials, solar power generation, and anti-gravity generators.
However, it does require the Moonshot DLC (the pre-DLC version is no longer maintained or compatible with Forts) and may conflict with other Workshop maps and mods.
How to mod forts
3,913 | уникальных посетителей |
119 | добавили в избранное |
Forts uses Lua to configure the game. By writing your own Lua scripts you can change and add to Forts. Lua is a powerful and easy to learn scripting language. You can pick up a lot by reading the scripts included in Forts, but to get a more structured introduction I recommend the tutorials found at lua-users:
The first 8 tutorials are enough to do everything needed to mod Forts effectively.
You can use any text editor to edit Lua scripts, such as Notepad, which comes with Windows. Something more sophisticated such as Notepad++ [notepad-plus-plus.org] or Sublime Text [www.sublimetext.com] will make life easier, however. To support localisation into some non-English languages the editor will need to support UTF-16 Unicode encoding.
Forts’ data can be browsed as ordinary files. You can find it by right clicking on Forts in Steam, then properties, then local files. You will see the data directory there.
The data is divided into subdirectories according to their purpose. For example there is a directory for devices, weapons and materials. You can browse these folders to learn about how the game is set up. The game looks for specific plain text Lua files in order to get the parameters and asset filenames it needs to load and run the game.
Each weapon entry has a value called FileName. This points to a Lua file with detailed data about the appearance and behavior of the weapon. It sets the effects used while firing, reloading, being destroyed etc. It also has a value called Projectile. This value references the SaveName of an entry in the Projectiles table of the projectile_list.lua file, and so specifies which projectile to create when the weapon fires. Devices are similar to weapons but don’t need parameters relating to firing. Materials have all of their configuration data in building_materials.lua, and their appearance is in the Sprites table, including damage levels.
You can browse this material, device, weapon and projectile data to see what parameters, texture files and effects are needed to make up the game. There is quite a lot, but everything is named well and you can ask us if something doesn’t make sense. Understanding the game configuration is essential for modding the game correctly.
In the data directory you’ll see a folder called ‘mods’. If you browse that you’ll see subdirectories. Each of these is a mod. If you browse some of these mods (such as weapon_pack) you’ll see some folders and Lua files that are the same as in the base data directory.
The way mods work in Forts is that the base Lua file is loaded first, and then for each of the mods that are active, the game looks for the same Lua file in the mod’s directory and loads that on top of what’s been loaded already. So each mod can change the variables and tables of the base game. They can also change images, projectiles, and effects. They can add completely new items, disable existing items, or remove them altogether.
If you are changing a variable it is often better to multiply it by a factor, or add or subtract, instead of setting an absolute value. We make balancing changes from time to time, and an absolute change may be off the mark afterwards.
Warning: never make changes to the base game files or included mod folders. Doing so will change your experience, make the game unstable, and cause desyncs in multiplayer and when watching older replays. If you need to revert a change you can right click on Forts in Steam, then properties, then local files. Select Verify Integrity of Game Files.
Let’s take a simple example of setting gravity to zero. The value that controls gravity is in db/constants.lua, in the table called Physics, and the variable is Gravity. By default this is 981, the value of acceleration under Earth’s gravity in game units per second per second.
The first step is to create a folder under mods, let’s call it zerog. Then we create a subdirectory called db, and within that a blank text file called constants.lua. It should look like the original file containing the variable we want to mod, but under our own mod directory instead.
Now we can’t use the same format in the base constants.lua file, because that would wipe all the other values in the Physics table. Instead we can reference a value within the table like so:
(in file mods/zerog/db/constants.lua)
You also need to create a mod.lua file in mods/zerog and add the following lines:
Run Forts and go to Sandbox. Start a map and go to the Player tab. You should see under the Physics category the name of the mod folder. Select that, start the Sandbox and watch things float about. Congratulations! You’ve made your first mod.
As you know we’ve already made a zero gravity mod, and the mod name is zerogravity. We found that setting the gravity to zero wasn’t the only change needed. We also reduced the drag so ships could move faster and the maximum angle at which a strut will accept a device, and changed a few other things. You might also find that making a mod requires more changes than you anticipated.
Because there can be any number of mods active, the data being modified is not necessarily what is in the base game. The base file is loaded, then the first mod, then the next mod, and so on. Each mod is applied to the changes made by the mods before it.
The order that mods are applied in is influenced by the optional Priority value in the mod.lua file. Lower values are applied first. Higher values are applied last, and so tend to have the final say. The expected range is 1 to 10, and the default is 5. If two mods have the same priority the order is alphabetical according to the mod name (or Workshop published id).
If a mod should make a change to every item, it should have a high value for Priority so it is applied last. The fast-build mod, for example, has a building_material.lua file which iterates the material items, including any that came from mods applied before it, and adjusts their build and scrap time like so:
Also, don’t be dependent on the data being untouched. If you want your new weapon to appear in a particular location you need to look for the position of the weapon you want it to appear after and insert it after that. Examples can be found in the weapon_pack mod. The Rocket is positioned after the EMP Rocket:
This works in practically all configuration scripts. In a specific device configuration script, or device.lua, to double production, for example:
Commanders use this system to apply changes to modded devices, weapons, materials, projectiles, and more. For example, Architect reduces build times in weapon_list.lua with a named function, like so:
= «upgrade» then device.BuildTimeComplete = 0.25*device.BuildTimeComplete end end end RegisterApplyMod(CommanderApplyModBase)
All commander ‘ApplyMod’ functions have the same name. If you are modding a commander and want to prevent this from functioning, you can remove it using the DeregisterApplyMod function:
You are free to name your own functions so that other mods can remove yours, just keep in mind that earlier mods may have defined such a function too. Make sure you give them a unique name, or you could overwrite a previous mod’s value.
NOTE: The older ApplyMod system is deprecated. It is still functional but we don’t recommend using it, and we may remove it at some point in the future.
The critical file in this mod is devices/device_list.lua. The first part of this script creates new sprites based on the included textures, found in ui/textures/HUD. The DetailSprite and ButtonSprite helper functions are defined in data/ui/uihelper.lua, and the Sprites table is read by the game to create any sprites defined by the configuration script. The ‘path’ variable is set by the game to the relative or absolute path of the mod (in the case of a subscribed mod), allowing it to reference new texture assets stored in the mod’s directory. You don’t need to understand exactly how this works, but if you keep your texture files in the same location and update the names it should work.
Moving down a bit, you’ll see where the new device is added to the Devices table.
You can open devices/sandbags_large.lua to see what detailed parameters are set. This is where you would make the device behave different to other devices. You can look at the devices included with the game and the weapon_pack mod to see what variables to change and what values would be appropriate. It’s a good idea to play around with the values to see what feels good, rather than just using the first values that occur to you. Testing with friends helps to get feedback.
In the middle of the file you’ll see a new Sprites table, which sets the single-frame sprite of the sandbag to the included texture /devices/SandbagsLarge.tga. Note the use of the path variable again. The following forward slash is important as it’s not included in the path variable.
Further down you’ll see the Root table, which configures how multiple sprites fit together to make a single device. This can be a complex set of nested tables for a weapon, as there are multiple parts and a pivot where the gun rotates. This structure specifies where projectiles and beams are emitted from by creating a «Hardpoint0» child node (with no Sprite value set). If you want to create a new weapon it’s best to copy an existing one and experiment with Root until you understand how it works. The Angle, Pivot and PivotOffset values determine how child nodes are positioned relative to the parent. UserData is set to the percentage of construction at which the node will appear (or disappear on scrap).
The other gameplay related change the Large Sandbags mod does is reduce the damage the 20mm cannon does to it. You’ll find this in mods\weapon_pack\weapons\projectile_list.lua. This is a mod of a mod (or a nested mod). It’s changing the way the weapon_pack works because the damage multiplier versus a device is associated with the projectile. It is set like this:
Devices (and weapons) can have one or more upgrades, with optional prerequisites (see the Prerequisites section below). This is achieved by adding an Upgrades table to the device in device_list.lua (or weapon_list.lua for weapons).
The entries in this table set the SaveName and cost of the upgrade, and can also set a button sprite for the context menu. Although the detail sprite of the device will be shown on rollover, when there are multiple upgrades custom buttons are recommended so the player can tell them apart easily.
The ButtonSprite helper function can be used to make the button sprite so it has disabled, rollover and pressed states. The built-in textures with path ui/textures/context/HUD-Buttons-Blank-*.tga can be copied and edited to create new buttons.
Upgrades can be disabled at start by setting Enabled = false, and later enabled by mission or mod script by using the EnableDeviceUpgrade or EnableWeaponUpgrade functions.
If you are modding an existing device then make sure to insert your upgrades rather than setting the table from scratch, to prevent the loss of the existing upgrades, or those added by other mods.
By default materials and devices can be built if the player has enough resources. It’s possible, however, to add a requirement to build a certain device or a combination of devices first. This is how the ‘tech’ buildings operate to restrict construction.
Both materials and devices (which includes weapons) have the same syntax for the Prerequisites variable. If it is left as nil, then it can always be built.
If assigned to a string then at least one device with that SaveName must be built before the material or device can be constructed:
There is an obsolete method of setting an alternative required device, but we recommend you use the more flexible syntax below. In the following example the item can be built if the workshop or the armoury has been built.
You can also set up a list of combinations of device SaveNames for complex requirements. If any one of the combinations is satisfied then the item can be built. In the following example, the item can be built if the workshop and the upgrade centre is built, or the factory alone is built. This list of combinations can be as long as you like.
Device upgrades can have their own prerequisites set in the same way. If the upgrade’s Prerequisite variable is not set then it defaults to the prerequisites of the target device of the upgrade.
Beams operate over a period of time, set by the BeamDuration variable of the weapon, and so have configuration options that projectile weapons don’t. The simplest way of setting up their width and damage is with the ProjectileThickness and ProjectileDamage variables in the weapons/projectile_list.lua item, which remain constant. ProjectileDamage for beams means ‘hitpoints per second’.
In addition, beams can have time functions for thickness and damage. This is to allow more dramatic wind up, wind down and oscillation. To achieve this you can implement the BeamThickness and BeamDamage functions in your weapon configuration script. They take a time value (relative to the end of FireDelay), and return a value which represents the instantaneous thickness and damage (still in hitpoints per second) of the beam.
Within the weapon configuration script, the constant variables and the result of the functions can both be modified with BeamThicknessMultiplier and BeamDamageMultiplier. They default to 1.
Here is part of the Plasma Laser weapon configuration script as an example. To allow more intuitive tuning of the beam we organise the data in a time-keyed table, BeamTable, and then use InterpolateTable to calculate intermediate values.
With the High Seas DLC update in March 2022, the ability to specify these functions as part of the projectile item was introduced. This was necessary because the Ammo system allowed a weapon to produce multiple beams. Also added was a new sprite which tracks the collision end point of the beam, described below. The Orbital Sweep projectile gives an example:
WARNING: name your beam table something unique to your mod. Using the same table name will overwrite previous values and change the behaviour of other beams.
Prior to High Seas, beams could only have one visual layer. Now it’s possible to have multiple layers, each with their own thickness functions, scroll rate, tile rate, and additive value.
They could also only have an effect produced at collision points. We needed more control of this, so we added an optional sprite with its own thickness function. It will exactly track the endpoint of the beam, even if it moves rapidly.
The sprites for each beam layer should specify «repeatS = true,» to make the texture tile along the length of the beam.
The Orbital Sweep beam is an example:
The High Seas update also introduced the concept of beams having a maximum distance of travel, which continues through reflections and when passing portals (which add no distance themselves). The beam will stop abruptly after this distance has been reached, like a light saber. It can be adjusted by setting the BeamMaxTravel variable of the projectile item. It defaults to a large number, so will not affect legacy beams.
Right clicking on a strut will bring up a context menu, including a number of buttons with material icons. These buttons can be used to convert the strut into a different material. By default this list of materials is set to the contents of the DefaultConversions table in the base building_materials.lua file:
This list can be modified like anything, but it’s also possible to customise it for a specific material by setting the Conversions table. It’s best to merge any new materials with the DefaultConversions table, to keep the changes introduced by other mods. To allow a material to be convertible to a portal in the context menu, for example:
In order for this to work the material to be included must have the Context variable set to the name of a valid sprite. The ButtonSprite function from ui/uihelper.lua must be provided with a path in order for it to find the textures within the mod’s ui/textures folder:
You can add custom effects to your mods such as explosions, muzzle flashes, and projectile trails. These can including new textures and sound effects, or instead use existing assets from the game. Reference these new effects from your other scripts using the file’s name relative to your mod’s ‘path’, for example in a device script:
Effect scripts take the following general format, for example:
The following effect types are available:
Creates a single textured quad that can move, rotate, scale and blend between two colours. See example above.
Creates a series of bursts made up of sprites with rules about how they are positioned, sized and rotated depending on the direction they are emitted.
Creates a textured streamer which follows the position of the effect.
Makes the camera move rapidly depending on how close it is to the effect.
In Forts all languages are implemented as mods. You can inspect the base string tables in the Forts/data/mods/language-* folders to see what files are available for modding. In order to change or extend string tables for your mod you need to mod these language mods. Using the Large Sandbags mod as a reference again, you will see the following folder structure (with English expanded as an example):
If you opened mods/language-English/devices/strings.lua, you will see:
This shows how the strings describing the new device are merged into the sub-string table called Device. The string ids, like «sandbags_large», and «sandbags_largeTip2», are automatically generated from each device SaveName to look for the strings to show.
If you are replacing an existing string, you can just overwrite it, as in the Scattershot commander string.lua example:
A few features were introduced with the Moonshot DLC that are not available in the base game. If you wish to make use of these features then your mod becomes dependent on Moonshot, and can only be activated when the host of the game has it installed (which is always you in single player games). These mods are displayed with a blue Moonshot icon in the mod selection screen.
When you make a Moonshot dependent mod, you must add a flag to your mod.lua file so the game can quickly identify it as such. You may get an error message if you try to publish a mod that depends on moonshot and does not have this flag:
The features and their associated keywords which trigger dependency are outlined below. Note that if these words are found anywhere in the appropriate file it will become dependent, even if it’s out of place or in a comment.
If you want to make use of Moonshot features when they’re available, but still allow your mod to run without them working if Moonshot is not available, then use this flag instead:
The game will automatically set two variables, dlc1Var_Active and dlc1Var_Value. These are set to true and 1 if Moonshot is available, and false and 0 if it’s not, respectively. You can use these to prevent the addition of weapons which don’t make sense, for example.
The keyword Portal in building_materials.lua triggers dependency. This allows a material to teleport projectiles and beams when two such struts are linked by the player.
The keyword MaxBursts in a weapon script, or weapon_list.lua will trigger dependency. When used in a weapon script (e.g. machinegun.lua) the weapon will self destruct after firing that many times. This is used on the Moonshot only Buzzsaw weapon.
The keyword RayDamage in the projectile_list.lua file will trigger dependency. This is used in combination with a few other variables to create damage in a straight line when a projectile collides with a strut. The buzzsaw projectile, for example:
The keyword FieldRadius in the projectile_list.lua will trigger dependency. This is used in combination with a few other variables to create a field for various purposes. It is used to implement smoke and to attract projectiles to the magnabeam point of impact. For example, the smoke projectile uses it like so:
The options for FieldType are:
By adding a script.lua file in their root folder, mods can have arbitrary Lua script executed based on events triggered by the game, including projectile impacts, destruction of devices and weapons, ownership changes and user input. There are also events for the initial load, physics frame, display frame, and restart. Functions can also be scheduled to execute at a specific time in the future. They behave identically to mission scripts, but are not tied to a specific map.
In response to these events the mod script can perform a host of changes to the game state, create effects, or show controls on the screen. It can also track any state it wishes in the ‘data’ table, which will automatically be serialised for the purpose of replays and players joining a battle.
The details of this dynamic mod scripting can be found at the Forts Scripting API Reference [www.earthworkgames.com] page, which is generated directly from the Forts source code with mark up to provide descriptions.
To make your mod easy to find on the Steam Workshop and in the game’s mod selection screen, we recommend you put it into a category. This is set in the (optional) mod.lua file you put in the mod’s base folder. This will apply a tag to the item in the Workshop, useful for searching for those of interest. In the game it will put the mod into a branch of a tree view which can be collapsed for quick browsing.
An example mod.lua would be
If mod.lua is missing, the Category variable is not specified, or it’s invalid then the mod is placed in the Misc category. Valid categories are:
Once you are happy with how your mod is working locally, you can upload it to the Steam Workshop. Before you do this you need to create a preview.jpg file in the mod’s folder which will represent it in Forts and on Steam Workshop. The size isn’t so important, but the aspect ratio should be 16:9 so it appears correctly in Forts. The map previews are 1024*576, for example. This is fine for mods too.
Now to publish the mod, go to the main menu and then enter the Workshop menu. Go to the Upload tab and select the mod you’ve been working on. Click on the Upload button, and then Yes. After a short while it will open the new item in the workshop. You should be subscribed to it automatically, and you should make it either hidden or visible to friends only for testing. To make sure the mod will work for others, you should get a friend to subscribe to it and run the game with it. Otherwise you should rename your mod folder and run the Workshop version of the mod. This will bring to light any asset path problems that had been missed during development. Change the folder name of you mod back to edit and update once the problems are fixed.
You can force a Workshop mod on in your custom map, in the same way as a built-in mod. In your map’s mission script, add or edit the Mods table to include the published file id. For example, to make sure Large Sandbags are available in your map:
To make it easier to understand, you could write it like this instead:
Forts Scripting API Reference
This document provides details on the Application Programming Interface (API) between Forts and scripts used for mission and mod implementation.
There are two types of functions listed below: ‘script functions’ and ‘events’.
Basic Script Example
The main entry points are the Load, Update and OnRestart events. The script can use the built-in function ScheduleCall to make things happen later.
Mission scripts
On creation of the map this file is automatically made and takes the name of the map folder, such as maps/Vanilla/Vanilla.lua. If the requested map name contains non-ANSI characters it will be something like maps/playermap1/playermap1.lua.
These scripts have a few settings specific to maps, such as to force on mods and to mark the map as symmetrical:
WARNING: mission scripts don’t run in Sandbox. Use Skirmish or Multiplayer to test them.
Mod scripts
Mods can have an optional file in their root, such as mods/sandbags_large/script.lua. If the mod is active and script.lua exists the game will load it. It behaves just like a mission script, but is not tied to a specific map.
Storing state
It’s possible for the script to set values that last longer than the current call. This can be useful for tracking objects, statistics, and AI state. It must be done with care to avoid desyncs, however.
To do this correctly all state must be stored within the data table, which is automatically written and restored by the game for each script, to allow late joining and replay seeking. Sub-tables are fine, but function values must be avoided, as these can’t be serialised.
When a player joins a game in progress, the host writes the data table of each script to a file, and sends this to the new player to bring them up to speed. This means that the data table should not contain anything that is unique to a player (i.e. non-deterministic). For example the value returned by GetLocalTeamId, or the time the player last pressed a button. You are likely to experience unexpected behaviour if you do this.
WARNING: setting values outside the data table will cause errors at run time.
WARNING: do not store non-deterministic values in the data table, such as the local team Id.
Debugging
Finding out where your script is going wrong is an important skill. You can use Log to see where execution gets to and the value of variables.
The console will show output of Log, plus syntax error and exception messages. The log.txt file in your Forts/users/(steamid) folder will also record them in full.
AddTextControl and SetControlText can be used to display information in a convenient place on the screen.
The functions SpawnCircle and SpawnLine are useful for checking your maths and verifying assumptions.
WARNING: remove or switch off debugging before publishing to avoid negatively affecting the experience for players.
Teams and Sides
So far Forts has been designed to be one side against another, i.e. two sides. Plus, there can be multiple forts on each side. Due to the variability of maps and flexibility of multiplayer configuration there may not be enough forts for every player to get their own fort. Therefore a ‘team’ in forts can be one or more players, and a ‘side’ is one or more allied teams.
Originally Forts was designed to be co-op only, so there were only two teams, which were synonymous with sides: 1 and 2. When we decided to add Team Deathmatch (TDM) we had to expand this to support multiple teams per side. There was already a signficant amount of code passing around a single value representing ownership. So instead of passing a new, separate value representing the team of the side that single number was changed to encode both side and team.
The implementation is that the least significant digit represents the side, of which there are only two (1 and 2). Added to this are multiples of 100 (i.e. MAX_SIDES) representing the team on the side. So there can be multiple players on each team, and multiple teams on each side. From that single teamId you can determine if two objects are on the same team, as before, by simply:
In addition, the modulo operator (%) can be used to inspect the least significant digit: the side. See if the teams are on the same side like this:
For example, in a 4v4 TDM game (with anti-air enabled), there will be the following teams:
Teams 1 and 2 are for the AI scripts which control the automatic defenses of all teams on their side.
In a human only co-op game there will only be the following teams:
In a co-op game with AI, however, there may be teams such as 102, 202, etc. This is because the AI operates like it does in TDM, as it would be difficult to coordinate multiple AI forts with their own builds in one script state.
Some script functions expect either a sideId (1 or 2), or a teamId (1, 2, 101, 201, 102, 202, etc.). If they expect a sideId they will typically take a teamId and calculate the sideId (teamId%MAX_SIDES). An example is GetDeviceCountSide, which will allow you to enumerate all devices for a side. It will take a teamId such as 101 but work out the side to be 1. If you want the devices for a team, you would use GetDeviceCount instead.
There are a few special ‘teams’ as well, that players can’t normally be assigned to, such as observers (TEAM_OBS). The values defined in forts.lua are:
Script Functions
These are used to make the game do something, or retrieve some information from it.
An example would be CreateNode, to create a new node, or NodePosition, which queries the world position of a node.
Events
These are functions implemented by a script to be told when something happens in the game. They generally start with ‘On’, but there are a few exeptions.
For example, a script might want to know when a device is destroyed. In this case the script could write the OnDeviceDestroyed function.
Reference
WARNING: Use this only for debugging, as it can clutter the console and log
WARNING: Calling this frequently will slow down the game significantly
Example Lua usage:
LogToFile
Write a message to log.txt
(same as Log but doesn’t display the message in the console)
Example Lua usage:
ExecuteInScript
Run Lua instruction immediately in the script with the given filename and teamId
Will not turn a non-deterministic event into a deterministic one. For this use SendScriptEvent instead.
This can’t easily differentiate different mod scripts since they may have the same filename, script.lua.
Example Lua usage:
SendScriptEvent
Run a Lua function with given parameters on all game instances simultaneously
Can be used to make non-deterministic events deterministic, such as user input
functionName: the name of the function to call
params: the parameters to use as represented by a string, not including parentheses
scriptName: the name of the script to call the function on. When empty all scripts are attempted.
toSelf: mods can pass true to run it only for their script
See also: OnKey, OnControlActivated
Example Lua usage:
AddStrings
Load strings into string translation table
Example Lua usage:
StringExists
Query if a string exists in the translation table
Example Lua usage:
InReplay
Returns true if the current game is a replay
Example Lua usage:
IsPaused
Returns true if the game is paused
Example Lua usage:
GetGameMode
Returns «Multiplayer», «Campaign», «Skirmish» or «Sandbox»
Example Lua usage:
Notice
Drops a notification in the console without string translation
Example Lua usage:
GetConstant
Query the value of a constant of type float
Example Lua usage:
GetConstantString
Query the value of a constant of type string
Example Lua usage:
GetRule
Query the value of a rule by teamId and name, of type float
Example Lua usage:
End the battle and load another
This is for single player only
side1Score: obsolete (not used for anything)
nextMap: the new map to load, can be «next» to advance a linear campaign
Example Lua usage:
EnableAI
Enable the Artificial Intelligence for a particular team, to use a specific fort script, difficulty and fort position
Call this in your Load event
teamId: the team to assign the fort script to
fort: the filename of the script, relative to the map folder with no extension
difficulty: how hard the AI should be 1
fortIfPos: integer position of the fort (-1 will auto select)
See also: Load
Example Lua usage:
GetRandomFloat
Generate and consume a deterministic random value
Use this only for critical game state changes
lower: the lower limit of the random value
upper: the upper limit of the random value
desc: a text description of the intended use, required for debugging
returns: a random value between lower and upper, inclusive
See also: GetNormalFloat, GetRandomInteger
Example Lua usage:
GetRandomFloatLocal
Returns a non-deterministic random float between lower and upper
Use GetRandomFloat for gameplay critical values
Example Lua usage:
GetNormalFloat
Generate and consume a deterministic random value within the normal distribution
Use this only for critical game state changes
Example Lua usage:
GetNormalFloatLocal
Returns a non-deterministic random float within the normal distribution
Use GetNormalFloat for gameplay critical values
Example Lua usage:
GetRandomInteger
Generate and consume a deterministic random integer value between lower and upper
Use this only for critical game state changes
Example Lua usage:
GetRandomIntegerLocal
Returns a non-deterministic random integer between lower and upper
Use GetRandomInteger for gameplay critical values
Example Lua usage:
SpawnEffect
Spawns an effect of the given name
Example Lua usage:
SpawnEffectEx
Spawns an effect of the given name (with extended options)
Example Lua usage:
CancelEffect
Destroys the effect with the given id
Example Lua usage:
DisableEffect
Prevents the effect with the given id spawning more particles, trail, etc.
Example Lua usage:
SetEffectPosition
Moves the effect with the given id
Example Lua usage:
SetEffectDirection
Changes the direction of the effect with the given id
Example Lua usage:
AddToEffectLifeSpan
Adds to the life span of the effect with the given id, returns new life span
Example Lua usage:
SpawnCircle
Spawns a temporary circle effect
Intended for debugging only
returns: the effect id which can be passed to CancelEffect, DisableEffect, SetEffectPosition, SetEffectDirection and AddToEffectLifeSpan
Example Lua usage:
SpawnLine
Spawns a temporary line effect
Intended for debugging only
returns: the effect id which can be passed to CancelEffect, DisableEffect, SetEffectPosition, SetEffectDirection and AddToEffectLifeSpan
Example Lua usage:
AttachEffectToControl
Attaches an effect so it is drawn after the control
effectId: the id returned from SpawnEffect
See also: SpawnEffect
Example Lua usage:
LightAll
Changes the colour of all AlienFX lights, with optional pulsing
Example Lua usage:
IgniteFire
Sets fire to any flammable structures under a circle
teamId: the exact team to affect. Can be TEAM_ANY.
Example Lua usage:
TipsEnabled
Query whether the player has tips enabled in their options
Generally this should be tested and respected when using ShowTip
returns: true if the player doesn’t want tips showing
See also: ShowTip, ShowTipChecked
Example Lua usage:
ShowTipChecked
Triggers a tip graphic with a specific stringId, has a checkbox to not show the same tip again
Avoid using tips if TipsEnabled() returns false
filename: the path of the graphic to show
stringId: the string id to use for translation
checkboxId: A unique name to identify this checkbox, to allow permanent disabling
forceCloseExisting: Force hide/replace any currently displayed tip
returns: true if the tip was successfully shown
See also: ShowTip, HideTip, TipsEnabled
Example Lua usage:
ShowTip
Triggers a tip graphic with a specific stringId
filename: The path of the graphic to show
stringId: The string id to use for translation
returns: true if the tip was successfully shown
See also: ShowTipChecked, HideTip, TipsEnabled
Example Lua usage:
HideTip
Makes the currently shown tip invisible, if any
Example Lua usage:
EnableTipDismissal
Causes tips to ignore or accept user dismissal
Example Lua usage:
EnableLobbyAlerts
Allows suppression of lobby alerts
Example Lua usage:
IsTipVisible
Query if a tip is currently visible
returns: true if a tip is being shown
Example Lua usage:
SetControlFrame
Determines whether UI functions work in screen space or world space
This value is persistent for the calling script, until changed by this function
Equivalent to the worldRelative parameter passed to the Add* UI functions
frame: FRAME_SCREEN (0) or FRAME_WORLD (1)
Example Lua usage:
GetControlFrame
Indicates whether UI functions work in screen space or world space
returns: FRAME_SCREEN (0) or FRAME_WORLD (1)
See also: SetControlFrame
Example Lua usage:
GetChildCount
Query the number of child controls of a control
returns: how many children the control has
See also: SetControlFrame
Example Lua usage:
GetChildName
Query the name of a child control
index: the zero-based index of the child. Use GetChildCount to get the upper limit.
returns: the name of the child. Empty string if index is invalid.
See also: SetControlFrame
Example Lua usage:
GetControlRelativePos
Query the position of a control relative to its parent
Example Lua usage:
GetControlAbsolutePos
Query the position of a control relative to the root control
Example Lua usage:
SetControlRelativePos
Set the position of a control relative to its parent
Example Lua usage:
SetControlAbsolutePos
Sets the position of a control relative to its root control
Example Lua usage:
SetControlLayoutX
Sets the dynamic layout script for the horizontal position of a control
Example Lua usage:
SetControlLayoutY
Sets the dynamic layout script for the vertical position of a control
Example Lua usage:
SetControlLayoutW
Sets the dynamic layout script for the width of a control
Example Lua usage:
SetControlLayoutH
Sets the dynamic layout script for the height of a control
Example Lua usage:
EvaluateLayoutScript
Force a UI control to re-evaluate its layout script
recursive: true means recursively evaluate child controls
Example Lua usage:
GetControlSize
Queries the width and height of a control
returns: a Vec3 containing the width and height
See also: SetControlFrame
Example Lua usage:
SetControlSize
Sets the width and height of a control
size: a Vec3 with x set to the width and y set to the height
See also: SetControlFrame
Example Lua usage:
SetControlStyle
Sets the style of a control, which affects font size, outline, shadows, colour, etc.
style: styles are defined in ui/styles.lua
See also: SetControlFrame
Example Lua usage:
GetControlStyle
Query the style of a control
returns: the style name of the control. Empty if not found.
See also: SetControlFrame
Example Lua usage:
LoadControl
Loads a control tree from a file and adds it to the specified parent
Example Lua usage:
AddTextControl
Creates a new text control
Example Lua usage:
AddTextButtonControl
Creates a new text button control
name: the name of new control
parent: the parent of the new control. Empty string means the HUD root.
text: the initial content of the text button
anchor: one of the ANCHOR_* values defined in forts.lua
pos: the position of control relative to its parent
worldRelative: true means the text size is constant relative to world objects
style: one of the styles defined in ui/styles.lua
Example Lua usage:
AddSpriteControl
Creates a new texture or animated texture control
name: the name of new control
parent: the parent of the new control. Empty string means the HUD root.
sprite: the initial texture or sprite of the control
anchor: one of the ANCHOR_* values defined in forts.lua
size: the size of control
pos: the position of control relative to its parent
worldRelative: true means the text size is constant relative to world objects
style: one of the styles defined in ui/styles.lua
Example Lua usage:
AddButtonControl
Creates a new texture or animated texture control
parent: the parent of the new control. Empty string means the HUD root.
name: the name of new control
sprite: the initial texture or sprite of the control
anchor: one of the ANCHOR_* values defined in forts.lua
size: the size of control as a Vec3
pos: the position of control relative to its parent
style: one of the styles defined in ui/styles.lua
Example Lua usage:
AddListItem
Adds a new list item to an existing list box
parent: the parent list box to add the item to
name: the name of new list item
text: the display text for the item
minContentsHeight: if > 0, will resize listbox height to match contents, limiting min listbox height to this value
maxContentsHeight: if > 0, will resize listbox height to match contents,limiting max listbox height to this value
See also: ClearListItems
Example Lua usage:
ClearListItems
Clears all items for a list box
parent: the of the list box
name: the name of list box to clear
minContentsHeight: if > 0, will resize listbox height to this value
See also: AddListItem
Example Lua usage:
SetButtonCallback
Sets the numerical activation id associated with a control
Example Lua usage:
CenterControl
Centers a control horizontally and vertically relative to its parent
The screen is used if there’s no parent
Example Lua usage:
SetControlText
Changes the content of a text or text button control
Triggers the re-evaluation of dynamic layout under the parent
parent: an empty string means the HUD root
See also: SetControlFrame
Example Lua usage:
SetControlTextW
Changes the content of a text or text button control
Triggers the re-evaluation of dynamic layout under the parent
parent: an empty string means the HUD root
See also: SetControlFrame
Example Lua usage:
AddContextButton
Adds a customised button on the context menu
When the button is pressed the script is notified by a call to OnContextButtonDevice or OnContextButtonStrut
WARNING: Only call this from OnContextMenuDevice and OnContextMenuStrut
Example Lua usage:
SetWordWrap
Sets the word wrap of a text control within a sprite control parent
Example Lua usage:
SetControlSprite
Sets the texture or animate texture of a sprite or button control
Example Lua usage:
SetControlSpriteByParent
Sets the texture or animate texture of a sprite or button control
Differs from SetControlSprite by using the parent parameter to disambiguate the control
Example Lua usage:
SetSpriteState
Sets the state of an animated texture on a sprite or button control
Example Lua usage:
SetSpriteAdditive
Controls additive rendering of a sprite or button control
Example Lua usage:
RotateSpriteControl
Turns the rendering of the texture by a number of 90 degree rotations
Example Lua usage:
ShowControl
Makes a control visible or not
Example Lua usage:
DeleteControl
Destroys a control
Example Lua usage:
SetControlColour
Changes the colour of a control
Example Lua usage:
AddGhostDevice
Creates a new ghost device/weapon
Useful for instructing players in a cutscene
Example Lua usage:
ClearGhostDevices
Destroys all ghost devices
Example Lua usage:
ShowWorld
Turns rendering of the world on or off
Example Lua usage:
ClearPrimaryMidgroundRenderOrder
Clears midground primary structure render order override
Example Lua usage:
AddPrimaryMidgroundRenderOrder
Adds a midground primary structure render order override
If used, make sure all primary structures have been added or they will not be rendered
structureId: The structure id to render
Example Lua usage:
EnablePauseMenu
Enables or disables the pause menu
If the pause menu is active when disabled the pause menu will be hidden
Example Lua usage:
EnablePauseMenuItem
Can prevent the addition of an option to the pause menu
name: values can be «Revert», «Resume», «InstantReplay», «Next»
Example Lua usage:
Pause
Pauses or resumes the battle
Example Lua usage:
EnableExpandedHUD
Enables or disables the full screen HUD
Example Lua usage:
MuteAllSounds
Pauses all sounds
Used to suspend sounds while playing a movie mid-battle
Example Lua usage:
EnablePhysics
Enables or disables physics simulation
Used to suspend physics while playing a movie mid-battle
Example Lua usage:
EndReplay
Prevents the replay recording any further gameplay
Used at the start of complex tutorials and when movies are played at end of battles
Example Lua usage:
EnableProduction
Enables or disables devices produces resources
Used during cutscenes to prevent accumulation
Example Lua usage:
GetProductionEnabled
Queries whether resource production is enabled
Can be affected by EnableProduction
Example Lua usage:
EnableTip
Enables or disables a specific tip by name
name: tip names can be found in mods/language-English/db/strings.lua
Example Lua usage:
EnableGrid
Enables or disables the grid used by the player to snap nodes and ground devices
Example Lua usage:
HideHUDOnRevert
Automatically hides the HUD after the player restarts the battle
Example Lua usage:
ShowHUD
Shows or hides the HUD, with or without animation
Example Lua usage:
ShowHUDTab
Shows or hides a tab on the HUD
name: one of «materials», «devices», «tech», or «weapons»
Example Lua usage:
OpenHUDTab
Gives focus to a tab on the HUD
name: one of «materials», «devices», «tech», or «weapons»
Example Lua usage:
EnableStartGameEffect
Turns on or off the horn sound at the start of a battle
Example Lua usage:
ShowLetterbox
Turns on or off the letterbox used in cutscenes
Example Lua usage:
LetterboxVisible
Queries whether the letterbox is visible
Affected by ShowLetterbox
Example Lua usage:
EnterGameOverMode
Prevents the player having any control and starts the end of battle process
Example Lua usage:
ShowResult
Sets the winner of the battle to winningTeamId and ends the battle
Example Lua usage:
SetTrucePeriod
Sets the truce period for a side
teamId: team side to modify
trucePeriod: new truce period
Example Lua usage:
SetTruceUIVisible
Sets the truce period UI visibility for a side
teamId: team side to modify
truceUIVisible: truce UI Visibility
warningEnabled: when false suppresses the truce countdown audio warning
Example Lua usage:
GetLocalTeamId
Queries the teamId of the local game instance
you should only affect things like user interface, enabled items, etc.
Use SendScriptEvent to execute code synchronously across all instances
WARNING: Do not directly alter the game state based on the local team or you will cause a desync
Example Lua usage:
ClearSimulation
Destroys all structures, devices and projectiles
Example Lua usage:
LoadStructureFile
clearSim: destroys the current contents of the world
structurePaintedCallback: when true OnStructurePainted is called to allow discovery
Example Lua usage:
PlayMovie
Starts movie playback on a sprite or button control
Example Lua usage:
PauseMovie
Pauses or resumes movie playback on a sprite or button control
Example Lua usage:
EndMovie
Stops and cleans up movie playback on a sprite or button control
Example Lua usage:
GetMovieProgress
Queries how much of the movie has completed playback in relative terms
returns: a number between 0 and 1 representing progress
Example Lua usage:
GetMovieTime
Queries how much of the movie has completed playback in seconds from the start
returns: the time in seconds since the beginning of the movie
Example Lua usage:
StartStream
Starts streaming an audio file, fmod event, or list of at the given volume
Calls OnStreamComplete when the stream ends
Intended for audio dialog clips
filename: can be a file path, fmod event name, or a constants table of these
volume: the volume to play the stream at
returns: the id which can be passed to PauseStream, FadeStream and other stream functions
See also: PauseStream, PauseStreamOnAdvance, FadeStream
Example Lua usage:
PauseStream
Pauses a stream started by StartStream
Example Lua usage:
PauseStreamOnAdvance
When pause is true the stream pauses itself when it ends
Example Lua usage:
ContinueStreamOnPauseMenu
Stream resumes when pause menu is shown
Example Lua usage:
StartMusic
Plays an individual music file or fmod event
Example Lua usage:
StopAllStreams
Ends all streams started by the current script
Example Lua usage:
DisableMusic
Prevents dynamic music operating
Example Lua usage:
FadeStream
Reduces the volume of a stream over duration
Example Lua usage:
AdjustStreamVolume
Changes the volume of the stream over duration
Example Lua usage:
StopStream
Stops a stream started by StartStream or StartMusic
Example Lua usage:
SetAudioParameter
Sets a audio parameter on a specific effect instance
Example Lua usage:
SetGlobalAudioParameter
Sets a global audio parameter
Example Lua usage:
LockControls
Prevents or allows the player to interact with the game
Example Lua usage:
EnableKey
Allows or blocks a key from being registered
Doesn’t work for observers
Example Lua usage:
EnableCursor
Shows or hides the cursor
Doesn’t work for observers
Example Lua usage:
SetMouseCursor
Changes the appearance of the cursor
mode: one of the MOUSE_* values from constants.lua
force: when true the mode will be sticky; ordinary cursor control won’t work
Example Lua usage:
SetCursorColour
Changes the colour of the cursor
Example Lua usage:
GetWorldExtents
Queries the minimum and maximum x and y of the world
returns: extents are returned in a table containing MinX, MaxX, MinY, MaxY and Zoom
See also: GetCamera
Example Lua usage:
RestoreScreen
Sets the player’s view to a named screen position
Example Lua usage:
RestoreSystemScreen
Sets the player’s view to one of the standard cameras
index: 0 = overview, 1 = team1, 2 = team2
duration: how long it takes the camera to move there. Can be zero to be instance.
See also: CancelCameraMove
Example Lua usage:
SetSystemScreenFromName
Assigns a named screen to one of the system screens
index: 0 = overview, 1 = team1, 2 = team2
Example Lua usage:
CancelCameraMove
Stops the current camera movement
Example Lua usage:
SetViewExtentsByNameRaw
Limits the player’s view using a named screen
Example Lua usage:
SetViewExtentsByName
Limits the player’s view using a named screen
Only applied if local player is not an abserver
Example Lua usage:
SetViewExtentLeft
Limit the player’s view to the left
Example Lua usage:
SetViewExtentRight
Limit the player’s view to the right
Example Lua usage:
ClearViewExtents
Resets the player’s view limits to the world extents
Example Lua usage:
IsPointVisible
Query if a world position is visible
worldPos: the point to test
screenName: optional named screen (empty for the current view)
returns: true if the point is within the screen
Example Lua usage:
ShowReactorBarPanel
Shows or hides the reactor panel
Example Lua usage:
SetReactorButtonEnabled
Enables or disables the button which jumps to a particular reactor
index: the index of the reactor to affect
enabled: set to false to disable
See also: ShowReactorBarPanel
Example Lua usage:
ShowTransactions
Show or hide resource transactions
Example Lua usage:
ShowBuildCostPreview
Show or hide the build cost preview
Example Lua usage:
EnableMaterial
Enable or disable a material for a side
saveName: can be «*» to apply to all materials
Example Lua usage:
EnableDevice
Enables or disables a device for a side
saveName: can be «*» to apply to all devices
See also: EnableWeapon
Example Lua usage:
EnableWeapon
Enables or disables a weapon for a side
saveName: can be «*» to apply to all weapons
See also: EnableDevice
Example Lua usage:
SetDevicePopulationCap
Sets the maximum number of devices or weapons a side can build
Example Lua usage:
AddDeviceNodeEffect
Attaches an effect to a node of a device or weapon
sideId: which side to affect (1 or 2)
saveName: the internal name of the device or weapon
nodeName: the name of the part to attach to
effectPath: the file path of the effect
automatic: enables and keeps the effect running (otherwise it’s set up but won’t run)
See also: ConfigureDeviceNodeEffect
Example Lua usage:
ConfigureDeviceNodeEffect
Changes configuration of a previously added node effect
sideId: which side to affect (1 or 2)
saveName: the internal name of the device or weapon
nodeName: the name of the part to attach to
effectPath: the file path of the effect
automatic: enables and keeps the effect running (otherwise it’s set up but won’t run)
actualTeam: sideId is really the teamId, allowing a team’s current devices’ effects to be activated
See also: AddDeviceNodeEffect
Example Lua usage:
EnableDeviceUpgrade
Enable or disable the upgrade of one device to another for a side
Example Lua usage:
EnableWeaponUpgrade
Enable or disable the upgrade of one weapon to another for a side
Example Lua usage:
Deselect
Causes the player to lose any current selection
Example Lua usage:
GetLinkCountOfTeam
Returns the number of struts in a specific team of a side, e.g. 1, 101, 201
Example Lua usage:
GetLocalSelectedDeviceId
Query the current device selection
Example Lua usage:
GetMouseAiming
Query whether the player is currently aiming
Example Lua usage:
GetDeviceCount
Query the number of devices on a team
Includes weapons (which are specialised devices)
returns: the number of devices on teamId
See also: GetDeviceId
Example Lua usage:
GetDeviceId
Query the id for a particular device at index on a team
Use GetDeviceCount to get suitable values for index (zero based)
returns: the id of the device at index
See also: GetDeviceCount
Example Lua usage:
GetDeviceCountSide
Device count includes weapons (which are specialised devices)
returns: the number of devices on sideId
See also: GetDeviceIdSide
Example Lua usage:
GetDeviceIdSide
Query the id for a particular device at index on a side (1 or 2)
Use GetDeviceCountSide to get suitable values for index (zero based)
returns: the id of the device at index
See also: GetDeviceCountSide
Example Lua usage:
GetWeaponCount
Gets the number of weapons on a given team (not including devices)
returns: the number of weapons on teamId
See also: GetWeaponId
Example Lua usage:
GetWeaponId
Query the id for a particular weapon at index on a team
Use GetWeaponCount to get suitable values for index (zero based)
returns: the id of the weapon at index
See also: GetWeaponCount
Example Lua usage:
GetWeaponCountSide
Get the number of weapon on a given side
returns: the number of weapons on sideId
See also: GetWeaponIdSide
Example Lua usage:
GetWeaponIdSide
Query the id for a particular weapon at index on a side (1 or 2)
Use GetWeaponCount to get suitable values for index (zero based)
returns: the id of the weapon at index
See also: GetWeaponCountSide
Example Lua usage:
GetDeviceEnabled
Query whether a device or weapon on a side is enabled for building
Example Lua usage:
GetMaterialEnabled
Query whether a material on a side is enabled for building
Example Lua usage:
GetMaterialMinLength
Query the minimum length of a material for a side
Example Lua usage:
GetMaterialMaxLength
Query the maximum length of a material for a side
Example Lua usage:
GetMaterialMaxLinkLength
Query the maximum link length of a material for a side
Example Lua usage:
GetDefaultBackMaterial
Query the material SaveName for creating background structure
Example Lua usage:
IsWeapon
Returns true if the given device is a weapon
Example Lua usage:
GetGroupSize
Query the current size of the group at this index
Example Lua usage:
GetGroupMemberId
Query the device id of the member a the group
index: the index of the group
memberIndex: the index of the member within the group
returns: the device id of the weapon
Example Lua usage:
GetWeaponBeamDamage
Query the amount of beam damage this weapon dealt on the last firing
Example Lua usage:
GetWeaponBeamReflected
Queries whether the beam was reflected during the last firing
Example Lua usage:
GetDeviceCanClaimStructures
Queries whether a device can claim structures
Example Lua usage:
GetDeviceStructureId
Query the structure id that a device is attached to
returns: the structure id, 0 if none.
Example Lua usage:
GetDevicePlatformA
Queries the first platform node of the given device
Example Lua usage:
GetDevicePlatformB
Queries the second platform node of the given device
Example Lua usage:
GetDeviceIdOnPlatform
Queries the device id on a specific platform
Device is also returned if on reverse direction
Example Lua usage:
GetPlatformSupportsDevice
Queries whether the a device type can be built on a given slope
Example Lua usage:
GetDeviceForward
Queries the forward vector of the given device
Example Lua usage:
GetDeviceIdAtPosition
Queries the device id at the given position
Example Lua usage:
GetDeviceType
Queries the SaveName of the given device
returns: empty string if not found
Example Lua usage:
GetDeviceTypeCount
Gets the number of device types for a side
Example Lua usage:
IsDeviceTypeAWeapon
Queries whether a device index is a weapon
Example Lua usage:
IsDeviceTypeBeam
Queries whether the given device’s default ammo type is a beam
Example Lua usage:
IsDeviceBeam
Queries whether the given device is a weapon with a beam ammo type selected
Example Lua usage:
IsDeviceTypeAmmo
Queries whether the given device type is ammo
Example Lua usage:
GetDeviceTypeSaveNameByIndex
Gets a device type SaveName for a side
Example Lua usage:
GetDeviceTypeSplashDamageByIndex
Query the splash damage produced by the default ammo projectile this weapon spawns
Example Lua usage:
IsDeviceTypeWeapon
Returns true if the given device type is a weapon
Example Lua usage:
IsSpotter
Does this device type on this side operate as a spotter (e.g. sniper)
Spotters can increase the aiming arc of other weapons and paint targets for weapons that need it
Example Lua usage:
IsDummy
Query whether the device or weapon is fake
Example Lua usage:
IsCloaked
Query whether the device or weapon is currently hidden to the enemy
Example Lua usage:
RequiresSpotter
Query whether this weapon type require a spotter with line of sight to the target
Example Lua usage:
IsNodeProjectile
Query if the given node is associated with a projectile
Example Lua usage:
GetNodeProjectileType
Example Lua usage:
GetNodeProjectileSaveName
Queries the type of projectile this node is
returns: empty string if not a projectile
Example Lua usage:
GetNodeProjectileDamage
Queries the damage left on the projectile associated with a node
Damage can be reduced by impact with structure (e.g. cannon)
returns: zero if not a projectile
Example Lua usage:
GetProjectileParams
Queries the information about a projectile associated with a node
FieldType: one or more FIELD_* bit flags
FieldRadius: the distance from the node position within which the field takes effect
returns: table containing the above mentioned values
Example Lua usage:
GetProjectileTypeIndex
Queries the index of a projectile type from projectile_list.lua
saveName: name of the projectile
teamId: the team of interest
Example Lua usage:
HasProjectileParamNodeByIndex
Queries node existence of a projectile type from projectile_list.lua by index
index: index of the projectile type
teamId: the team of interest
nodeName: name of the table to query for existance
Example Lua usage:
GetProjectileParamStringByIndex
Queries a string property of a projectile type from projectile_list.lua by index
index: index of the projectile type
teamId: the team of interest
paramName: name of the param to query
Example Lua usage:
GetProjectileParamIntByIndex
Queries an integer property of a projectile type from projectile_list.lua by index
index: index of the projectile type
teamId: the team of interest
paramName: name of the param to query
Example Lua usage:
GetProjectileParamBoolByIndex
Query a boolean property of a projectile type from projectile_list.lua by index
index: index of the projectile type
teamId: the team of interest
paramName: name of the param to query
Example Lua usage:
GetProjectileParamString
Queries a string property of a projectile type from projectile_list.lua
saveName: name of the projectile
teamId: the team of interest
paramName: name of the param to query
Example Lua usage:
GetProjectileParamInt
Queries an integer property of a projectile type from projectile_list.lua
saveName: name of the projectile
teamId: the team of interest
paramName: name of the param to query
Example Lua usage:
GetProjectileParamFloat
Queries a float property of a projectile type from projectile_list.lua
saveName: name of the projectile
teamId: the team of interest
paramName: name of the param to query
Example Lua usage:
GetProjectileParamBool
Query a boolean property of a projectile type from projectile_list.lua
saveName: name of the projectile
teamId: the team of interest
paramName: name of the param to query
Example Lua usage:
GetNodeProjectileTimeRemaining
Query the time a projectile will survive for
returns: time left to go, in seconds
Example Lua usage:
SetNodeProjectileAgeTrigger
Sets the time after spawn at which the first age effect will be triggered
Example Lua usage:
GetNodeProjectileAgeTrigger
Queries the time after spawn at which the first age effect will be triggered
Example Lua usage:
GetNodeAge
Queries how long in seconds a node has lived for
Could be a structure or projectile node
returns: zero if not found
Example Lua usage:
GetProjectileFieldRadius
Queries the radius of a projectile field
returns: zero if not a projectile
Example Lua usage:
GetProjectileGravity
Queries the gravity of a projectile, which may be different from the map’s gravity
returns: the vertical force component (positive is down)
Example Lua usage:
GetProjectileTypeGravity
Queries the gravity of a projectile by type, which may be different from the map’s gravity
returns: the vertical force component (positive is down)
Example Lua usage:
GetProjectileTypeDrag
Queries the drag of a projectile by type
returns: parameter of the projectile
Example Lua usage:
GetProjectileTarget
Queries the destination of projectiles
Missiles return their target.
Other projectiles and nodes will return the position projected 1s into the future.
returns: somewhere the projectile is heading.
Example Lua usage:
IsMissileAttacking
Queries whether a missile projectile is in the attack phase
returns: if not a missile
Example Lua usage:
GetMissileTarget
Returns the current target of a missile projectile
returns: destination position of the missile (origin if not a missile)
See also: GetMissileTargetProjected
Example Lua usage:
GetMissileTargetProjected
Returns the projected target of a missile projectile
This is the position TargetRearOffsetDistance behind the actual target (returned by GetMissileTarget)
returns: destination position of the missile (origin if not a missile)
See also: GetMissileTarget
Example Lua usage:
SetMissileTarget
Sets the target of a missile projectile
Example Lua usage:
GetWeaponTypeProjectileSpeed
Queries the maximum fire speed of a projectile
returns: 1 if not found, and logs console error
Example Lua usage:
GetWeaponTypeFireDelay
Queries the fire delay of the weapon
returns: 0 if not found
Example Lua usage:
GetWeaponTypeRoundsEachBurst
Queries the rounds per burst of the weapon
returns: 1 if not found
Example Lua usage:
GetWeaponTypeRoundsPeriod
Queries the rounds period of the weapon
returns: 0 if not found
Example Lua usage:
GetDeviceTeamId
Query the side of a device
This should really be called GetDeviceSideId
E.g. 1 or 2
Example Lua usage:
GetDeviceTeamIdActual
Query the team of a device
In team death match players can have their side and fort encoded into a large teamId
E.g. 101 means team 1 of side 1, 102 means team 1 of side 2
Use teamId%MAX_SIDES to get the sideId from a teamId
Example Lua usage:
IsGroundDevice
Queries whether a device can only be built on the ground
Example Lua usage:
GetDeviceLinkPosition
Queries how far along the platform the device is placed
returns: position in the range 1
Example Lua usage:
GetDevicePosition
Queries the world position of a device
Includes device on platforms or on the ground
Example Lua usage:
FindClosestDeviceOnStructure
Searches for the nearest device on the same structure with the specified saveName
pos: The position to search from
structureId: The structure to search on (0 for all structures)
saveName: The device saveName to look for (empty string for all devices)
returns: The id of the found device (0 if none found)
Example Lua usage:
FindNodeOnStructure
Finds the closest node Id which is closest to pos on the specified structure
pos: The position to search from
structureId: The structure to search on (0 for all structures)
farthest: Find the farthest instead of the closest
returns: The id of the node closest to pos
Example Lua usage:
FindVisibleAngles
Starts a search for the visible angles from the perspective of a weapon
Can be narrowed using other functions (below).
Example Lua usage:
NarrowVisibleAnglesBySide
Removes visible angle which are not in the direction of a side’s structures
FindVisibleAngles should be used before this to set up the weapon’s visible angles
weaponId: The weapon being inspected
sideId: The side to narrow to
returns: The number of angle brackets remaining
See also: FindVisibleAngles, NarrowVisibleAnglesBySegment, GetVisibleAngleBracket
Example Lua usage:
NarrowVisibleAnglesBySegment
Removes visible angle which are not in the direction of the given line segment
FindVisibleAngles should be used before this to set up the weapon’s visible angles
weaponId: The weapon being inspected
sideId: The side to narrow to
returns: The number of angle brackets remaining
See also: FindVisibleAngles, NarrowVisibleAnglesBySide, GetVisibleAngleBracket
Example Lua usage:
GetVisibleAngleBracketCount
Query the number of angle brackets previously calculated by FindVisibleAngles
Example Lua usage:
GetVisibleAngleBracket
Query an angle bracket previously calculated by FindVisibleAngles
index: The index of the angle bracket
returns: The angle bracket: x is the first angle, y is the second angle
See also: FindVisibleAngles, GetVisibleAngleBracketCount
Example Lua usage:
GetDeviceCentrePosition
Queries the center of a device’s bounding box
Includes device on platforms or on the ground
Example Lua usage:
GetDeviceComponentPosition
Queries the position of a component of the given device
Example Lua usage:
GetWeaponBarrelPosition
Queries the position of the «Head» sprite
This is approximately the pivot of the weapon, not really where projectiles are spawned
Example Lua usage:
GetWeaponHardpointPosition
Queries the position of where the weapon spawns projectiles
Example Lua usage:
dlc2_SetDevicePosition
Moves a ground or floating device to a position
Requires the High Seas DLC (dlc2)
Example Lua usage:
GetDeviceAngle
Queries the orientation of a device
Example Lua usage:
SetDeviceAngle
Sets the angle of a ground device
Example Lua usage:
GetDeviceEfficiency
Queries the performance of a device (e.g. turbine)
Example Lua usage:
GetDeviceMovingId
Queries the corresponding linked device id of a device being moved
Example Lua usage:
IsDeviceFullyBuilt
Queries the construction state of a device
returns: true if the device is constructed
Example Lua usage:
IsDeviceUnderConstruction
Queries whether a device is under construction
Will return false if the device is built, under repair or being scrapped
returns: true if the device is under construction
Example Lua usage:
IsDeviceAvailable
Determines if a device is not being used by a player
Example Lua usage:
IsWeaponReadyToFire
Queries whether a weapon is ready to fire
Example Lua usage:
ReloadWeapon
Instantly reloads the given weapon
Example Lua usage:
SetWeaponEffectTag
Sets the enabled/disabled state for effect tags (only supports beam impacts)
tag: The tag for the child elements in the effects.
Example Lua usage:
SetWeaponSelectedAmmo
Sets the selected ammo type for a weapon
tag: The unique tag for the ammo. If the tag can’t be found in the ammunition list, it will check against ammo projectile names. an empty tag will choose the first (default) ammo
Example Lua usage:
GetWeaponAmmo
Queries the projectile SaveName that the weapon fires
Example Lua usage:
GetWeaponSelectedAmmo
Queries the projectile SaveName of the ammo the weapon is set to fire
Example Lua usage:
GetWeaponFiringTimeRemaining
Queries how long a weapon still has to fire
Example Lua usage:
GetWeaponFieldsBlockFiring
Queries whether a weapon can be blocked by fields that block fire
Example Lua usage:
CastRayFromDevice
Sends a ray from the centre of a device or weapon towards the target
Reports details of any collision in various GetRay* functions (see below)
Example Lua usage:
CastGroundRay
Intersects a line segment only with the terrain
terrainFlags: one of the TERRAIN_* bit flags specified in forts.lua, used to modify which terrain blocks are
Returns RAY_HIT_TERRAIN or RAY_HIT_NOTHING
See also: GetRayHitPosition
Example Lua usage:
CastGroundRayFromWeapon
Intersects a line segment only with the terrain
terrainFlags: one of the TERRAIN_* bit flags specified in forts.lua
Returns RAY_HIT_TERRAIN or RAY_HIT_NOTHING
See also: GetRayHitPosition
Example Lua usage:
CastRay
Use GetRayHitTeamId(), GetRayHitPosition() and GetRayHitMaterialSaveName() to get more information on the collision
Ignores background blocks
source: where to start ray from
target: where to end
rayFlags: RAY_DEBUG, RAY_EXCLUDE_DYNAMIC_TERRAIN, RAY_EXCLUDE_NEUTRAL only
fieldBlockFlags: which fields to intersect (FIELD* constants in forts.lua)
returns: one of the ray result flags (e.g. RAY_HIT_STRUCTURE) in forts.lua
See also: GetRayHitTeamId, GetRayHitPosition, GetRayHitMaterialSaveName, GetRayHitDoor
Example Lua usage:
GetRayHitSideId
returns the side hit during most recent call to
Example Lua usage:
GetRayHitTeamId
Returns the hit teamId of the previous ray test
Example Lua usage:
GetRayHitPosition
Returns the hit position of the previous ray test
Example Lua usage:
GetRayHitMaterialSaveName
Returns the hit material SaveName of the previous ray test
Example Lua usage:
GetRayHitDoor
Returns the true if the last ray cast hit a door
Example Lua usage:
GetRayHitLinkNodeIdA
Returns the first nodeId of the previous ray test
Example Lua usage:
GetRayHitLinkNodeIdB
Returns the second nodeId of the previous ray test
Example Lua usage:
GetRayHitDeviceId
Returns the device id hit by the previous ray test
Example Lua usage:
GetBlockingDevice
Returns the deviceId of the device blocking CreateGroundDevice() or CreateDevice()
Example Lua usage:
CreateGroundDevice
Spawns a device on the ground
The position must be on suitable terrain within range of a fort
Sets a value for GetBlockingDevice when return value is CS_OBSTRUCTION
Sets a value for GetBlockingDevice when return value is CD_OCCUPIED
deviceTeamId: the team the device should belong to (must match the ground owner)
saveName: the type of the device to create
position: the location to place the device (must be on the ground)
angle: in degrees with 90 pointing up
See also: CreateDevice, DestroyDevice, DestroyDeviceById
Example Lua usage:
dlc2_CreateFloatingDevice
Spawns a disembodied device anywhere (except inside solid ground)
The device’s dlc2_BuildAnywhere must be set to true in device_list.lua
The position must be on suitable terrain within range of a fort
Sets a value for GetBlockingDevice when return value is CS_OBSTRUCTION
Sets a value for GetBlockingDevice when return value is CD_OCCUPIED
Requires the High Seas DLC (dlc2)
deviceTeamId: the team the device should belong to (must match the ground owner)
saveName: the type of the device to create
position: the location to place the device (must be on the ground)
angle: in degrees with 90 pointing up
See also: CreateDevice, DestroyDevice, DestroyDeviceById
Example Lua usage:
CreateDeviceWithFlags
Spawns a new device on the specified platform using specified create device flags
Sets a value for GetBlockingDevice when return value is CD_OCCUPIED
deviceTeamId: the team the device should belong to (must match platform owner)
saveName: the type of the device to create
nodeIdA: the first node id of the platform
nodeIdB: the second node id of the platform
t: the position on the platform to make the device 1
flags: the CREATEDEVICEFLAG to apply, e.g. CREATEDEVICEFLAG_IGNORERECESSIONCOST
See also: CreateDevice, CreateGroundDevice, DestroyDevice, DestroyDeviceById
Example Lua usage:
CreateDevice
Spawns a new device on the specified platform
Sets a value for GetBlockingDevice when return value is CD_OCCUPIED
deviceTeamId: the team the device should belong to (must match platform owner)
saveName: the type of the device to create
nodeIdA: the first node id of the platform
nodeIdB: the second node id of the platform
t: the position on the platform to make the device 1
See also: CreateGroundDevice, DestroyDevice, DestroyDeviceById
Example Lua usage:
UpgradeDevice
Converts the device or weapon to the specified device, if compatible
returns the new deviceId if successful, or otherwise one of the UD_* failure codes
Example Lua usage:
GetDeviceHealth
Returns the relative health of the device in the range 1
Example Lua usage:
GetDeviceHitpoints
Returns the absolute health of the device in hitpoints
Example Lua usage:
ApplyDamageToDevice
Damages the given device, returns the new absolute health in hitpoints
Example Lua usage:
IsDeviceRepairable
Queries whether the device can be repaired
Example Lua usage:
RepairDevice
Starts the repair process of the given device
Example Lua usage:
EMPDevice
Disables the device as if hit by an EMP
deviceId: the id of the device to disable
duration: how long the device is disabled for in seconds
Example Lua usage:
DeviceCanBeDestroyedById
Queries whether the specified device can be reclaimed
The reactor can’t be, as an example
Example Lua usage:
DestroyDeviceById
Starts the salvage process for the given device
Example Lua usage:
DestroyDevice
Starts the salvage process for the device on the given platform
Example Lua usage:
DestroyDeviceAtPos
Starts the salvage process for the device at the given position
Example Lua usage:
DeviceExists
Returns true if the given deviceId is valid
Example Lua usage:
DeviceExpired
For weapons that expire after a set number of bursts, this will
return true if the final burst been spawned, but the weapon has not yet been destroyed
Example Lua usage:
DeviceDisabled
Returns true if device has been disabled by EMP
Example Lua usage:
dlc2_ApplyForce
Adds a force to a joint
Requires the High Seas DLC (dlc2)
Example Lua usage:
dlc2_CreateProjectile
Spawns a projectile at an arbitrary position
Requires the High Seas DLC (dlc2)
Example Lua usage:
DestroyProjectile
Destroys the joint or projectile with the given nodeId
Example Lua usage:
NodeExists
Returns true if the given node is valid
Example Lua usage:
NodeStructureId
Returns the structureId of the given node
Example Lua usage:
StructureNodeAtIndex
Returns the node Id at an index within a structure
Example Lua usage:
NodeStructureIndex
Returns the index of this node within its structure
Example Lua usage:
NodeLinkCount
Returns the number of struts attached to the given node
Example Lua usage:
NodeNonSegmentedLinkCount
Returns the number of struts attached to the node which aren’t rope type materials
Example Lua usage:
MaterialIsSegmented
Returns true if the given material is of a rope type
Example Lua usage:
NodeLinkedNodeId
Returns the nodeId at the other end of the strut of the given index
Example Lua usage:
IsNodeLinkedTo
Returns true if the two nodes are connected via a non-segmented strut
Example Lua usage:
IsNodeDeleting
Returns true if all links of this node are in the scraping state
Example Lua usage:
IsLinkConductive
Returns true if a link conducts power
Example Lua usage:
GetDeviceState
Returns the state of the given device
One of the DEVICE_* values from forts.lua
Example Lua usage:
GetLinkState
Returns the state of the given strut
One of the LINK_* values from forts.lua
Example Lua usage:
GetLinkHealth
Get the relative health of the given strut in the range 1
Example Lua usage:
GetTeamMinLinkHealth
Get the lowest relative strut health of the given team
Useful for the AI to quickly determine if any struts need repairing
Example Lua usage:
GetLinkCost
Returns the cost of building a new strut to the given position, with the given material
Example Lua usage:
GetLinkLengthCost
Returns the cost of building a length of the given material
Example Lua usage:
GetLinkRepairCost
Returns the cost of fully repairing the given strut
Example Lua usage:
RepairLink
Starts repairing the given strut
Example Lua usage:
CancelRepairLink
Stops repairing the given strut
Example Lua usage:
IsLinkRepairing
Returns true of the given link is currently repairing
Example Lua usage:
RepairCancelsOnDamage
Sets the global property of stopping repair if a strut is damaged
Example Lua usage:
GetLinkSegmentsOnFire
Returns the number of segments on fire on the given strut
Example Lua usage:
GetTeamLinksOnFire
Get the number of struts on fire for the given team
Example Lua usage:
IsFireAlarmOn
Returns true if the fire alarm is on for the local player
Example Lua usage:
GetLinkCountOfSide
Returns the number of struts of the given side, e.g. 0, 1, 2
When passed a specific team will convert to side
Use GetLinkCountOfTeam() for specific team within a side
Example Lua usage:
SetStructureConnectable
Allows or blocks connectivity to the structure of the given node
Used internally to prevent players connecting to blast doors
Example Lua usage:
SetStructureRepulsive
Allows or blocks construction near the structure of the given node
Used internally to prevent players building near or through blast doors
Example Lua usage:
EnumerateLinks
Easily enumerate struts that satisfy a damage condition
The callback must have:
— parameters: nodeA [1+], nodeB [1+], saveName, relativeHealth 1, stress 1, segmentsOnFire [0+], deviceId [0+]
— return value: true or false, indicating whether to continue the search
If a link has less health than damageThreshold or a device with less than damageThresholdDevice a call for the link will be made
This can be used to filter out healthy links and devices when searching for items to repair (for optimisation)
To do a breadth first enumeration from a device type (typically this will be «reactor»), specify in sourceDevice parameter
Otherwise a zero length string will enumerate the links from the nodes in numerical (creation) order
If a strut has no device on it then the deviceId given to the callback will be 0
Stress represents how close the strut is to breaking, where 0 is no compression/expansion, and 1 is the limit
teamId: the team/side to enumerate (see matchSide parameter)
callbackName: the name of the function to call for each strut found
damageThreshold: relative health of the strut 1, below which the strut will be passed to the callback
damageThresholdDevice: relative health of a device on the strut 1, below which the strut will be passed to the callback
sourceDevice: the SaveName of a device used as the origin(s) of the search. Commonly «reactor», but can be empty («») for numerical order.
matchSide: if true will search any structures on the same side as teamId
WARNING: CreateLink and DestroyLink will not function while this call is active
WARNING: Can’t be called recursively or with EnumerateStructureLinks
Example Lua usage:
EnumerateStructureLinks
Easily enumerate struts within a specific structure
The callback must have:
— parameters: nodeA [1+], nodeB [1+], link position, saveName, deviceId [0+]
— return value: true or false, indicating whether to continue the search
Enumerate the links from the nodes in numerical (creation) order
If a strut has no device on it then the deviceId given to the callback will be 0
WARNING: CreateLink and DestroyLink will not function while this call is active
WARNING: Can’t be called recursively of with EnumerateLinks
Example Lua usage:
EnumerateChainNodes
Follows a chain of struts in both directions, reporting nodes to a callback
The callback takes only the next nodeId found in the chain
nodeIdA: the first starting node
nodeIdB: the second starting node
callbackName: the name of the callback function
Example Lua usage:
GetStructureCount
Query the number of separate structures in the world
Each structure gets a unique and stable id
Example Lua usage:
GetStructureId
Query the id of a structure
Example Lua usage:
GetStructureTeam
Query the teamId of a structure
Example Lua usage:
GetStructurePos
Query the geometric centre of a structure
Example Lua usage:
GetStructureRadius
Query the geometric radius of a structure
Example Lua usage:
GetStructureOnLand
Determine if a structure has a physical connection to land
returns: true if the structure has any foundations, excluding via non conductive materials (i.e. ropes)
See also: GetStructureCount, GetDeviceStructureId, NodeStructureId, GetStructureInWater
Example Lua usage:
GetStructureInWater
Determine if a structure has a physical connection to land
returns: true if the structure has any part under water, excluding via non conductive materials (i.e. ropes)
See also: GetStructureCount, GetDeviceStructureId, NodeStructureId, GetStructureOnLand
Example Lua usage:
GetWaterDepthAt
Query the depth of the water at specific point
Example Lua usage:
GetWaterLevel
Query the vertical coordinate of the world water level
x: The horizontal position to query
See also: GetWaterDepthAt
Example Lua usage:
dlc2_ConvertStructure
Convert team ownership of a structure
Requires the High Seas DLC (dlc2)
Example Lua usage:
ProjectileCount
Query the total projectile nodes belonging to a side
sideId: 0, 1 or 2
returns: the number of projectiles belonging to the team
See also: GetProjectileId
Example Lua usage:
GetProjectileId
Query the node id of a projectile at the index of a specific side
Example Lua usage:
NodeCount
Query the total nodes belonging to a side
sideId: 0, 1 or 2
returns: the number of structure joints belonging to the team
See also: GetNodeId
Example Lua usage:
GetNodeId
Query the id at the index of a specific side
Example Lua usage:
NodeTeam
Query the team id of a node
returns: TEAM_ANY (-1) if the node doesn’t exist
See also: GetNodeId
Example Lua usage:
NodePosition
Query the position of a node
Example Lua usage:
NodeVelocity
Query the velocity of a node
Example Lua usage:
NodeSelectable
See if a node can be selected by a player
The middle nodes of a segmented material (rope) can’t be selected
Example Lua usage:
GetClosestFoundationNodeId
Find the closest foundation node id of a team to a position
The maximumn distance is defined in constants.lua
Example Lua usage:
SnapToNode
Find the closest node within maxDist for a team
Example Lua usage:
SetBackgroundLayerSpriteState
layerName: name of the layer
state: new sprite state
keepTime: transfer current state time to new state
Example Lua usage:
GetTerrainBlockIndex
Find the index of the first terrain block with a specific name
Example Lua usage:
EnableTerrainBlock
Show or hide any terrain blocks with a specific name
Example Lua usage:
GetSurfaceSaveName
Query the name of a surface
surfaceType: the index of the surface
returns: empty string if surfaceType is invalid
Example Lua usage:
UpdateGroundTriangles
Recalculates the terrain triangles and open edges
Use this after making changes to a block’s nodes
Example Lua usage:
CreateBlock
Create a new ground block
returns: the id of the block that was created
See also: SetBlockTexture, AddBlockVertex
Example Lua usage:
GetEnvironmentPathBase
Query the current environment path base
Useful for constructing texture names for SetBlockTexture
E.g. returns «environment/canyon»
Example Lua usage:
GetEnvironmentPath
Query the current environment path
Useful for constructing texture names for SetBlockTexture
E.g. returns «environment/canyon»
Example Lua usage:
GetMapFilename
Query the current map filename or Workshop published file Id
E.g. returns «Vanilla», «1230779210»
Example Lua usage:
SetBlockTexture
Change the texture of a ground block
Example Lua usage:
AddBlockVertex
Add a vertex to an existing ground block
Example Lua usage:
GetBlockSelectionCount
Gets the number of blocks selected
Intended for use within terraform scripts only
Example Lua usage:
GetBlockSelection
Gets the block index within the current selection
Intended for use within terraform scripts only
Example Lua usage:
GetBlockCount
Query the total number of blocks in the world
Example Lua usage:
GetBlockVertexCount
Query the number of vertices in a block
Example Lua usage:
GetBlockVertexPos
Query the position of a terrain block vertex
Example Lua usage:
SetBlockVertexPos
Change the position of a vertex in a terrain block
Example Lua usage:
MirrorHorizontal
Flip a terrain block sideways about a point in space
Example Lua usage:
MirrorVertical
Flip a terrain block up and down about a point in space
Example Lua usage:
FlipBlockNormals
Invert the normals (surface up vectors) of a terrain block
Example Lua usage:
ClearBlockSelection
Remove all blocks from the current selection
Example Lua usage:
SelectBlock
Add a terrain block to the current selection
Example Lua usage:
SetBlockFlags
Change a subset of flags on a block
flagsToSet: a combination of BLOCKFLAG_* values (see scripts/shapes.lua)
Example Lua usage:
MakeUndoLevel
Saves the current state in an undo level
Use this in a terraform script after making changes to make the action easy to undo
Example Lua usage:
IsPointOnGround
Query whether a point in space is on a terrain block surface
pos: the position of the point
teamId: not used
Example Lua usage:
IsFoundation
Query whether a node is a foundation
Example Lua usage:
IsNonFoundation
Returns true for isolated nodes of some materials (e.g. cable)
Example Lua usage:
GetNodeGroundBlockIndex
Query the block index associated with a foundation node
Example Lua usage:
IsTeamConnectedToGroundBlock
Queries whether the given team has a node touching a terrain block
WARNING: Slow for large structures
Example Lua usage:
GetPosGroundBlockIndex
Query the index of the block that snaps to the given position
Example Lua usage:
GetLinkMaterialSaveName
Query the SaveName of the material connecting two nodes
Example Lua usage:
IsPortal
Query whether a strut connecting two nodes is a portal
Being connected and active has no bearing on the result
returns: true if the strut exists and its material is a portal
See also: GetPortalDestinationA, GetPortalDestinationB
Example Lua usage:
GetPortalDestinationA
Returns the first node of the destination portal
Example Lua usage:
GetPortalDestinationB
Returns the second node of the destination portal
Example Lua usage:
CreateNode
Create a new node at pos, linked to the node with id linkedNodeIdA
teamId: the team to create for
materialSaveName: the name of the material to use
linkedNodeIdA: the existing node Id to link from
pos: the position of the new node
returns: the node Id if the operation was successful. A negative value indicates failure with a CS_* value from forts.lua
See also: DestroyNode, CreateLink, GetCreateNodeGroundSnap
Example Lua usage:
GetCreateNodeGroundSnap
Query whether the last CreateNode call snapped to the ground and attempted to create a foundation
returns: true if the CreateNode call snapped to ground
See also: CreateNode
Example Lua usage:
DestroyNode
Salvage the given node and any attached struts
The calling script must have control of the team of the node
teamId: the expected team of the node
nodeId: the Id of the node to destroy
See also: DestroyLink
Example Lua usage:
GhostStructure
Toggles ghost mode on a structure containing a node
WARNING: Don’t use this directly, it’s meant for cutscenes with the Structures table in a scene
Example Lua usage:
DestroyStructure
Instantly destroy the entire structure connected to the given node
Example Lua usage:
CreateLink
Create a strut between the two given nodes
WARNING: Does not function during a call to EnumerateLinks
Example Lua usage:
DestroyLink
Salvage the strut between the two given nodes
WARNING: Does not function during a call to EnumerateLinks
Example Lua usage:
ConnectPortals
Links two portals identified by the parameters
teamId: the teamId the nodes should be owned by
nodeIdA: the first node of the first portal
nodeIdB: the second node of the first portal
nodeIdADest: the first node of the second portal
nodeIdBDest: the second node of the second portal
returns: CP_SUCCESS or CP_INVALIDNODES
Example Lua usage:
SwitchPortal
Reverses the direction of the specified portal
teamId: the teamId the nodes should be owned by
nodeIdA: the first node of the portal
nodeIdB: the second node of the portal
returns: CP_SUCCESS or CP_INVALIDNODES
Example Lua usage:
IsWeaponSpotting
Query if the specified weapon is spotting a target for another weapon
Example Lua usage:
SetWeaponPaintTarget
Specify that a missile type weapon should target a location for an AI
Example Lua usage:
ClearWeaponPaintTarget
Cancel the target of a missile type weapon
Example Lua usage:
GetWeaponPaintTargetMarked
Query if the weapon’s target was reached by a spotting laser
Example Lua usage:
GetWeaponReloadPeriod
Query the given weapon type’s base reload period
This will be inaccurate if the weapon is using ammo which overrides ReloadTime
returns: the time it takes to reload, in seconds
See also: GetWeaponReloadPeriodById
Example Lua usage:
GetWeaponReloadPeriodById
Query a specific weapon’s reload period
This takes into account recently used ammo
returns: the time it takes to reload, in seconds
See also: GetWeaponReloadPeriod
Example Lua usage:
SetWeaponReloadTime
Sets a weapon’s remaining reload time
FireWeapon
Example Lua usage:
GetWeaponReloadTime
Query how far into the reload cycle a weapon is
returns the value of GetWeaponReloadPeriodById if it’s fully reloaded
Example Lua usage:
GetDeviceProductionRate
Query the rate of metal and energy production in units per second
Example Lua usage:
GetWeaponFireCost
Query the cost of firing the given weapon
Beam weapons will report the rate of resource consumption per second
Example Lua usage:
GetWeaponTypeFireCost
Query the default cost of firing the given weapon type
Beam weapons will report the rate of resource consumption per second
Not accurate if the selected ammo firing cost differs
Example Lua usage:
GetDeviceCost
Query the cost of building the given device
Example Lua usage:
IsHumanOnSide
Query whether a human player is currently on a side
Example Lua usage:
GetTeamCount
Used to discover the actual number teams in play
Use GetTeam to get the teamId for each index
Example Lua usage:
GetTeamId
In co-op battles this will return 0, 1 and 2
In team death match this will return 0, 1, 2 and 101, 201, etc. for teams within a side
Use teamId%MAX_SIDES to get the side of these (1 or 2)
Example Lua usage:
GetTeamResources
Query the current resource balance of the given team
Example Lua usage:
GetTeamResourceCapacity
Query the current resource capacity of the given team
Example Lua usage:
GetTeamResourceRate
Query the current resource accumulation rate of the given team
This is per-frame; multiply by ‘FrameRate’ or divide by ‘data.updateDelta’ to calculate per-second rates
Example Lua usage:
AddResources
Increment the given team’s balance by value
amount: can be negative to spend resources
Example Lua usage:
SetUnlimitedResources
unlimitedMetal: set unlimited Metal
unlimitedEnergy: set unlimited Energy
See also: GetTeamResources, AddResources
Example Lua usage:
TransferResources
Transfer resources from a team to a side
The resources are distributed evenly among the teams within the side
Example Lua usage:
ShowStolenResources
Shows an amount as stolen on Spook’s enemy resource HUD
Example Lua usage:
SetInspectedEnemyTeamId
Sets the team that Spook is currently spying on, highlighting their reactor
Example Lua usage:
GetTeamCommanderPoints
Query the commander change progress of a side
returns: a number in the range 1
Example Lua usage:
ActivateCommander
Activate the commander for the given side
Example Lua usage:
IsCommanderActive
Query whether the commander is active for the given side
Example Lua usage:
SetTeamFlag
Set a team bit flag (e.g. no construct effects for devices, links and nodes)
flags: One of the TEAMFLAG_* values from forts.lua (e.g. TEAMFLAG_SILENT)
Example Lua usage:
AimWeapon
Returns true if able to hit the target
Use GetAimWeaponAngle and GetAimWeaponSpeed to query aiming solution
Example Lua usage:
GetAimWeaponAngle
Returns the angle needed to hit the target calculated in AimWeapon
Example Lua usage:
GetAimWeaponSpeed
Returns the speed needed to hit the target calculated in AimWeapon
Example Lua usage:
ReserveWeaponAim
Prevents the weapon’s aim jumping back to the refire angle for the duration
Example Lua usage:
GetFireAngle
Gets the current world angle of the weapon
Not deterministic
Example Lua usage:
GetFireSpeed
Gets the current fire speed of the weapon
Not deterministic
Example Lua usage:
GetWeaponMaxFireSpeed
Query the maximum speed projectiles are launched from a weapon (with the commander inactive)
Example Lua usage:
GetFireVel
Get a vector representing the current direction and speed of fire for a weapon
Example Lua usage:
GetMaxFireRadius
Query the outside radius of the aiming arc for a weapon
id: the device id of the weapon
Example Lua usage:
GetFuseDelay
Query the fuse delay for timed projectile weapons
Example Lua usage:
FireWeaponWithPower
Attempts to fire the given weapon at target with some error and level of power
stdDev: standard deviation (normal distribution) for error on calculated fire angle (in degrees)
stdDevTestOverride: standard deviation (normal distribution) for maximum friendly structure collision tests, < 0 means ignore and use stdDev value for collision tests
Use GetRayHitLinkNodeIdA and GetRayHitLinkNodeIdB to query blocking structure
flags: one of the FIREFLAG_* values from forts.lua (typically use FIREFLAG_NORMAL)
power: affects the speed or spread of the shot as if cursor is closer or further from the weapon in the aiming arc 1
returns: one of the FIRE_* values from forts.lua (e.g. FIRE_SUCCESS)
See also: FireWeapon, OnWeaponFired
Example Lua usage:
FireWeapon
Attempts to fire the given weapon at target with some error
stdDev: standard deviation (normal distribution) for error on calculated fire angle (in degrees)
use GetRayHitLinkNodeIdA and GetRayHitLinkNodeIdB to query blocking structure
flags: one of the FIREFLAG_* values from forts.lua (typically use FIREFLAG_NORMAL)
returns: one of the FIRE_* values from forts.lua (e.g. FIRE_SUCCESS)
See also: FireWeaponWithPower
Example Lua usage:
IsDoor
Queries whether a material is a door type
Example Lua usage:
OpenDoor
Opens or closes the specified door
Same functionality as SetDoorState but a simpler boolean interface and instant is set to false
Example Lua usage:
SetDoorState
Allows doors to be controlled.
newState can be DS_CLOSED, DS_OPENING, DS_OPEN, or DS_CLOSING.
If instant is true and newState is DS_CLOSED or DS_OPEN then
the door is forced closed or open immediately.
Example Lua usage:
OpenWeaponDoors
Attempts to open the doors in front of the given weapon
Weapon must be aimed prior for this to be deterministic
returns the SP_ codes to indicate what happened
Example Lua usage:
CloseWeaponDoors
Attempts to close the doors that were previously opened by the given weapon
Example Lua usage:
DoorCountAI
Excludes repairing doors
Example Lua usage:
EnableMouse
Toggle the mouse cursor
Example Lua usage:
ProcessedMousePos
Query the snapped position of the mouse cursor
returns: the position snapped to grid, ground, struts, etc.
Example Lua usage:
GetMousePos
Query the position of the mouse cursor
returns: the mouse screen position.
Example Lua usage:
MoveMouseToPoint
Automatically move the mouse cursor from the current position to pos over duration seconds
Example Lua usage:
CancelMoveToPoint
End an automatic move started by MoveMouseToPoint
Example Lua usage:
AddMouseAccessory
Attach a sprite to the mouse cursor
Example Lua usage:
DeleteMouseAccessory
Delete an accessory called ‘name’ attached with AddMouseAccessory
Example Lua usage:
WorldToScreen
Transform a world position to screen coordinates
Useful for attaching screen space controls to world locations
Example Lua usage:
LeftClickMouse
Create an artificial left mouse button click
Example Lua usage:
RightClickMouse
Create an artificial right mouse button click
Example Lua usage:
MiddleClickMouse
Create an artificial middle mouse button click
Example Lua usage:
EnableCameraControls
Toggles player control of camera controls such as zoom and pan
Example Lua usage:
GetCamera
Queries the current extents and zoom of the camera
returns: extents are returned in a table containing MinX, MaxX, MinY, MaxY and Zoom
See also: GetCameraFocus, GetWorldExtents
Example Lua usage:
GetCameraFocus
Query the current centre of the screen
Example Lua usage:
GetCameraZoom
Query the current zoom level
Example Lua usage:
GetMinZoom
Query the minimum zoom level
This specifies how far the camera can zoom in
Example Lua usage:
SetMaterialToCreate
Sets which material the player has selected
Example Lua usage:
ShowProp
Shows or hides a prop of a specific name
Example Lua usage:
GetPropCount
Query the number of props in the world
Example Lua usage:
IsPropType
Query whether the prop with the given index uses a texture name given by the type parameter
Example Lua usage:
GetPropName
Query the name of a prop with a given index
Example Lua usage:
GetPropIndex
Query the position of a prop with a specific name
Example Lua usage:
GetPropPos
Query the position of a prop with a given index
Example Lua usage:
SetPropPos
Set the position of a prop with a given index
Example Lua usage:
GetPropPosByName
Query the position of a prop with a specific name
Example Lua usage:
EnableFogOfWar
Shows or hides the insides of a side to the enemy
Example Lua usage:
EnableFogOfWarShowArmour
Shows or hides the armour, shields, etc. of a side to the enemy
Example Lua usage:
SetSideVisible
Shows or hides the forts of a side (i.e. cloaking)
Example Lua usage:
LineSegNearestToPoint
Calculates the position on the line segment closest to a point
The return value is clamped to the end points if it is beyond them
start: The first end-point of the line segment
end: The second end-point of the line segment
pt: The point to find the nearest point to
returns: The closest point on the line segment to pt
Example Lua usage:
Called at the start of a battle
Example Lua usage:
Update
The main entry point for arbitrary game state tracking and changes. Called for every physics frame.
You can use OnUpdate for visual/audio changes instead for more frequent execution.
Example Lua usage:
OnUpdate
Called every display frame (not physics frame). Use this for updating debugging, visuals or audio only.
WARNING: don’t use this to change game state, as it’s not synchronous and will cause desyncs. Use Update instead.
Example Lua usage:
OnStreamComplete
Called when a stream started from StartStream is finished
seriesId: return value of StartStream
fromReplay: true if this is reproduced from a replay
Example Lua usage:
DismissResult
Called by game when the player escapes (e.g. clicks on) the victory/defeat banner
Return true to bring up the post-game pause menu
Example Lua usage:
OnPreRestart
Called before the battle is restarted
Example Lua usage:
OnRestart
Called when the battle is restarted
Example Lua usage:
OnInstantReplay
Called when instant replay is started
Example Lua usage:
OnPreSeek
Called during replays before a seek
Example Lua usage:
OnSeek
Called during replays after a seek
Example Lua usage:
OnSeekStart
Called during replays when seeking to start
Example Lua usage:
Cleanup
Called when returning to the menu
Example Lua usage:
OnNext
Called when the player clicks the ‘next’ pause menu option during a campaign
Example Lua usage:
OnExit
Called when the player exits a battle
Example Lua usage:
OnTipHidden
Called when the player satisfies or dismisses a tip
Example Lua usage:
OnEnableTip
Called when a tip is enabled or disabled
Example Lua usage:
OnTabOpened
Called when a different tab is selected
name: can be «materials», «devices», «tech», «weapons», «terrain», «surfaces», or «props»
Example Lua usage:
OnMaterialSelected
So different scripts can enforce minimum delays between tips
saveName: the material type selected
See also: OnLinkCreated
Example Lua usage:
OnDeviceSelected
Called when the local player selects a device type on the HUD
Example Lua usage:
OnNodeCreated
Called when a new joint is created by a player or AI
Does not include when an existing joint breaks or when projectiles are created
nodeId: the id of the node
teamId: the team the node belongs to
pos: where the node is currently located
foundation: true if the node is a foundation
selectable: true if the node can be selected (intermediate nodes of ropes can’t be selected)
extrusion: true if the node was created as part of an extrusion
See also: CreateNode, OnLinkCreated, OnNodeDestroyed, OnWeaponFired
Example Lua usage:
OnLinkCreated
Called when a new strut is created by a player or AI
teamId: the team the strut belongs to
saveName: the identifying name of the link’s material
nodeA: the id of the first node of the link
nodeB: the id of the second node of the link
pos1: the position of the first node of the link
pos2: the position of the second node of the link
extrusion: true if the link was created as part of an extrusion
See also: CreateLink, OnLinkDestroyed, OnNodeCreated
Example Lua usage:
OnDeviceCreated
Called when a new platform device is created by a player or AI
teamId: the team the device belongs to
deviceId: the id of the device
saveName: the identifying name of the device’s type
nodeA: the id of the first node of the platform link
nodeB: the id of the second node of the platform link
t: the position on the link the device was made 1
upgradeId: the id of a device that was upgraded to create this (0 if none)
See also: OnGroundDeviceCreated, CreateDevice, OnDeviceDestroyed
Example Lua usage:
OnGroundDeviceCreated
Called when a new ground device is created by a player or AI
teamId: the team the device belongs to
deviceId: the id of the device
saveName: the identifying name of the device’s type
pos: the position of the device
upgradeId: the id of a device that was upgraded to create this (0 if none)
See also: OnDeviceCreated, CreateGroundDevice, OnDeviceDestroyed
Example Lua usage:
OnDeviceCompleted
Called when a device finishes construction
Example Lua usage:
OnDeviceHit
Called when a device is impacted by a projectile (but not beams)
teamId: the team the device belongs to
deviceId: the id of the device
saveName: the type of the device
newHealth: the current health of the device 1
projectileNodeId: the id of the projectile which hit the device
projectileTeamId: the team of the projectile which hit the device
pos: the location of the impact
See also: OnDeviceDestroyed, OnProjectileDestroyed, OnLinkHit, OnTerrainHit
Example Lua usage:
OnDeviceHitBeam
Called when a device is impacted by a projectile (but not beams)
teamId: the team the device belongs to
deviceId: the id of the device
saveName: the type of the device
newHealth: the current health of the device 1
weaponId: the id of the projectile which hit the device
projectileSaveName: the projectile type of the beam
pos: the location of the impact
See also: OnDeviceHit, OnLinkHitBeam, OnTerrainHitBeam
Example Lua usage:
OnDeviceDeleted
Called when a device is deleted by a player or AI
teamId: the team the device belongs to
deviceId: the id of the device
saveName: the identifying name of the device’s type
nodeA: the id of the first node of the platform link (-1 for ground devices)
nodeB: the id of the second node of the platform link (-1 for ground devices)
t: the position on the link the device was made 1 (0 for ground devices)
See also: DestroyDevice, OnDeviceDestroyed, OnDeviceCreated, OnGroundDeviceCreated
Example Lua usage:
OnDeviceDestroyed
Called when a device is destroyed
teamId: the team the device belongs to
deviceId: the id of the device
saveName: the identifying name of the device’s type
nodeA: the id of the first node of the platform link (-1 for ground devices)
nodeB: the id of the second node of the platform link (-1 for ground devices)
t: the position on the link the device was made 1 (0 for ground devices)
See also: OnDeviceDeleted, OnDeviceCreated, OnGroundDeviceCreated
Example Lua usage:
OnDeviceConsumed
Called when a device has changed teams, possibly to neutral
oldTeamId: the previous team of the device
newTeamId: the current team of the device
deviceId: the id of the device
Example Lua usage:
OnDeviceTeamUpdated
Example Lua usage:
OnTerrainHit
Called when a projectile collides with a terrain block
terrainId: the id of the terrain block hit
damage: the raw damage carried by the projectile (may be reduced by other collisions)
projectileNodeId: the id of the projectile which hit the terrain
projectileSaveName: the type of the projectile
surfaceType: the surface type index hit
pos: the position of the impact
normal: the surface normal of the impact
See also: OnTerrainHitBeam, OnProjectileDestroyed, OnLinkHit, OnDeviceHit, GetSurfaceSaveName
Example Lua usage:
OnTerrainHitBeam
Called when a beam collides with a terrain block
terrainId: the id of the terrain block hit
damage: the damage carried by the beam
weaponId: the weapon that fired the beam
projectileSaveName: the projectile type of the beam
surfaceType: the surface type index hit
pos: the position of the impact
normal: the surface normal of the impact
See also: OnTerrainHit, OnWeaponFired, GetSurfaceSaveName, OnLinkHitBeam, OnDeviceHitBeam
Example Lua usage:
OnPortalUsed
Called when a projectile or beam passes through a portal
nodeA: the first node id of the source portal
nodeB: the second node id of the source portal
nodeADest: the first node id of the destination portal
nodeBDest: the second node id of the destination portal
objectTeamId: the owning team of projectile or beam
objectId: the projectile id, or the weapon’s id if beam
isBeam: true when a beam has been passed, otherwise a projectile
See also: OnShieldReflection
Example Lua usage:
OnShieldReflection
Called when a projectile or beam is reflected off a strut
nodeA: the first node id of the strut
nodeB: the second node id of the strut
objectTeamId: the owning team of projectile or beam
objectId: the projectile id, or the weapon’s id if beam
isBeam: true when a beam has been passed, otherwise a projectile
See also: OnPortalUsed
Example Lua usage:
OnLinkHit
Called when a projectile impacts a strut (not beams or splash damage)
nodeIdA: the first node id of the strut
nodeIdB: the second node id of the strut
objectId: the projectile id
objectTeamId: the owning team of projectile
objectSaveName: the type of the projectile
See also: OnPortalUsed, OnShieldReflection, OnLinkDestroyed, OnDeviceHit, OnTerrainHit
Example Lua usage:
OnLinkHitBeam
Called when a beame impacts a strut
nodeIdA: the first node id of the strut
nodeIdB: the second node id of the strut
weaponId: the weapon id
weaponTeamId: the owning team of projectile
projectileSaveName: the projectile type of the beam
See also: OnLinkHit, OnDeviceHitBeam, OnTerrainHitBeam
Example Lua usage:
OnLinkDestroyed
Called when a strut is destroyed or deleted
This is called for every segment of a rope
The link exists at the time of the call, and is removed immediately after
teamId: the owning team of the strut
saveName: the material type of the strut
nodeA: the first node id of the strut
nodeB: the second node id of the strut
breakType: one of the LINKBREAK_* values from forts.lua, e.g. LINKBREAK_PROJECTILE, LINKBREAK_DELETE
See also: OnLinkHit, OnLinkCreated, OnNodeDestroyed
Example Lua usage:
OnNodeDestroyed
Called when a structure node is destroyed
Does not include projectiles, see OnProjectileDestroyed instead
The node exists at the time of the call, and is removed immediately after
nodeId: the id of the node
selectable: true if the node could be selected (intermediate rope nodes are not selectable)
See also: OnProjectileDestroyed, OnLinkDestroyed
Example Lua usage:
OnNodeBroken
Called when a node is broken in two due to link rotation
Example Lua usage:
OnProjectileDestroyed
Called when a projectile node is destroyed
The node exists at the time of the call, and is removed immediately after
nodeId: the id of the projectile node
teamId: the owner of the projectile (can be None)
saveName: the type of the projectile
structureIdHit: the id of the last structure hit
See also: OnNodeDestroyed, OnProjectileRedirected
Example Lua usage:
OnProjectileRedirected
Called when a mesh projectile is redirected by a decoy
nodeId: the id of the projectile node
teamId: the owner of the projectile (can be None)
decoyTeamId: the owner of the decoy (can be None)
saveName: the type of the projectile
decoyNodeId: the id of the decoy causing the redirect
See also: OnProjectileDestroyed
Example Lua usage:
OnStructurePainted
Called when a new structure is identified
Each separate structure is assigned its own unique id
teamId: the owner of the structure
structureId: the assigned id of the structure
firstNodeId: the id with the lowest id in the structure
Example Lua usage:
OnProjectileCollision
Called when two projectiles collide in mid-air
Not called for projectile-beam collisions
teamIdA: the team of the first projectile
nodeIdA: the id of the first projectile
saveNameA: the type of the first projectile
teamIdB: the team of the second projectile
nodeIdB: the id of the second projectile
saveNameB: the type of the second projectile
See also: OnWeaponFired, OnProjectileDestroyed
Example Lua usage:
OnExecuteProjectileAction
Called when two projectiles collide in mid-air
nodeId: the id of the projectile
saveName: the type of the projectile
pos: the position of the impact
normal: the surface normal of the impact
hitType: the impact or expiry type
hitTeamId: the team of the impacting object
hitSaveName: the savename of the impacting object
See also: OnProjectileCollision
Example Lua usage:
OnWeaponFired
A weapon has spawned a projectile
also called when secondary projectiles are made from projectile effects
teamId: the owner of the weapon
saveName: the type of the weapon
weaponId: the id of the weapon
projectileNodeId: the id of the spawned projectile
projectileNodeIdFrom: the parent projectile for secondary projectile spawn (0 if spawned by weapon)
See also: OnWeaponFiredEnd, OnProjectileCollision, OnProjectileDestroyed
Example Lua usage:
OnWeaponFiredEnd
Called when a weapon has stopped firing (e.g. end of burst, end of beam)
teamId: the owner of the weapon
saveName: the type of the weapon
weaponId: the id of the weapon
See also: OnWeaponFired
Example Lua usage:
OnWeaponOverheated
Called when a weapon overheats
teamId: the owner of the weapon
saveName: the type of the weapon
weaponId: the id of the weapon
See also: OnWeaponFired, OnWeaponFiredEnd
Example Lua usage:
OnControlActivated
Called when a user interface control is pressed by the player
name: the name of the control
code: unused (will be nil)
WARNING: Do not change game state directly based on user input; use SendScriptEvent instead
Example Lua usage:
OnKey
The player has pressed a key or mouse button
WARNING: Do not change game state directly based on user input; use SendScriptEvent instead
Example Lua usage:
OnTeamDefeated
Called when a team has lost its last reactor
defeatedTeamId: the id of the team that has been destroyed
Example Lua usage:
OnGameResult
Called when the battle has been won
winningTeamId: the id of the winning team (1 or 2)
customCondition: true when the won via a custom script condition
Example Lua usage:
OnShowResult
Called when the victory/defeat banner is displayed
This happens some time after the result is actually decided
Example Lua usage:
OnBuildError
Called when the player makes a mistake during building
teamId: the teamId of the player
type: one of the BUILDERROR_* values defined in forts.lua
Example Lua usage:
OnDoorControl
Called when a door is opened by a player (not AI)
teamId: the owner of the door
nodeA: the id of the first node of the door
nodeB: the id of the second node of the door
opening: true if the door is opening, otherwise it is closing
Example Lua usage:
OnDoorState
Called when a door changes state
teamId: the owner of the door
nodeA: the id of the first node of the door
nodeB: the id of the second node of the door
doorState: one of the DS_* values from forts.lua, e.g. DS_CLOSED, DS_OPENING
Example Lua usage:
OnRepairArea
Called when a player repairs an area
teamId: the team of the player
pos: the centre of the area
links: the number of struts that are now repairing in the area
fireSegments: the number of fire segments in the area being extinguished
devices: the number of devices now repairing in the area
See also: RepairLink, RepairDevice
Example Lua usage:
OnGroupAddition
Called when the local player adds a device to a group
the group may already have other slaves
index: the group identifier
masterDeviceId: the controlling weapon
slaveDeviceId: the added device
See also: OnGroupFired
Example Lua usage:
OnGroupFired
Called when the player fires a weapon group
index: the group number (-1 for a group unassigned to a number)
masterDeviceId: the device id of the leader of the group
cycle: set to true when using round robin firing
fired: the number of weapons actually fired
count: the number of weapons in the group
Example Lua usage:
OnTargetDisrupted
Called when a spotter for a missile type weapon aims into a disruption field (e.g. smoke)
teamId: the owner of the spotting device
deviceId: the id of the spotting device
See also: OnStructureCreateDisrupted, OnDeviceCreateDisrupted
Example Lua usage:
OnStructureCreateDisrupted
Called when a player or AI attempts to build structure in a disruption field
teamId: the team of the disrupted player or AI
pos: the attempted location for the construction
See also: OnTargetDisrupted, OnDeviceCreateDisrupted
Example Lua usage:
OnDeviceCreateDisrupted
Called when a player or AI attempts to build a device in a disruption field
teamId: the team of the disrupted player or AI
saveName: the type of the device attempted to build
pos: the attempted location for the construction
See also: OnTargetDisrupted, OnStructureCreateDisrupted
Example Lua usage:
OnAchievement
Called when the player acheives a mission objective
index: the index of the objective (0, 1, or 2)
Example Lua usage:
OnContextMenuDevice
Called when the player opens the context menu on a device
Used for customising the context menu
Example Lua usage:
OnContextMenuStrut
Called when the player opens the context menu on a strut
Used for customising the context menu
Example Lua usage:
OnContextButtonDevice
Called when the player clicks on a device context button added via AddContextButton
Example Lua usage:
OnContextButtonStrut
Called when the player clicks on a strut context button added via AddContextButton