Actor.hpp

Header notes
Native reflection signatures for Unreal's AActor / UActorComponent.
See README.md for the doc-comment convention and why fields are void*.

No UE4SS/Unreal includes on purpose: every *_Params here matches the Unreal
ProcessEvent parameter block by raw layout, so this header parses standalone.

Actor::K2_GetActorLocation

confirmed

World-space location of the actor.

Returns
FVector Location World location in Unreal units (cm).
Actor.hpp:11

Actor::K2_GetActorRotation

confirmed

World-space rotation of the actor.

Returns
FRotator Rotation Pitch/Yaw/Roll in degrees (memory order).
Actor.hpp:21

ActorComponent::GetOwner

candidate

The actor that owns this component (for reading a component's world transform via the actor's K2_GetActor* functions).

Returns
AActor* ReturnValue Owning actor, or null.
Actor.hpp:31

Actor::GetAttachParentActor

confirmed

The actor this actor is attached to. Confirmed in-game: the driver pawn (TS2DefaultDriverPawn_C) is attached to the rail vehicle it is driving (e.g. RVV_..._Class805_..._C), so this is TSM's link from the local player to their driven vehicle.

Returns
AActor* ReturnValue Parent actor, or null when unattached.
Actor.hpp:42

DLCManager.hpp

Header notes
UDLCManagementFunctionLibrary — TSW's content-on-demand API (module
TS2Prototype). A loco's cooked assets aren't loadable on a client that hasn't
loaded that loco this session (the AssetRegistry only indexes primary assets
like RVDs, and leaf meshes aren't reachable until the content is loaded). The
WORKING recipe for rendering a remote player's train (see Docs/dynamic-asset-
loading.md, and Game/Assets.cpp pull_remote_mesh):
  1. GetAllVehiclesForFreeRoam → find the entry whose SoftObject is under the
     loco's mount (e.g. "/AABS_Class805/").
  2. RequestContentLoad(that entry, FreeRoamTrainEntry) — makes the loco's
     content reachable (async).
  3. KismetSystemLibrary::LoadAsset(mesh path) — pulls the specific mesh in.
  4. Find the mesh by object name (leaf meshes are never registry-indexed).

Enum values are from the TSW6 dump (Docs/Dumps/CXXHeaderDump/TS2Prototype_enums.hpp).

DLCManagementFunctionLibrary::GetAllVehiclesForFreeRoam

working

Enumerate every free-roam-spawnable vehicle the player owns — INCLUDING DLC whose pak isn't mounted yet (this is what the sandbox/free-roam menu lists). OutList is TArray<FCachedTrainEntry>; each entry's FCachedContentPiece::SoftObject (offset 0) is the train-entry soft path (an RVD) to feed the content loader.

enumerates owned DLC incl. not-yet-loaded locos.

DLCManager.hpp:52

DLCManagementFunctionLibrary::RequestContentLoad

working

Async (void) content load. Feed a free-roam entry's SoftObject with category FreeRoamTrainEntry. Doesn't crash (unlike the Synchronous variant on loco targets) and makes the loco's content *reachable* over ~seconds; a streamable LoadAsset then pulls the actual meshes.

the content trigger used by Assets::request_loco_content.

DLCManager.hpp:61

DLCManagementFunctionLibrary::IsAssetPathLoadable

working

Whether TSW's content system can load the asset at `InPath`. NOTE: returns TRUE for owned-but-unloaded leaf meshes even though they aren't yet directly loadable — it means "TSW knows about it", not "reachable right now". Diagnostic — no side effects.

(diagnostic)

DLCManager.hpp:86

DLCManagementFunctionLibrary::RequestContentLoadSynchronous

crashes

Synchronous content load. DEAD END: on real loco targets (RVD / formation) it hits a UE fatal check() and crashes the game (minidump-confirmed); on a mesh target it no-ops. Use the async RequestContentLoad instead. Kept only to document the failure.

do not call.

DLCManager.hpp:100

DLCManagementFunctionLibrary::GetActiveMountPoints

working

Returns TSet<FString> of TSW's registered content mount points (e.g. "/AABS_Class805/"). NOTE: presence here means TSW knows the content, NOT that its files are reachable by the loader yet.

(diagnostic)

DLCManager.hpp:108

Doors.hpp

