Files

5.8 KiB

TpF3 mod tooling and mod structure

Resolves issue #3. Offline copies of sources: docs/reference/wiki/ (wiki, converted to Markdown) and docs/reference/script-doc/ (selected script-doc pages; the full site has ~320 pages, we kept api*, app, and a few content/ modules). Example mod: .examples/ug_tf3_example_config_change.

Mod folder layout

Source: wiki modding:general:moddefinition.

<author>_<modname>/          dir name not functional; keep == modId
  _metadata/modinfo.json     name (<=32 chars), summary (<=100), description, localization, authors, tags, dependencies (mod.io ids), url
  _metadata/0.png, N.png     1920x1080 previews; description.html optional
  content/                   all resources; mirror base-game structure
    mod.script.tl            optional script functions
  mod.json                   technical definition
  strings.json               optional translations {lang:{key:text}}

Mods are plain directories. Do not edit the install dir. Install by copying into staging_area/ in the userdata dir (e.g. ...\Steam\userdata\<id>\3493540\local\staging_area\; userdata folder reachable via Settings > Advanced > Open user data folder). modId precedence if duplicated: Staging Area > Manual install dir > Subscribed.

mod.json

Keys: modId (a-z0-9_, <author>_<modname>, no _3 major suffix as in TpF2), revision (int, bump per release), severityAdd/severityRemove (None|Warning|Critical; defaults None/Warning), visible (default true), cosmetic (true only if no simulation impact; keeps achievements), dependencies[] ({mod:{modId,revisionMin,revisionMax}, modInfo:{displayName,url}, loadBefore (default true), optional (default false)}), incompatibilities[], params[] (key, name, tooltip, uiType Button|Slider|ComboBox|IconButton|CheckBox, values, numbers, defaultIndex 0-based while Lua/Teal indices are 1-based), and script hooks. Static JSON on purpose so a broken definition cannot prevent game start.

Example mod's mod.json: modId ug_tf3_config_change, revision 1, severityAdd None, severityRemove Warning, cosmetic false, preRunScript.fileName = "ug_tf3_config_change::mod.script@preRunFn". modinfo.json there uses tag script; wiki sample uses "Script Mod" (see modding:general:modtags for the official list).

Teal vs Lua

Source: wiki modding:general:syntax. All scripts are Lua (5.2 manual referenced); scripts "usually use the Teal dialect" (statically typed Lua: : type annotations, record). Only local variables, no globals. Types: any, nil, boolean, integer, number, string. Teal source files are .tl (e.g. mod.script.tl); wiki examples still also show .con.lua/.script.lua for constructions, so both coexist. Import: ug_require "::/scripts/name.lua". Resource refs use <modid>::/path. Script-doc signatures are written in Teal (global record Api, function(...): T), so it doubles as the type definition source (BaseConfig, ModelMetadata, etc.).

Entry points

Source: wiki modding:general:modscripts; example mod.script.tl. Referenced from mod.json as <modid>::<file-no-ext>@<function>. Base-game functions run first, then mods in activation order.

  • preRunScript (preRunFn): before resources load. Args (configDict {{string,string}}, allModParams {string:{string:integer}}, baseConfig BaseConfig). Mutate baseConfig fields (e.g. example sets baseConfig.trainAccelerationFactor = 0.5). Full property list: wiki modding:scripting:baseconfig.
  • runScript (runFn): when mod loads; (configDict, allModParams). Can register file filters / resource modifiers (see modding:scripting:modifiersfilters), but postRun preferred.
  • postRunScript (postRunFn): once after all resources loaded; (configDict, allModParams). Use api.res.* (e.g. modelRep.forEachModelWithMetadata, getAsTable/setAsTable/addAsTable, setVisible). Cannot add new 3D resources, only reference existing .mdl. Own params: allModParams[getCurrentModId()].<key>. The example module shape is local mod = {}; mod.preRunFn = function(...) end; return mod.

Logging and debugging

Source: wiki modding:tools:ingame, modding:scripting:api.

  • Enable debug mode: debugMode = true in settings.lua, or Settings > Advanced. Enables hotkeys, debug views, Debug Tool Window (AltGr+D).
  • Ingame console (key below ESC): shows stdout.txt output, runs Lua; commands \clear, \stdout <on|off>, \history; CTRL+SPACE autocomplete.
  • debugPrint(<table>) dumps table structures; wiki recommends testing API calls in the console.
  • Model Editor opens a console window with debug output. Script-doc has no dedicated logging module (searched api*); print use is not documented, so verify empirically.

Editor tooling

Source: wiki modding:tools:external.

  • VS Code recommended (Notepad++ alternative, Lua highlighting only). Install Teal (github.com/teal-language/tl) plus extensions sumneko.lua (LuaLS) and pdesaulniers.vscode-teal. "The Model Editor automatically creates necessary workspace configuration files in the Staging Area" (so editing mod scripts inside the staging area picks up Teal config; the config contents are not documented on the wiki).
  • Model Editor (ModelEditor.bat in install dir; config under %APPDATA%/Transport Fever 3/ where userDataPath must be set with forward slashes) for models/vehicles. Blender (FBX), GIMP/Paint.NET/Compressonator (DDS) for assets.
  • Script reference: https://wiki.transportfever3.com/script-doc/ (root api global: res, gui, engine, type, util, cmd, modhub; plus app).

Gaps

Not resolved by sources: exact contents of the auto-generated Teal workspace files, whether print reaches stdout.txt, how a .tl is compiled (game appears to load Teal directly, undocumented). Wiki pages for baseconfig/modifiersfilters were saved; the 320 script-doc content/ modules were mostly not.