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). MutatebaseConfigfields (e.g. example setsbaseConfig.trainAccelerationFactor = 0.5). Full property list: wikimodding:scripting:baseconfig.runScript(runFn): when mod loads;(configDict, allModParams). Can register file filters / resource modifiers (seemodding:scripting:modifiersfilters), but postRun preferred.postRunScript(postRunFn): once after all resources loaded;(configDict, allModParams). Useapi.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 islocal mod = {}; mod.preRunFn = function(...) end; return mod.
Logging and debugging
Source: wiki modding:tools:ingame, modding:scripting:api.
- Enable debug mode:
debugMode = trueinsettings.lua, or Settings > Advanced. Enables hotkeys, debug views, Debug Tool Window (AltGr+D). - Ingame console (key below ESC): shows
stdout.txtoutput, 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*);printuse 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) andpdesaulniers.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.batin install dir; config under%APPDATA%/Transport Fever 3/whereuserDataPathmust 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
apiglobal: res, gui, engine, type, util, cmd, modhub; plusapp).
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.