Header notes
Vehicle feature surface for SOS phase E (doors/pantograph -> the wire's
VehicleFeatures bits). Mined from the dump 2026-07-18; door state is read
via plain reflected PROPERTIES (no calls — the sandbox spike taught us cold
UFunction calls into unfamiliar systems can fatal-check), pantograph via
IsDeployed(), the same call class as the proven-safe component getters.

Enum values (TS2Prototype_enums.hpp):
  EDoorOpenState (UDoorComponent.State):    0 Open, 1 Closed, 2 Opening, 3 Closing
  EDoorState (UDoorV2Component.TargetState): 0 Indeterminate, 1 Open, 2 Closed

Lights: URailVehicleComponent only exposes switch DELEGATES (no state
property found) — the wire's lights byte stays reserved until a readable
source turns up.

UDoorComponent (property reads only)

untested

Legacy door component; `State` (EDoorOpenState, u8) is the live open state, `Position` (float 0..1) the blend.

(dump 2026-07-18) — verify owners via `train features`

Doors.hpp:19

UDoorV2Component (property reads only)

untested

VHID door; `TargetState` (EDoorState, u8) is where the door is headed (Open while opening — right level-state for sync).

(dump 2026-07-18)

Doors.hpp:27

UPantographComponent::IsDeployed

untested

Whether this pantograph is up.

Returns
bool ReturnValue

(dump 2026-07-18)

Doors.hpp:35

Gameplay.hpp

Header notes
UTS2GameplayFunctionLibrary — TSW's gameplay BP library (module TS2Prototype).
Currently catalogues the scenario/world-entry path: the autonomous test harness
needs the game IN a route world (a pawn in the menu background is not enough —
no ribbon network exists there), and LoadScenario is the menu's own function for
entering one. See Game/Assets.cpp `asset scenario-load`.

TS2GameplayFunctionLibrary::LoadScenario

untested

(const UObject* WorldContextObject, UScenarioDefinition* Scenario) — the route/scenario select screen's own "enter this scenario" call. Triggers the full level travel + scenario setup (delegates TS2GameInstance::OnLoadScenarioBegin/Complete fire around it). WorldContextObject: the menu pawn works (same convention as the DLC library calls in Game/Assets.cpp).

derived from the TSW6 dump only; verify in-game.

Gameplay.hpp:16

UUIFunctionLibrary::SetSelectedRoute / SetEnteredThroughRouteSelection

do-not-call

The main-menu's selection state helpers. DO NOT call these with hand-marshalled structs: a copied 0xF0 FCachedRouteDefinition is unverified state, and GetFullCachedContentList (the natural source) HANGS THE GAME THREAD from the menu (2026-08-28, twice). The world-entry gate lives inside LoadScenario's own state machine instead — see Game/Assets.cpp list_scenarios.

wedged the game thread; kept only as a warning.

Gameplay.hpp:26

KismetSystemLibrary.hpp

KismetSystemLibrary::ExecuteConsoleCommand

candidate

Run a command string through the engine's console dispatcher. Unlike calling a UFunction directly, this reaches BOTH UFUNCTION(exec) commands and native IConsoleManager-registered commands — e.g. TSW's ts2.rtt.*/ts2.dbg.* family (SpawnFormation, RouteMeTo, RemoveTrainFromTrack, ...), which don't appear in the reflection dump at all because they're not UFunctions. Candidate alternative to hand-marshalled SpawnFormation/SetTrainEntry calls — see tsm-console-command-spawn-lead memory. Console output goes to UE's own log, not TSM's — observe via before/after diffs or in-game behaviour, not a captured return string.

Parameters
  • WorldContextObject const UObject* Any in-world object.
  • Command FString e.g. "ts2.rtt.SpawnFormation ...".
  • SpecificPlayer APlayerController* Target player; null = default.
KismetSystemLibrary.hpp:21

KismetSystemLibrary::DrawDebugSphere

candidate

Draw a wireframe debug sphere (used for remote player markers).

Parameters
  • WorldContextObject const UObject* Any in-world object.
  • Center FVector World location (cm).
  • Radius float Sphere radius (cm).
  • Segments int32 Wireframe segments.
  • LineColor FLinearColor RGBA 0..1.
  • Duration float Seconds to persist (0 = one frame).
  • Thickness float Line thickness.
KismetSystemLibrary.hpp:44

KismetSystemLibrary::DrawDebugBox

candidate

Draw a wireframe debug box (used for remote train markers).

