Open Road MP

Players

The player object, finding players, and changing money, vehicles, position and more.

The player object

Events hand you a Player. It always shows the latest state the server knows:

Field
idnumber, unique while the player is online
nameplayer name
accountIdthe player's Open Road MP account, e.g. "oprmp:KXQTRB-4821" - confirmed by the master server, the same under any name and on every server
teamthe player's role in the Open Road MP team ("admin", "developer", "moderator", "support"), else null
language"de" or "en": the language of the player's Open Road MP UI - word your own messages in it
moneybank balance in euro, updated every second (null for players with an older client)
companythe player's company in your gamemode, or null
position{ x, y, z } in metres, null until the player is in the world
headingdriving direction in degrees, 0 = north
speedkm/h, negative when reversing
truckbrand and model, e.g. "DAF XG+"
damagewear of engine, transmission, cabin and chassis, 0 to 1
vehiclegauges and switches of the truck - see below
jobthe active job or null (see Jobs)
radiowhat the player listens to, null while the radio is off
ghosttrue after mp.players.setGhost(player, true)
visiblefalse after mp.players.setVisible(player, false)

Position and speed are updated every second, the rest within a few seconds. The fields are read-only - change things with the functions below.

mp.commands.add("where", "shows your position", (player) => {
  const p = player.position
  if (!p) return
  mp.chat.send(player, `x ${p.x.toFixed(0)}, z ${p.z.toFixed(0)}, ${player.speed.toFixed(0)} km/h`)
})

Finding players

mp.players.all()     // everyone online
mp.players.get(3)    // by id, undefined if not online

Every function that takes a player also accepts the id instead of the object.

Your own data per player

Keep it in a Map by id and clean up when the player leaves:

const deliveries = new Map<number, number>()

mp.events.on("jobDelivered", (player) => {
  deliveries.set(player.id, (deliveries.get(player.id) ?? 0) + 1)
})

mp.events.on("playerLeave", (player) => {
  deliveries.delete(player.id)
})

Gauges and switches

player.vehicle is what the dashboard shows, updated every second:

Field
engineOnengine running
gear> 0 forward, < 0 reverse, 0 neutral
rpmengine speed
fuel / fuelCapacitylitres in the tank / tank size
fuelRangekm the fuel lasts at the average consumption
odometerkm on the clock
cruiseControlset speed in km/h, 0 = off
speedLimitspeed limit of the road in km/h, 0 = none
parkingBrakeparking brake on
trailerAttached / cargoDamagea trailer on the hook / damage of its cargo, 0 to 1
lights{ low, high, parking, beacon, hazard }
wiperswipers on
routethe navigation's route { distanceKm, minutes }, or null
mp.commands.add("dash", "shows your dashboard", (player) => {
  const v = player.vehicle
  mp.chat.send(player, `gear ${v.gear}, ${v.rpm} rpm, ${v.fuel?.toFixed(0)} l, ${v.odometer} km`)
})

// a speed check with the road's limit
setInterval(() => {
  for (const p of mp.players.all()) {
    const limit = p.vehicle.speedLimit
    if (limit && p.speed > limit + 20) mp.ui.notify(p, { title: `Slow down: ${limit} km/h`, kind: "warning" })
  }
}, 5000)

All fields but engineOn, trailerAttached, lights and wipers are missing (undefined) for players whose game runs an older Open Road MP version. Changes come as events: engineStart, trailerAttach, playerRefuel ...

Money and progress

mp.players.setMoney(player, 25000)      // bank balance in euro
mp.players.giveMoney(player, 500)       // + 500 € (negative: takes money, never below 0)
mp.players.setExperience(player, 50000) // experience points
mp.players.setLevel(player, 12.5)       // level 12, half way to 13
mp.players.setExploration(player, 100)  // whole map explored (percent)

Truck and job

