The main file for script-based modifications is main.lua. This file is executed when the Mod is loaded.

There are multiple ways how a Mod can do its work:

  • Config variables: the game configuration can be changed directly by setting the appropriate values in the configuration table.
  • File filter: a function that is invoked for all files in a directory. The function can then decide whether the file should be included or not. The file filter can access the data in the file, making it a very versatile tool.
  • Modifier: a function that is invoked after a resource file has been loaded. It is used for modifying the data on the fly.

Config variables

The configuration variables are accessible via the global game.config table.


Building costs are initially loaded from the file res\config\costs.lua (see note below) and can be modified as follows:
game.config.costs.terrainRaise = 5.0

Cargo types

Cargo types are loaded from res\config\cargotypes.lua (see note below). To add a new cargo type, one would write:
table.insert(game.config.cargotypes, { id = "STEEL", name = _("Steel") })

Note: it is not recommended to edit these files (costs.lua, cargotypes.lua). They mainly exist for historic/compatibility reasons. Instead, costs and cargo types should be modified from main.lua as described on this page.


Disable “main connections”: game.config.enforceMainConnections = false

Terrain, Environment

Terrain and environment configuration works slightly different as before. Instead of a single configuration, there are multiple “named configurations”. These are presented in a list so that the user can choose one of them when starting a new game.

Terrain configuration is mainly about setting different textures for different purposes, while the environment configuration includes light/fog parameters and textures for the sky box and the environment map.

See res\config\base_config.lua for the initial configuration, and dlcs\usa_1\main.lua for how to create derived configurations.

Town and street names

Again, it’s possible to define multiple name lists for the user to choose from.

To add a new name list for e.g. Bavarian town/street names, one would first create the following files and directories.

Train Fever\

If necessary, town names can be defined in different languages, but they must at least be specified in English, since this is the fallback language.

Then, to register the directory with the game, the following line is added to main.lua:
setConfig("nameList", "bavaria", { name = _("Bavarian"), folder = "bavaria" })

The second parameter is a key used internally.

File filters

File filters filter the content of a directory, i.e. they define which files are visible to the game. When starting a new game, the user can choose a filter for each category. That is, only one filter is active per category.

The following code installs a filter for vehicles which removes all non-steam-locomotives from the game. The precondition (1) is necessary because all models (trees, depots etc.) go through this filter. See res\config\base_filters.lua for reference.

local function myFilter(fileName, data)
  if not fileFilters.model.vehicle(fileName, data) then                 -- (1)
    return false
  if data.metadata.railVehicle and data.metadata.railVehicle.engines and
      #data.metadata.railVehicle.engines == 1 and data.metadata.railVehicle.engines[1].type ~= "STEAM" then
    return false
  return true

addFileFilter("model/vehicle", "steam", _("Steam locomotives"), myFilter)

Again, the second parameter of addFileFilter is a key used to internally identify this filter.

File filters can be specified for the following categories:

  • model/vehicle
  • model/tree
  • model/industry
  • model/other
  • multipleUnit
  • building
  • street


Modifier functions allow to modify resources on the fly at the time they’re loaded. This is useful to edit the same value in multiple files; in fact it’s much more convenient than copying and editing all affected files by hand. Furthermore, multiple modifiers can be added by different Mods without one Mod overriding the files of the other.

For example, the following modifier function sets the top speed of all rail vehicles to 125%:

local function myModifier(fileName, data)
  if data.metadata.railVehicle then
    data.metadata.railVehicle.topSpeed = 1.25 * data.metadata.railVehicle.topSpeed

  return data

addModifier("loadModel", myModifier)

Modifiers can be defined for the following catgories:

  • loadModel
  • loadBridge
  • loadBuilding
  • loadBuildingMaterial
  • loadMultipleUnit
  • loadRailroadCrossing
  • loadSoundSet
  • loadStreet
  • loadTrainStation
  • loadTunnel

1 thought on “Scripting

Comments are closed.