Files

50 lines
5.8 KiB
Markdown

# 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.