Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9edc9c065a | ||
|
|
0ef87ebab7 | ||
|
|
86a48e75c9 | ||
|
|
94ea772fa8 | ||
|
|
035adb5762 | ||
|
|
8e145a2870 |
No files matched your search
@@ -0,0 +1,2 @@
|
||||
tlconfig.lua
|
||||
.claude/settings.local.json
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"pdesaulniers.vscode-teal"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
## Agent skills
|
||||
|
||||
### Issue tracker
|
||||
|
||||
Issues live in Gitea (`git.arthurerlich.de`), driven with the `tea` CLI. See `docs/agents/issue-tracker.md`.
|
||||
|
||||
### Triage labels
|
||||
|
||||
Default five-role vocabulary (`needs-triage`, `needs-info`, `ready-for-agent`, `ready-for-human`, `wontfix`). See `docs/agents/triage-labels.md`.
|
||||
|
||||
### Domain docs
|
||||
|
||||
Single-context: one `CONTEXT.md` + `docs/adr/` at the repo root. See `docs/agents/domain.md`.
|
||||
|
||||
## Modding
|
||||
|
||||
- The mod is `mod/` (junctioned into the game's `staging_area` as `haylan_tf3_overtake`). Scripts are Teal (`.tl`, typed Lua); `mod.json` goes at the root of `mod/`.
|
||||
- Type-check with `tl check mod/<file>.tl` (run from the repo root; it reads `tlconfig.lua`). `tl` is type-check only; whether the game compiles `.tl` itself is undocumented.
|
||||
- `tlconfig.lua` and `.claude/settings.local.json` are machine-local and gitignored. Copy `tlconfig.template.lua` to `tlconfig.lua` and replace `<tf3_install_folder>` with the game's install path (here `D:/SteamLibrary/steamapps/common/Transport Fever 3/`).
|
||||
- Authoritative API types: `<install>/api/tealdef` and `<install>/base/tealdef`. Read them, and the offline docs in `docs/reference/`, before guessing an API. Research notes are in `docs/research/`; vocabulary in `CONTEXT.md`.
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
# TpF3 Overtake
|
||||
|
||||
A Transport Fever 3 script-mod that lets road vehicles pass slower vehicles instead of queueing behind them.
|
||||
|
||||
## Language
|
||||
|
||||
**Overtaking**:
|
||||
A faster vehicle getting past a slower one ahead of it on the same road, as seen by the player. It may be a visual illusion (the passer drives through the blocker) rather than a real lane change.
|
||||
_Avoid_: Passing, bypass
|
||||
|
||||
**Blocker**:
|
||||
The slower vehicle ahead that the passer would otherwise queue behind.
|
||||
_Avoid_: Obstacle, lead vehicle
|
||||
|
||||
**Passer**:
|
||||
The faster vehicle that overtakes the blocker.
|
||||
_Avoid_: Overtaker
|
||||
|
||||
**Player-owned vehicle**:
|
||||
A vehicle belonging to one of the player's lines. Only these are in scope for overtaking.
|
||||
_Avoid_: AI vehicle, ambient traffic
|
||||
|
||||
**Same-direction multilane road**:
|
||||
A road with two or more lanes in the passer's direction, where overtaking needs no oncoming-traffic check.
|
||||
|
||||
**Two-way road**:
|
||||
A road with one lane per direction, where overtaking is only safe if no oncoming vehicle is in the way.
|
||||
@@ -0,0 +1,5 @@
|
||||
require "api_def"
|
||||
require "content_def"
|
||||
|
||||
-- list your mods here, if you provide your own d.tl definitions
|
||||
-- require "example_mod_1"
|
||||
@@ -0,0 +1,51 @@
|
||||
# Domain Docs
|
||||
|
||||
How the engineering skills should consume this repo's domain documentation when exploring the codebase.
|
||||
|
||||
## Before exploring, read these
|
||||
|
||||
- **`CONTEXT.md`** at the repo root, or
|
||||
- **`CONTEXT-MAP.md`** at the repo root if it exists — it points at one `CONTEXT.md` per context. Read each one relevant to the topic.
|
||||
- **`docs/adr/`** — read ADRs that touch the area you're about to work in. In multi-context repos, also check `src/<context>/docs/adr/` for context-scoped decisions.
|
||||
|
||||
If any of these files don't exist, **proceed silently**. Don't flag their absence; don't suggest creating them upfront. The `/domain-modeling` skill (reached via `/grill-with-docs` and `/improve-codebase-architecture`) creates them lazily when terms or decisions actually get resolved.
|
||||
|
||||
## File structure
|
||||
|
||||
Single-context repo (most repos):
|
||||
|
||||
```
|
||||
/
|
||||
├── CONTEXT.md
|
||||
├── docs/adr/
|
||||
│ ├── 0001-event-sourced-orders.md
|
||||
│ └── 0002-postgres-for-write-model.md
|
||||
└── src/
|
||||
```
|
||||
|
||||
Multi-context repo (presence of `CONTEXT-MAP.md` at the root):
|
||||
|
||||
```
|
||||
/
|
||||
├── CONTEXT-MAP.md
|
||||
├── docs/adr/ ← system-wide decisions
|
||||
└── src/
|
||||
├── ordering/
|
||||
│ ├── CONTEXT.md
|
||||
│ └── docs/adr/ ← context-specific decisions
|
||||
└── billing/
|
||||
├── CONTEXT.md
|
||||
└── docs/adr/
|
||||
```
|
||||
|
||||
## Use the glossary's vocabulary
|
||||
|
||||
When your output names a domain concept (in an issue title, a refactor proposal, a hypothesis, a test name), use the term as defined in `CONTEXT.md`. Don't drift to synonyms the glossary explicitly avoids.
|
||||
|
||||
If the concept you need isn't in the glossary yet, that's a signal — either you're inventing language the project doesn't use (reconsider) or there's a real gap (note it for `/domain-modeling`).
|
||||
|
||||
## Flag ADR conflicts
|
||||
|
||||
If your output contradicts an existing ADR, surface it explicitly rather than silently overriding:
|
||||
|
||||
> _Contradicts ADR-0007 (event-sourced orders) — but worth reopening because…_
|
||||
@@ -0,0 +1,35 @@
|
||||
# Issue tracker: Gitea
|
||||
|
||||
Issues and specs for this repo live as Gitea issues on `git.arthurerlich.de` (repo `haylan/tpf3-overtake`). Use the `tea` CLI for all operations (see the `gitea-tea` skill).
|
||||
|
||||
## Conventions
|
||||
|
||||
- **Create an issue**: `tea issues create --title "..." --description "..."`. Use a heredoc for multi-line bodies.
|
||||
- **Read an issue**: `tea issues <number> --comments`
|
||||
- **List issues**: `tea issues list --state open --fields index,title,body,labels` with `--labels` filters as needed.
|
||||
- **Comment on an issue**: `tea comment <number> "..."`
|
||||
- **Apply / remove labels**: `tea issues edit <number> --add-labels "..."` / `--remove-labels "..."`
|
||||
- **Close**: `tea issues close <number>` (comment first with `tea comment`)
|
||||
|
||||
Infer the repo from `git remote -v` — `tea` does this inside a clone.
|
||||
|
||||
## Pull requests as a triage surface
|
||||
|
||||
**PRs as a request surface: no.**
|
||||
|
||||
## When a skill says "publish to the issue tracker"
|
||||
|
||||
Create a Gitea issue.
|
||||
|
||||
## When a skill says "fetch the relevant ticket"
|
||||
|
||||
Run `tea issues <number> --comments`.
|
||||
|
||||
## Wayfinding operations
|
||||
|
||||
Used by `/wayfinder`. The **map** is a single issue labelled `wayfinder:map`; **child** tickets are issues labelled `wayfinder:<type>` (`research`/`prototype`/`grilling`/`task`) with `Part of #<map>` at the top of the body and listed in the map's task list.
|
||||
|
||||
- **Blocking**: a `Blocked by: #<n>, #<n>` line at the top of the child body. Unblocked when every blocker is closed.
|
||||
- **Frontier query**: open children of the map, minus any with an open blocker or an assignee; first in map order wins.
|
||||
- **Claim**: assign the issue to yourself (`tea issues edit <n> --add-assignees <user>`).
|
||||
- **Resolve**: comment the answer, close the issue, then append a pointer to the map's Decisions-so-far.
|
||||
@@ -0,0 +1,15 @@
|
||||
# Triage Labels
|
||||
|
||||
The skills speak in terms of five canonical triage roles. This file maps those roles to the actual label strings used in this repo's issue tracker.
|
||||
|
||||
| Label in mattpocock/skills | Label in our tracker | Meaning |
|
||||
| -------------------------- | -------------------- | ---------------------------------------- |
|
||||
| `needs-triage` | `needs-triage` | Maintainer needs to evaluate this issue |
|
||||
| `needs-info` | `needs-info` | Waiting on reporter for more information |
|
||||
| `ready-for-agent` | `ready-for-agent` | Fully specified, ready for an AFK agent |
|
||||
| `ready-for-human` | `ready-for-human` | Requires human implementation |
|
||||
| `wontfix` | `wontfix` | Will not be actioned |
|
||||
|
||||
When a skill mentions a role (e.g. "apply the AFK-ready triage label"), use the corresponding label string from this table.
|
||||
|
||||
Edit the right-hand column to match whatever vocabulary you actually use.
|
||||
@@ -0,0 +1,37 @@
|
||||
# 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.
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"authors": [
|
||||
{
|
||||
"name": "haylan",
|
||||
"role": "CREATOR"
|
||||
}
|
||||
],
|
||||
"description": "Lets road vehicles overtake slower vehicles (work in progress).",
|
||||
"summary": "Vehicle overtaking (WIP)",
|
||||
"name": "Overtake",
|
||||
"tags": [
|
||||
"script"
|
||||
],
|
||||
"url": ""
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
local mod = {}
|
||||
|
||||
mod.preRunFn = function(_configDict : {{string, string}}, _allModParams : {string : {string : integer}}, _baseConfig : BaseConfig)
|
||||
print("[haylan_tf3_overtake] hello from preRunFn")
|
||||
end
|
||||
|
||||
mod.postRunFn = function(_configDict : {{string, string}}, _allModParams : {string : {string : integer}})
|
||||
print("[haylan_tf3_overtake] hello from postRunFn")
|
||||
end
|
||||
|
||||
return mod
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"modId": "haylan_tf3_overtake",
|
||||
"revision": 1,
|
||||
"severityAdd": "None",
|
||||
"severityRemove": "Warning",
|
||||
"cosmetic": false,
|
||||
"preRunScript": {
|
||||
"fileName": "haylan_tf3_overtake::mod.script@preRunFn"
|
||||
},
|
||||
"postRunScript": {
|
||||
"fileName": "haylan_tf3_overtake::mod.script@postRunFn"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
return {
|
||||
include_dir = {
|
||||
-- ensure to set proper paths for the definitions for the base game
|
||||
"<tf3_install_folder>api/tealdef",
|
||||
"<tf3_install_folder>base/tealdef",
|
||||
|
||||
-- list your mods here, if you provide your own d.tl definitions
|
||||
-- "example_mod_1",
|
||||
},
|
||||
global_env_def = "all_def"
|
||||
}
|
||||
Reference in new issue
Block a user