Parameters
  • WorldContextObject const UObject* Any in-world object.
  • Center FVector World location (cm).
  • Extent FVector Half-size in each axis (cm).
  • LineColor FLinearColor RGBA 0..1.
  • Rotation FRotator Pitch/Yaw/Roll (deg).
  • Duration float Seconds to persist (0 = one frame).
  • Thickness float Line thickness.
KismetSystemLibrary.hpp:66

RailVehicle.hpp

Header notes
RailVehicle / RailVehicleDefinition — the higher-level rail-vehicle objects.
From the spike: RailVehicle has comparatively few (and less relevant)
functions, RailVehicleDefinition holds top-level properties (destination,
driver, etc.). The concrete link between these and RailVehicleComponent was
not established in Live View — record findings here as they are confirmed.

Cataloged for the docs; not wired into TSM's train sync yet.

RailVehicle::OnSpawn

candidate

Called when a rail vehicle is spawned into the world; a hook point for reacting to (or driving) TrainSpawner results.

RailVehicle.hpp:15

RailVehicle::SeatCharacterMap

candidate

(Property) map of seats -> occupying characters. Candidate for resolving which vehicle the local player is driving/seated in.

RailVehicle.hpp:21

RailVehicle::UsesSimpleControls

works

Does this loco ship as a SIMPLE-CONTROLS unit (drive it with a throttle and nothing else) or a full-startup one (battery, pantograph, VCB, key, reverser... before it will take power)? Reads the loco's `URailVehicleDefinition::bUsesSimpleControls` (+0x028C) — a CONTENT DESCRIPTOR, not a runtime mode, so there is no toggling it on a spawned consist.

Returns
bool ReturnValue

read by `train move simple audit`. Class 805 answers FALSE on all five cars (2026-08-07) — which is what ended the attempt to drive puppets from the cab. See Natives/VirtualHID.hpp.

RailVehicle.hpp:27

RailVehicleComponent.hpp

Header notes
RailVehicleComponent — the component that carries the rail-vehicle behaviour
(velocity, consist links). This is the object TSM reads to sync a player-driven
train.

TSW6 architecture (confirmed in-game 2026-07-13): each rail vehicle is a pair —
a visual actor `RVV_<...>_C` (what the driver pawn is attached to) and a
model/physics actor `RVM_<...>_C`. The RailVehicleComponent (instance name
`RailVehiclePhysicsComponent0`) is owned by the RVM actor, not the RVV the pawn
attaches to. TSM bridges RVV -> RVM via the actor's GetOwner/attach chain (see
Game/Train.cpp `rail_component_for`).

RailVehicleComponent::GetForwardsVelocity

confirmed

Signed forward speed of this vehicle along the track.

Returns
float speed_ms Metres per second; positive = travelling forward.

(verified in-game 2026-07-13: returns m/s)

RailVehicleComponent.hpp:18

RailVehicleComponent::GetVelocity

candidate

Full 3D velocity vector of this vehicle.

Returns
FVector ReturnValue Velocity (cm/s) in world space.
RailVehicleComponent.hpp:28

RailVehicleComponent::GetAngularVelocity

candidate

Angular velocity of this vehicle.

Returns
FVector ReturnValue Angular velocity (deg/s or rad/s — verify).
RailVehicleComponent.hpp:38

RailVehicleComponent::GetPosition

broken

DO NOT USE. Whatever this returns, it is not a readable world position at the return-property offset.

Returns
FVector ReturnValue Garbage.

calibrated against a normally-driven train 2026-08-05 and FAILED. The player drove a spawned consist 600 m under its own power; GetPosition reported (-0,-14,-3), i.e. the world origin. Other reads on the same session returned 7e29 and 2.4e11. Its y component was -14 on three unrelated consists while x/z varied wildly, so the return is not a plain FVector here. This native produced a confident WRONG root-cause diagnosis of the puppet 1 km cull (see the tsm-puppet-sim-anchor memory) — do not build another measurement on it without calibrating first.

RailVehicleComponent.hpp:48

RailVehicleComponent::GetNextRailVehicle

candidate

The next vehicle in the consist from this one (walk to enumerate the formation one link at a time).

Returns
RailVehicleComponent* ReturnValue Next vehicle, or null at the end.

(in-game 2026-07-13 it returned null on the driven car — either not the right getter or needs a different start; the full-consist API is still to be identified on the component)

