Knowledge from the fieldRedM

Mission trains suppress BOTH enter and exit vehicle controls (player gets stuck in/out of seat); the game also re-seats an AI conductor on empty seats — script enter/exit + run a seat guard

learning:41

Mission trains suppress BOTH enter and exit vehicle controls (player gets stuck in/out of seat); the game also re-seats an AI conductor on empty seats — script enter/exit + run a seat guard

Context

You let a player drive a _CREATE_MISSION_TRAIN (0xC239DBD9A57D2A71). You put them in the driver seat with TaskWarpPedIntoVehicle(ped, train, -1) — and driving works, full control. But then the player cannot exit (pressing the normal exit-vehicle key does nothing), and once out (by any means) they cannot re-enter (no enter prompt appears). Worse: an AI conductor NPC keeps appearing in the driver seat whenever it's empty, showing a "ghost" driver and blocking the player.

The traps (verified in-game, build 1491)

  1. The mission-train task system suppresses both the normal ENTER and EXIT controls. TaskWarpPedIntoVehicle is the only thing that reliably seats the player WITH control; the natural walk-up-enter and the press-to-exit are both eaten.
  2. An active mission train re-seats an AI conductor into seat -1 the moment it's free (especially while moving / after a desync). Deleting it once isn't enough — it comes back.
  3. Door locks are NOT the cause (lock status reads unlocked). It's purely control-suppression + AI re-seating.

The fix (verified — full enter/exit cycle works, control preserved)

Script all three:

-- EXIT: drive the leave-task yourself (4160 = throw self out, bypasses the
-- moving-vehicle exit block; for a stopped train the ped just steps out).
TaskLeaveVehicle(ped, train, 4160)

-- ENTER: on foot near the train, evict any squatting NPC then WARP in.
-- Warp is the only method that reliably preserves CONTROL — natural/target
-- entry can seat you "ownerless" => enterable-but-uncontrollable.
local cur = GetPedInVehicleSeat(train, -1)
if cur ~= 0 and cur ~= PlayerPedId() and not IsPedAPlayer(cur) then
  SetEntityAsMissionEntity(cur, true, true); DeletePed(cur)
end
TaskWarpPedIntoVehicle(ped, train, -1)

-- GUARD: a loop that continuously evicts any non-player ped from seat -1, so
-- the AI conductor can't squat the seat (blocks entry + ghost driver).
CreateThread(function()
  while true do
    local t = getActiveTrain()
    if t and DoesEntityExist(t) then
      local s = GetPedInVehicleSeat(t, -1)
      if s ~= 0 and s ~= PlayerPedId() and not IsPedAPlayer(s) then
        SetEntityAsMissionEntity(s, true, true); DeletePed(s)
      end
    end
    Wait(500)
  end
end)

Bind the enter/exit to a custom key (e.g. via jo_libs jo.rawKeys.listen("F", ...) — reliable keyboard scancode; RedM control IDs for this are flaky). Make it contextual: leave if seated, enter if on foot within range. A driverless mission train still moves on SetTrainCruiseSpeed (so autopilot keeps driving while the seat is empty — see related finding).

Linked natives

  • _CREATE_MISSION_TRAIN (0xC239DBD9A57D2A71)

Tags: trains, vehicles, mission-train, enter, exit, conductor, railroad
Category: natives
Source: scandi-railroad-poc
Created: 2026-05-22T21:42:03.217Z

Back to documentation