teleports
Last updated on
Operator-placed teleport pads to places players cannot walk to, optionally locked to a job, with every trip checked and performed by the server.
Lets operators place pads that move a player to another spot: a rooftop with no stair, a mezzanine, an interior the game only reaches by cutscene. The player sees a marker, stands on it and presses E; the prompt strip names the destination. A pad can be one-way or two-way, and its outbound leg can be locked to jobs, grades and duty. The client only sends a pad key and a direction; the server re-checks the job gate, the player's own position and bucket, then moves the player with the platform's teleport. Use it to open up unreachable places or give a job its own entrance.
| Side | both |
| Requires | character (hard) |
| Optional | prompts (the strip row), downed (refuses while down) |
| Contract | teleports v1 — server, client |
| Config | config/teleports.lua (shared) |
| Data | none |
No pad ships enabled
The three entries in POINTS are examples at coordinate 0,0,0 with enabled = false. A server has no teleports until an operator adds real ones. Read positions and heading with /opx.admin.self.pos.
Commands
| Command | Access | Arguments | Effect |
|---|---|---|---|
/opx.teleports.where | ACL command.opx.teleports.where | [key] | Prints config problems, then one line per pad: label, bucket, one/two-way, both ends, job gate, and how many trips were taken, refused and lost. Ends with whether the platform teleport native exists. Name set by COMMAND. |
Configuration
config/teleports.lua sets OPX.Config.MODULES.teleports.
| Key | Default | Effect |
|---|---|---|
enabled | true | false switches the module off. |
USE_RADIUS | 2.0 | Metres across the ground from an entrance within which it may be used. The server allows REACH_SLACK (1 m) more. |
USE_HEIGHT | 2.5 | Metres above or below the entrance that still count, so a player falling past is not on it. |
MARKER | { shape = 'cylinder', style = 'interaction', RADIUS = 1.2 } | Marker look. Shapes ring, cylinder; styles interaction, objective, spawn, danger; radius 0.1..50. |
LOCKED_STYLE | 'danger' | Marker style for a pad the player may not use (with DENIED = 'shown'). |
DENIED | 'shown' | shown draws locked pads in LOCKED_STYLE; hidden draws nothing for them. The server refuses either way. |
MAX_DISTANCE | 120.0 | Metres beyond which a marker is not drawn, 1..500. |
GROUND_OFFSET | 0.06 | Metres the marker is lifted off the declared Z, 0..2. |
POLL_MS | 15000 | How often the client re-asks for the list (carries duty and job changes). |
SCAN_MS | 500 | Client marker and prompt pass. |
JOB_MAX_AGE_MS | 60000 | Job snapshot age past which gated pads close. |
MEMBERSHIP | 'primary' | primary or any, as in elevators. |
FADE_MS | 400 | Screen fade around the move. Tunable TP_FADE_MS. |
SETTLE_MS | 12000 | How long the platform waits for the body to stand at the destination, 1000..30000. Tunable TP_SETTLE_MS. |
REQUEST_WINDOW_MS | 10000 | Rate window. Tunable TP_REQUEST_WINDOW_MS. |
REQUESTS_PER_WINDOW | 6 | Trips asked per player per window, as every other place (was 4 before PR #95). Tunable TP_REQUESTS_PER_WINDOW. |
KEY | { ID = 'opx.teleports.use', NAME = 'teleports.key.use', DEFAULT = 'E' } | The use key. Players rebind it in the pause menu under ID. DEFAULT = false registers none. |
COMMAND | 'opx.teleports.where' | Diagnostic command name; false registers none. |
POINTS | 3 disabled examples | Pad key → definition. See below. |
example_secure = {
enabled = false,
LABEL = 'EXAMPLE: secure floor',
BUCKET = 0,
ENTRY = { LABEL = 'Lobby', X = 0.0, Y = 0.0, Z = 0.0, HEADING = 0.0 },
EXIT = { LABEL = 'Secure floor', X = 0.0, Y = 0.0, Z = 60.0, HEADING = 270.0 },
RETURN = true,
DISMOUNT = false,
JOBS = { arasaka = 2 },
ON_DUTY = true,
REASON = 'Arasaka Counterintel, on duty',
},- key: pad name, 1..48 characters.
enabled:falseskips the pad.LABEL: pad name for the diagnostic, max 64.BUCKET: routing bucket, default0. Both ends share it.ENTRY:{ LABEL, X, Y, Z, HEADING }— where the player stands.EXIT:{ LABEL, X, Y, Z, HEADING }— where they land and which way they face.RETURN:truemakes the exit an entrance back toENTRY.DISMOUNT:truepulls the player out of a vehicle instead of refusing. The vehicle stays behind.JOBS,ON_DUTY,REASON: the job gate, outbound leg only.- The prompt shows the label of the end the player is going to. The way back (
RETURN) is never gated, so nobody is stranded after losing a job.
The job gate
Same format as elevators; see OPX.JobGate.Evaluate.
| Field | Meaning |
|---|---|
JOBS | { [jobName] = minimumGradeLevel }. Any one listed job at its grade passes. No JOBS = public. |
ON_DUTY | true also requires that job to be the worked job and on duty. |
REASON | Text shown to a refused player, max 64. Never translated. |
Refusal codes
| Code | Meaning | Player sees |
|---|---|---|
rate_limited | Too many requests. | error.tooFast |
in_flight | A trip is already running (lock released after 45 s). A trip that fails is always answered, and the client's own latch also opens after 45 s. | teleports.inFlight |
no_such_teleport | Unknown key, or back on a one-way pad. | teleports.noSuchTeleport |
no_character, job_stale, job_required, grade_too_low, off_duty | The job gate refused. | REASON, else teleports.locked |
downed | The player is down. | teleports.downed |
no_position, wrong_bucket, too_far | Not standing on the entrance. | teleports.noPosition, teleports.tooFar |
unavailable, no_promise | Open77.players.teleport is missing on this host. | teleports.unavailable |
player_in_vehicle, dismount_failed, player_not_alive, player_not_ready, invalid_position | Refused by the platform teleport. | teleports.inVehicle, teleports.notAlive, teleports.notReady, teleports.badDestination |
settle_timeout | The body never stood at the exit in SETTLE_MS. Usually no floor at the exit. | teleports.neverArrived |