RailVehicleComponent.hpp:67

RailVehicleComponent::GetFormation

confirmed

The whole consist this vehicle belongs to (loco + wagons), in order — every car regardless of which cab you're in. This is TSM's consist enumerator (GetNextRailVehicle yields nothing from an end cab). Read via Game/Train.cpp `call_object_array`, which reads the TArray and DestroyValue()s it so it doesn't leak.

Returns
TArray<RailVehicleComponent*> ReturnValue All vehicles in order.

(present on the component, verified in-game 2026-07-13)

RailVehicleComponent.hpp:80

URailVehicleComponent::SetOverrideLocation

untested

Kinematically place this vehicle at a world location (candidate M2 teleport primitive). Semantics unconfirmed — may be the world-origin-shift helper, not a teleport; the T3 probe decides.

Parameters
  • FVector Location World position (cm).

(dump 2026-07-21)

RailVehicleComponent.hpp:101

URailVehicleComponent::SetOverrideSpeed

untested
Parameters
  • float Speed m/s (0 = hold in place).

(dump 2026-07-21)

RailVehicleComponent.hpp:110

URailVehicleComponent::SetSimpleEffortOrBrakeCoefficient

untested

Simple-controls drive input: the game's own physics drives the vehicle (candidate M4a). +effort accelerates; bStop brakes/holds.

Parameters
  • float EffortOrBrake [-1..1] throttle/brake coefficient.
  • bool bStop

(dump 2026-07-21)

RailVehicleComponent.hpp:116

URailVehicleComponent::IsDerailed

untested
Returns
bool ReturnValue The T3 success check after a move.

(dump 2026-07-21)

RailVehicleComponent.hpp:125

URailVehicleComponent::GetFormationLength

confirmed
Returns
float ReturnValue Whole-consist length in **METRES**, not cm.

2026-08-05 — a 5-car Class 805 returns 129, and its measured geometry is 104 m centre-to-centre plus one 26 m car = 130 m end to end. Reading it as cm made `train move walk` space the cars 25.8 CM apart and stack the whole consist inside itself. Multiply by 100 before mixing it with any other TSM length.

RailVehicleComponent.hpp:131

URailVehicleComponent::GetForwardVector

untested
Returns
FVector ReturnValue Unit forward direction in world space.

(dump 2026-07-21)

RailVehicleComponent.hpp:141

URailVehicleComponent::ApplySimulationPreset

partial

Bring the vehicle's SYSTEMS to a preset state — the game's own "prepare this train". Looked like the answer to the master key, which no amount of lever dragging will turn.

Parameters
  • ESimulationPreset Preset 0 Parked, 1 RunningStopped, 2 RunningActive
  • FName ConfigName NAME_None works

NO-OP 2026-08-07 — preset 2 moves LastAppliedPreset to RunningActive on every car, but the master key stays out and bStop stays 1, so the consist is no more drivable than before.

RailVehicleComponent.hpp:147

URailVehicleComponent::ApplyVHIDPreset

dead

Drive a NAMED SET of controls to a target over time — the driver's assistant / AI path for operating a cab. Needs a GameplayTasks component and a preset name from the vehicle's VHIDPresets array.

Parameters
  • UGameplayTasksComponent* GameplayTasksComponentRef
  • AController* ControllerRef
  • FName PresetName, float TargetInputValue, float ErrorTolerance, float MinMoveTime, float MaxMoveTime, float RateOfChange

2026-08-07 — the Class 805's 11 VHIDPresets are ALL lighting. No power, key or startup preset is shipped, so there is nothing here to drive a train with (`train move simple audit` dumps them).

RailVehicleComponent.hpp:158

URailVehicleComponent::ResetPhysics

ruled

Re-seat the sim. RULED OUT as the puppet re-anchor primitive.

Parameters
  • ESimulationPreset Preset
  • FName ConfigurationName

OUT 2026-08-05 — presets 0 and 1 changed nothing observable on a hard-set consist; **preset 2 CRASHED THE GAME**. Do not call it with a preset above 1. Preset 3 remains untested and is not worth another crash to find out.

RailVehicleComponent.hpp:171

Sandbox.hpp