mp.players.repair(player)       // truck, trailer and cargo like new
mp.players.repairCargo(player)  // only the cargo
mp.players.cancelJob(player)    // cancels the active job
mp.players.setFuel(player, 1)   // full tank; 0.25 = a quarter
mp.players.setFatigue(player, 0) // fully rested (minutes driven without rest)

Cargo without a job

giveCargo hands the player a trailer loaded with a cargo - for transports of your own gamemode:

mp.players.giveCargo(player, "apples")      // the game's usual amount
mp.players.giveCargo(player, "apples", 20)  // 20 units

Cargo ids are those of mp.world.cargo().

Police

mp.players.fine(player, "speeding", 500)  // fined by the game's police, 500 €
mp.players.fine(player, "red_signal")     // the game's own amount

The fine comes at once, with the game's police message - also without a police car nearby and when the server's fines rule is off.

The offence names are those of playerFined; playerFined fires as for any fine.

Changing the vehicle

setVehicle replaces the player's truck. Names are the game's model names, or a dealer variant after a /:

mp.players.setVehicle(player, "scania_s_2016")
mp.players.setVehicle(player, "scania_s_2016/scania_s2016_8x4_770")

mp.vehicles.trucks() lists every truck of the game with name, brand, model, axles and engine - your editor also completes the names.

Players who press Drive without a vehicle of their own get the server's fallback vehicle (fallback_vehicle in server.cfg). Per player: mp.players.setFallbackVehicle(player, "volvo_fh16_2012"), or null for the game's "no vehicle" message.

Licence plate

mp.players.setLicensePlate(player, "OR MP 42")              // German design
mp.players.setLicensePlate(player, "AB 123 CD", "france")   // design of another country

1 to 12 characters of A-Z, 0-9, space, - and .. Truck and trailers get it, and all other players see it.

Position and time

// 20 m behind another player, facing the same way
const rad = (target.heading * Math.PI) / 180
mp.players.teleport(player, {
  x: target.position.x + Math.sin(rad) * 20,
  y: target.position.y + 1,
  z: target.position.z + Math.cos(rad) * 20,
}, target.heading)

// time of day (the game's clock only runs forward: it jumps to the next 6:30)
mp.players.setTime(player, 6, 30)

teleport needs a height (y) - a position on the road. Without one, use a depot of the game: the truck is put at the company's entrance point, facing into the yard.

mp.players.teleportToCompany(player, "tradeaux", "dusseldorf")  // ids as in mp.world.companies()
mp.players.teleportToCity(player, "berlin")                     // a depot in Berlin

Ghosts and hidden players

mp.players.setGhost(player, true)     // drives through everyone, everyone through them
mp.players.setVisible(player, false)  // the others no longer see this player at all
  • A ghost collides with no one - like in a safe zone, but everywhere. Their HUD shows "Ghost mode" at the top. Good for AFK players, newcomers, or the losers of a race who should not block the others.
  • A hidden player disappears for everyone else: no truck, no name, not in the player list. They still see the others and keep playing - for admins watching, or events that only some players should see. setVisible(player, true) brings them back.

Messages and kicking

mp.chat.send(player, "Only you see this")
mp.players.sendCompanyMessage(player, "Welcome to the company!")  // the HUD's company news line
mp.players.kick(player, "Please read the rules")

For a notice at the top of the HUD, see mp.ui.notify; for messages in a player's name, mp.chat.sendAs.

Mails

A mail lands in the game's own mail screen (desktop menu Mail), with the game's "new mail" mark - good for welcome letters, rules or rewards:

mp.events.on("playerJoin", (player) => {
  mp.players.sendMail(player, {
    from: "Dispatch",
    subject: "Welcome!",
    body: `Hello ${player.name},\n\nyour first job is waiting in Berlin.\n\nSafe travels!`,
  })
})

from defaults to the server's name; a mail needs a subject or a body. The text is plain: a line break starts a new line, < and > are shown as ( and ). Mails live until the player leaves the server - they are not saved. The game's own mails (bank, dealers, ...) never arrive on a server, and every player starts with an empty mail screen.

On this page