Files
tpf3-overtake/docs/research/overtake-feasibility.md
2026-10-04 21:58:04 +02:00

38 lines
4.7 KiB
Markdown

# Can TpF3 scripting make cars overtake?
Issue #2 (part of map #1). Researched 2026-10-04.
**Verdict: not feasible with the documented API.** Scripts can observe vehicles and scale a vehicle's top speed, but nothing documented lets a script change a road vehicle's lane, path position or per-tick movement. Overtaking would need engine support that the docs do not show.
## Sources
- Wiki, modifiers/filters: https://wiki.transportfever3.com/doku.php?id=modding:scripting:modifiersfilters
- Wiki, base config: https://wiki.transportfever3.com/doku.php?id=modding:scripting:baseconfig
- Script-doc index: https://wiki.transportfever3.com/script-doc/ (pages `api/engine.html`, `api/engine/system.html`, `api/cmd.html`, `content/scripts/gamescript.html`)
- Local example mod: `.examples/ug_tf3_example_config_change` (uses `preRunFn` to set `baseConfig.trainAccelerationFactor`)
## Findings
1. **The "modifiers/filters" page is about resource loading, not runtime behaviour.** `addModifier(category, fn)` edits resource data (`fileName`, `data`) as it loads, and `addFileFilter` toggles resource visibility. Vehicle-related categories are only `loadModule`, `loadMultipleUnit`, plus the `model/vehicle` and `model/car` filters. They cannot touch live vehicle movement. The page says it "is not yet adapted for Transport Fever 3", so it may be outdated.
2. **BaseConfig has no road-vehicle or traffic-behaviour fields.** The vehicle-related ones are `trainAccelerationFactor`, `trainBrakeDeceleration`, `simulateCargoWeight`, `loadspeedPenaltyForTrainOverlength` and `maxVehicleCloneAmount`. All are global and train-oriented. This runs once in `preRunFn`.
3. **Game script phases.** `gamescript.html` defines `update`, `postUpdate` and `handleEvent`, which run on the engine state with mutable script state, and `guiUpdate` and `guiHandleEvent` for the GUI. "Mutable" here means the script's own state, not engine entities. `api.engine` is documented as "for reading the game engine state". So per-tick script code can read the world but only change it through `api.cmd` commands.
4. **Read access to vehicles exists but is thin.** `api.engine.system.landVehicleMoveSystem` exposes `getVehicleInfo(vehicleEntity)`, whose `LandVehicleMoveInfo` return type is not expanded in the docs. It also has `getBlockedTrains`, `isTrainWaitingForFreePath` and `forEach` (train oriented). Components include `Engine.Component.MovePath` (`path`, `dyn.pathPos`, `dyn.speed`, `dyn.accel`, `blocked`, `occupiedFrontIndex`, `occupiedBackIndex`) and `Engine.Component.LandVehicle` (`isTram`, `dyn.brakingTimer`, `turnLeft`, `turnRight`). `BaseEdge` carries `laneConfig` and `BaseNodeConfig.laneConnections`.
5. **Write access is limited to commands.** The relevant `api.cmd` entries are `makeVehicleSetModifiersCmd(vehicle, TransportVehicle.Modifiers)`, `makeVehicleSetStoppedByUserCmd`, `makeVehicleSendToDepotCmd`, `makeVehicleReverseCmd`, `makeVehicleSetLineCmd` and `makeVehicleTryToDepartCmd`. There is no command to set a `MovePath`, speed, lane or position on a land vehicle. `makeComponentExchangeCmd` is marked debug and its doc says it accepts only `EmissionEmitter` or `ModelInstanceList`. `makeCustomVehicleCreateOrUpdateCmd` takes a `Carrier` and an optional `movePathAircraft`, so it is aimed at aircraft or custom vehicles rather than road traffic.
6. **No overtaking concept appears anywhere.** A text search of `api.engine`, `api.engine.system` and `api.cmd` found no "overtake" or "passing" terms.
## Candidate mechanisms
| Mechanism | What it gives | Overtaking? |
|---|---|---|
| `makeVehicleSetModifiersCmd` with `topSpeedScale` | Per-vehicle top speed scaling | No. A faster car still queues behind a slower one. |
| `BaseConfig` in `preRunFn` | Global acceleration or braking (trains only) | No |
| Lane config (`BaseEdge.laneConfig`, `laneConnections`) via construction or street definitions | Static lane layout, for example an extra lane built into the road | Only as static road design. Whether the engine's car AI uses a spare lane to pass is undocumented. |
| `landVehicleMoveSystem` / `MovePath` reads | Observe speed, position and blockage per tick | Detection only |
| Custom entities / custom vehicles (`makeCustomEntity*`, `makeCustomVehicleCreateOrUpdateCmd`) | Script-driven fake visuals | Theoretically a script could despawn a real car and animate a fake one past the blocker. This is a heavy hack with unproven viability for road vehicles. |
## Open questions (not answered by the docs)
- The fields of `LandVehicleMoveInfo`.
- Whether the engine already supports passing on multi-lane or bus-lane roads, outside of script control.
- Whether anything outside the published script-doc (native mod interfaces) exists. Testing in-game would be the next step.