Header notes
TSW6's sandbox (free-roam) spawn path, mined from the dump 2026-07-17 for SOS
phase C. The chain TSM drives (and hooks) to spawn real consists at runtime:

  UTimetableRuntimeExtensionLibrary (BP function library, module TS2Prototype):
    FindSpawnableFormations(Search)                  -> TArray<UTrainEntryDefinition*>
    FindTrainSpawnLocationNearDriverPawn(pawn, dist) -> FNetworkRibbonLocation + dir
    SpawnFormation(ctx, entry, ribbonLoc, dir)       -> void (no handle!)

  UNetworkBlueprintFunctionLibrary:
    GetTransformAtTrackLocation(ctx, loc, out FTransform) — ribbon -> world.

  ASandboxManager — the free-roam menu's state machine (Idle/SpawningTrains/
  RemovingTrains/...); StartRemovingTrain(RVComponent) is the removal probe.

FNetworkRibbonLocation (0x1C bytes: FGuid RibbonReference @0x08, float
RibbonLocation @0x18) is treated as an opaque blob — copied whole between out
params and call frames, never interpreted. EDirectionOfTravel: 0 = Forwards,
1 = Backwards (TS2Prototype_enums.hpp).

SpawnFormation returns nothing, so the spawned consist is found by a
before/after diff on live RailVehicleComponents (Game/Spawner.cpp).

UTimetableRuntimeExtensionLibrary::FindSpawnableFormations

untested

Search the loaded spawnable formations (free-roam entries). Only returns entries whose content is loaded this session.

Parameters
  • TArray<FString> Search Substring filters (empty = all).
Returns
TArray<UTrainEntryDefinition*> ReturnValue

(dump 2026-07-17)

Sandbox.hpp:32

UTimetableRuntimeExtensionLibrary::FindTrainSpawnLocationNearDriverPawn

untested

A valid on-track spawn location near the driver pawn.

Parameters
  • ADriverPawn* DriverPawn
  • float DistanceCM
  • FNetworkRibbonLocation& OutRibbonLoc (out, 0x1C)
  • EDirectionOfTravel& OutLocalSpawnDir (out, u8)
Returns
bool ReturnValue False = no valid location found.

(dump 2026-07-17)

Sandbox.hpp:40

UTimetableRuntimeExtensionLibrary::SpawnFormation

untested

Spawn a formation (consist) at a track location. Returns void — resolve the new consist via component diff. TSM also hooks this to catch the game's own free-roam menu spawns.

Parameters
  • UObject* WorldContextObject
  • UTrainEntryDefinition* TrainEntry
  • FNetworkRibbonLocation RibbonLoc (0x1C)
  • EDirectionOfTravel LocalSpawnDir (u8)

(dump 2026-07-17)

Sandbox.hpp:51

StartSettingPathForRV

untested
Parameters
  • URailVehicleComponent* RailVehicleComponent

(dump 2026-08-05)

Sandbox.hpp:84

AddWaypointsForRVPath

untested
Parameters
  • URailVehicleComponent* RailVehicle
  • FNetworkRibbonLocation SelectedRibbonLocation

same param pair as SetDestinationForRV; a path may need waypoints before a destination will take.

Sandbox.hpp:87

RemoveCurrentPathForRV

untested
Parameters
  • URailVehicleComponent* RailVehicleComponent

the "undo" if a path gets stuck.

Sandbox.hpp:92

GetState

undocumented
Returns
ESandboxManagerState (u8): 0 Idle, 1 SpawningTrains, 2 RemovingTrains, 3 SettingPath, 4 RemovingPath, 5 AddingWaypointToPath.
Sandbox.hpp:99

UNetworkBlueprintFunctionLibrary::GetTransformAtTrackLocation

untested

World transform of a ribbon location. FTransform (UE4.26 x64): FQuat @0x00, FVector Translation @0x10, Scale @0x20 — TSM reads the translation only.

Returns
bool ReturnValue False = invalid location.

(dump 2026-07-17)

Sandbox.hpp:124

UNetworkBlueprintFunctionLibrary::IsTrackLocationValid

candidate
Sandbox.hpp:132

UNetworkBlueprintFunctionLibrary::AdvanceTrackLocation

untested

Walk along the ribbon network from a location by a distance, following ribbon connections. Used as a spawn preflight: if the consist's length can't be walked off the spawn point, the track runs out / hits a null ribbon and SpawnFormation would access-violate reading UNetworkRibbon::RibbonWidth (0x154).

Parameters
  • UObject* WorldContextObject
  • FNetworkRibbonLocation InLocation (0x1C)
  • float InDistanceCM
  • EDirectionOfTravel InDir (u8)
  • FNetworkRibbonLocation& OutLocation (out)
  • bool& OutSuccess (out)
  • float& OutDistanceRemaining (out; >0 = ran off)

(dump 2026-07-17)

Sandbox.hpp:136

ASandboxManager::GetState

candidate

ESandboxManagerState: 0 Idle, 1 SpawningTrains, 2 RemovingTrains, 3 SettingPath, 4 RemovingPath, 5 AddingWaypoint. Attribution signal: the menu spawns while state == 1.

Sandbox.hpp:157

ASandboxManager::StartRemovingTrain

untested

The menu's train-removal entry point; candidate despawn path for TSM-spawned consists.

Parameters
  • URailVehicleComponent* RemoveTrainCandidate

(dump 2026-07-17)

Sandbox.hpp:164

ASandboxManager::IsRibbonLocationValidForSpawn

untested

The game's OWN spawn-room validator — the check the free-roam menu runs (which is why the menu never crashes). Given a ribbon location + direction, returns whether a train can spawn there without laying a car off the network. The reliable replacement for the AdvanceTrackLocation heuristic IF it doesn't fatal-check when called outside the menu flow (a prior agent recorded that it might — probe with `spawn valid` first).

Parameters
  • FNetworkRibbonLocation InRibbonLocation (0x1C)
  • EDirectionOfTravel InLocalDirection (u8)
Returns
bool ReturnValue

(dump 2026-07-21) — re-probe post-priming (TPM T4)

Sandbox.hpp:171

ASandboxManager::SetTrainEntry

untested

Set the manager's CURRENT train entry — the menu's first step. Takes the full FCachedTrainEntry (0x1B8); TSM replays one captured from the menu pick so IsThereRoomForCurrentTrainEntry becomes a valid gate.

Parameters
  • FCachedTrainEntry NewTrainEntry (0x1B8)
Returns
bool ReturnValue

(dump 2026-07-21)

Sandbox.hpp:185

ASandboxManager::SetSpawningState

untested

Enter the SpawningTrains state (GetState -> 1). THE setup the free-roam menu does before spawning — it makes the spawn subsystem consistent (creates/enables the SpawnPlaceholder). Driving SpawnFormation/room-checks while Idle instead is what crashes intermittently (2026-07-21). Pair with SetIdleState.

Returns
bool ReturnValue

(dump 2026-07-21)

Sandbox.hpp:195

ASandboxManager::SetIdleState

untested

Return to Idle (teardown after a spawn). No params.

(dump 2026-07-21)

Sandbox.hpp:205

ASandboxManager::IsThereRoomForCurrentTrainEntry

untested

Room check for the manager's CURRENT entry (set via the placeholder/SetTrainEntry) at the current placement.

Returns
bool ReturnValue

(dump 2026-07-21)

Sandbox.hpp:210

ASandboxManager::IsThereRoomForTrainEntry

untested

Room check for a specific entry at the manager's current spawn location. More menu-state-dependent than the ribbon-location form (uses internal state), so likelier to fatal-check cold.

Parameters
  • UTrainEntryDefinition* TrainEntry
Returns
bool ReturnValue

(dump 2026-07-21)

Sandbox.hpp:217

ASandboxManager::SetDestinationForRV

untested

The free-roam "drive to destination" path (candidate M4b): the game's AI drives the consist to a ribbon location for us.

Parameters
  • URailVehicleComponent* RailVehicle
  • FNetworkRibbonLocation SelectedRibbonLocation (0x1C)

(dump 2026-07-21)

Sandbox.hpp:226

ASandboxManager::AddWaypointsForRVPath

untested
Parameters
  • URailVehicleComponent* RailVehicle
  • FNetworkRibbonLocation SelectedRibbonLocation (0x1C)

(dump 2026-07-21)

Sandbox.hpp:234

ASandboxSpawnPlaceholder::SetTrainEntry

untested

Set the placeholder's entry — takes a PLAIN UTrainEntryDefinition (no FCachedTrainEntry needed, unlike the manager's SetTrainEntry).

Parameters
  • UTrainEntryDefinition* NewTrainEntry

(dump 2026-07-21)

Sandbox.hpp:250

ASandboxSpawnPlaceholder::RecalculateVehiclePlacementsTransform

untested

Lay out the per-car placements for the entry at a ribbon location — the menu's setup step before the room check/spawn.

Parameters
  • FNetworkRibbonLocation InRibbonLocation (0x1C)
  • EDirectionOfTravel InLocalDirection (u8)

(dump 2026-07-21)

Sandbox.hpp:257

ASandboxSpawnPlaceholder::Enable

untested

Enable the placeholder (the menu enables it while positioning).

(dump 2026-07-21)

Sandbox.hpp:265

Timetable.hpp

Header notes
TS2TimetableRouteMapWidget — the timetable/route map UI widget. From the
spike these route functions are the current lead on identifying the loaded
route (for the server's `map` field and, later, refusing cross-route joins).
Cataloged for the docs; route identity is not wired into TSM yet.

TS2TimetableRouteMapWidget::SetRouteMapPointsInteractable

candidate
Timetable.hpp:24

Track.hpp

ATrackNetworkActor (AActor)

candidate

Per-tile owner of a slice of the track network. FindAllOf by this class name; skip Default__ CDOs.

(dump 2026-07-21)

Track.hpp:23

UPhysicsFunctionLibrary::GetRibbonUnderWheel

untested
Parameters
  • UObject* WorldContextObject
  • FSimulationComponentNodeReference RefNode {FName Component, FName Node}
  • float& T (out; ribbon location)
  • EDirectionOfTravel& Direction (out; u8)
Returns
UNetworkRibbon* ReturnValue

(dump 2026-07-21) — RefNode source unresolved

Track.hpp:89

TrainSpawner.hpp

ATrainSpawner (AActor)

undocumented

Self-contained consist spawner. FindAllOf / find_class_by_name by this class name; spawn a fresh instance (no pre-placed one exists in free-roam).

TrainSpawner.hpp:44

ATrainSpawner::SpawnConsist (no params)

probing

Spawn the consist for TrainDefinition at this actor's transform.

(0x154 on off-network placement; retry with a Track-validated transform)

TrainSpawner.hpp:60

ATrainSpawner::DespawnConsist (no params)

untested

Despawn the consist this spawner made — candidate clean despawn primitive (SandboxManager::StartRemovingTrain is still unverified).

TrainSpawner.hpp:65

VirtualHID.hpp

UVirtualHIDComponent::SetNormalisedInputValue

confirmed

Drive this control to `Value`, a [0..1] FRACTION OF THAT LEVER'S OWN RANGE — not a raw input value. The two differ per control: Reverser range [0..1] -> set 0.67 gives in=+0.67 (1:1) PowerHandle range [-1..+1] -> set 0.25 gives in=-0.50 (in = 2v-1) Measured 2026-08-07, reproducible. So on a combined power/brake handle, v=0.5 is NEUTRAL, v<0.5 is brake and v>0.5 is power; the player's own driving position of in=+0.25 is v=0.625, and full power (in=+1.00) is v=1.0. Asking for "0.25 power" gets you half brake, which is exactly the trap we fell into.

Parameters
  • float Value

working 2026-08-07 — MasterKey, Reverser and PowerHandle all set and hold. Match the control name EXACTLY: a substring match on "PowerHandle" also hits "PowerHandle_BrakeHold" and pins the brake on with the same command that asks for power.

VirtualHID.hpp:37

UVirtualHIDComponent::SetPositionDeltaAnalogue

works

THE PLAYER INPUT PATH. Moves the lever by DeltaMovement on behalf of a Controller, which is what a human hand does — so it runs the whole bIsChanging / CurrentChangingController / OnBeginChanging -> InputValueChanged -> OnEndChanging cycle that actually pushes the new position into the simulation.

Parameters
  • AController* Controller (the local PlayerController)
  • float DeltaMovement

as an input path, 2026-08-07 — but only while a controller is registered as holding the lever: forge CurrentChangingController + bIsChanging, apply deltas, then let go. Notched levers (Reverser, MasterKey) snap back from a step too small to clear their detent, so escalate the step when a lever stops responding. Prefer this over SetNormalisedInputValue, which writes CurrentInputValue while the sim never reacts and leaves even MANUAL driving braked afterwards.

VirtualHID.hpp:54

UVirtualHIDComponent::InputValueChanged

untested

The notification half. If a raw set has to be told to propagate, this is the call that does it.

Parameters
  • float OldValue, float NewValue
VirtualHID.hpp:71