RATScript v2 / Complete Reference

Scripting Reference

The current RAT 5 event language: syntax, values, scopes, reusable functions, telnet capture, runtime limits, and built-ins.

Start here

RATScript is a small language for answering three questions: what happened, should RAT react, and what should RAT do. You can begin by editing a template; you do not need to memorize the language or the function list.

Read a value

Names beginning with $, such as $player.name, are facts supplied by the current event.

Make a decision

Use if ... then to run actions only when a condition is true.

Perform an action

Functions such as log(...), discord_send(...), and gs_broadcast(...) do the work.

# This script runs when a new player joins.
log(format("Welcome, {0}!", $player.name))
Always preview firstSome functions send real Discord messages, run telnet commands, move players, or control the game server. Preview and read the function description before enabling a script.

Contents

  1. Start here
  2. Execution model and source layout
  3. Statements and control flow
  4. Values, operators, and conditions
  5. Variables, objects, and scopes
  6. Arrays, indexing, and FOR EACH
  7. Global runtime variables
  8. Event variables
  9. String interpolation
  10. Persistent shared state
  11. Reusable functions
  12. Telnet commands and capture
  13. Built-in functions
  14. Limits and failure behavior
  15. Complete examples

1. Execution model and source layout

rat5.v2 is the supported event-script version. RAT selects enabled definitions for an event, builds read-only event and runtime values, validates the script, and executes statements from top to bottom. Scripts can calculate values, branch, update definition-local persistent state, call reusable functions, and perform controlled side effects.

  1. Event and runtime values are fixed for the logical execution.
  2. Validation rejects unknown names, invalid object paths, malformed blocks, and incorrect argument counts.
  3. Only the first matching branch of an if block executes.
  4. wait(...) suspends this execution without blocking other scripts.
  5. Successful global.* mutations are persisted for this definition.

Source layout

# A minimal chat command
set local.message = lower(trim($chat_content))
if local.message == "!hello" then
  set global.hello_count = coalesce(global.hello_count, 0) + 1
  gs_broadcast(format("Hello {0}! Use #{1}", $player.name, global.hello_count), "say")
end

2. Statements and control flow

set and unset

set assigns a local or persistent global value. Object paths are created as needed. unset removes the selected local or global path and its descendants.

set local.normalized = lower(trim($chat_content))
set global.last_player = $player.name
unset global.last_error

if, else if, else, and end

if $players_online == 0 then
  log("Server is empty")
else if $players_online < $players_max then
  log("Slots are available")
else
  log("Server is full")
end

Calls, actions, and return

Value-returning calls may appear inside expressions. Action calls are complete statements. return is valid inside reusable functions and may return a value or stop with no value.

FOR EACH ... IN ... END

FOR EACH repeats a block once for every item in an array or compatible collection. The item is placed in a local variable for the duration of each pass. Start with the arrays and loops guide before using nested loops.

for each local.player in $players
  log(local.player.name)
end

wait(milliseconds)

wait suspends the current logical execution and resumes from the following statement. Its limits and restart behavior are documented below.

3. Values, operators, and conditions

RATScript values are null, strings, numbers, booleans, objects, and arrays. Function results and variables retain their type. Strings can interpolate scalar values, but arrays must be indexed, joined, or processed with FOR EACH.

PrecedenceOperatorsPurpose
1()Grouping and function calls
2not, unary -Boolean negation and numeric negation
3*, /, %Multiplication, division, remainder
4+, -Addition, concatenation, subtraction
5<, <=, >, >=Numeric or compatible ordered comparison
6==, !=Equality and inequality
7andShort-circuit conjunction
8orShort-circuit disjunction

null, false, numeric zero, an empty string, and an empty array are falsey; other values are truthy. Arrays and objects support equality checks. Prefer explicit comparisons and exists(...) when optional data matters.

4. Variables, objects, and scopes

FormLifetimeWritableUse
$name, $object.field, $array[index]Current executionNoEvent-specific and runtime values supplied by RAT.
local.name, local.items[index]Current call frameYesTemporary calculations, objects, and native arrays.
global.namePersistent per event definitionScalars onlyPersistent strings, numbers, booleans, and null values. Objects and arrays must stay local.
Reusable-function parameter nameCurrent function callNoArguments declared by function name(parameter).

Objects use dotted paths, for example $player.position.x. Arrays use brackets, and access can be chained: $players[0].position.x or local.groups[0].players[1].name. Missing optional properties and out-of-range reads evaluate to null. Use exists(...) before relying on optional data.

5. Arrays, indexing, and FOR EACH

An array is an ordered list of values. Use arrays when the same action should be applied to several names, numbers, players, attachments, or other items. Array positions start at zero, so the first item is at position [0].

Create and read arrays

set local.names = ["Alice", "Bob", "Charlie"]
set local.first = local.names[0]
set local.chosen = local.names[local.index]
set local.matrix = [[1, 2], [3, 4]]
set local.value = local.matrix[1][0]

Array items may be strings, numbers, booleans, null, objects, other arrays, or expressions. Empty arrays are written as []. Brackets can be followed by more brackets or object properties, such as $players[0].position.x.

Change a local array

set local.names[1] = "Robert"
set local.names = append(local.names, "Charlie")

Indexed assignment works only through a mutable local.* native array. Replacing an existing item does not change other copies of the array. Assignment cannot grow an array; use append(...), which returns a new array.

Missing positionsReading beyond the end of an array returns null. Writing beyond the end, or using a negative, fractional, or nonnumeric index, produces a runtime error.

Repeat work with FOR EACH

for each local.player in $players
  log(format("{0} is level {1}", local.player.name, local.player.level))
end

The iterator must be a simple local.* name. RAT evaluates the collection once when the loop starts, then runs the body once per item in order. An empty collection runs zero times and leaves the iterator as null; after a nonempty loop, the iterator contains the final item.

Loops may be nested, may call reusable functions, and may contain wait(...). A wait resumes at the same item. break and continue are not currently part of RATScript.

Built-in and compatible collections

CollectionHow to use itNotes
$players$players[0] or FOR EACHRead-only snapshot of currently online players, with the same fields as $player.
$discord.attachments$discord.attachments[0] or .item_01Both forms work; existing scripts do not need to change.
$discord.embeds$discord.embeds[0] or .item_01Read-only compatibility-indexed collection.
$discord.reactions$discord.reactions[0] or .item_01Read-only compatibility-indexed collection.

count(...), join(...), contains_value(...), bracket indexing, and FOR EACH accept native arrays and compatible indexed collections. append(...) accepts native arrays only.

Arrays are local working dataArrays and objects cannot be saved in global.*. Store a scalar result such as a count, name, number, boolean, or joined string instead.

6. Global runtime variables

These values are supplied to event scripts and scheduled tasks..

NameKindDescriptionExampleAvailability
$players
  • $players[].id
  • $players[].name
  • $players[].platform_id
  • $players[].cross_platform_id
  • $players[].steam_id
  • $players[].eos_id
  • $players[].xbl_id
  • $players[].platform_family
  • $players[].platform_user_id
  • $players[].cross_platform_family
  • $players[].cross_platform_user_id
  • $players[].entity_id
  • $players[].online
  • $players[].last_seen_at
  • $players[].ip_address
  • $players[].level
  • $players[].health
  • $players[].stamina
  • $players[].score
  • $players[].ping
  • $players[].deaths
  • $players[].zombie_kills
  • $players[].player_kills
  • $players[].total_play_time_seconds
  • $players[].credits
  • $players[].ban_active
  • $players[].ban_reason
  • $players[].ban_until
  • $players[].group.id
  • $players[].group.name
  • $players[].group.max_teleport_destinations
  • $players[].group.teleport_cooldown_seconds
  • $players[].position.x
  • $players[].position.y
  • $players[].position.z
arrayBounded snapshot of players currently online, ordered by the current player snapshot.
Read-only
rat5.v2 only
[{"name":"Trekkan","online":true}]Required
$backup
  • $backup.last nullable
  • $backup.status nullable
objectMost recent backup operation result.
rat5.v2 only
—Required
$config
  • $config.server_name nullable
  • $config.server_description nullable
  • $config.server_website_url nullable
  • $config.server_login_confirmation_text nullable
  • $config.region nullable
  • $config.language nullable
  • $config.server_port nullable
  • $config.server_visibility nullable
  • $config.server_disabled_network_protocols nullable
  • $config.server_max_world_transfer_speed_ki_bs nullable
  • $config.server_max_player_count nullable
  • $config.server_reserved_slots nullable
  • $config.server_reserved_slots_permission nullable
  • $config.server_admin_slots nullable
  • $config.server_admin_slots_permission nullable
  • $config.web_dashboard_enabled nullable
  • $config.web_dashboard_port nullable
  • $config.web_dashboard_url nullable
  • $config.enable_map_rendering nullable
  • $config.telnet_enabled nullable
  • $config.telnet_port nullable
  • $config.telnet_failed_login_limit nullable
  • $config.telnet_failed_logins_blocktime nullable
  • $config.terminal_window_enabled nullable
  • $config.admin_file_name nullable
  • $config.user_data_folder nullable
  • $config.server_allow_crossplay nullable
  • $config.eac_enabled nullable
  • $config.ignore_eos_sanctions nullable
  • $config.hide_command_execution_log nullable
  • $config.max_uncovered_map_chunks_per_player nullable
  • $config.persistent_player_profiles nullable
  • $config.max_chunk_age nullable
  • $config.save_data_limit nullable
  • $config.game_world nullable
  • $config.world_gen_seed nullable
  • $config.world_gen_size nullable
  • $config.game_name nullable
  • $config.game_mode nullable
  • $config.player_safe_zone_level nullable
  • $config.player_safe_zone_hours nullable
  • $config.build_create nullable
  • $config.bedroll_dead_zone_size nullable
  • $config.bedroll_expiry_time nullable
  • $config.allow_spawn_near_friend nullable
  • $config.camera_restriction_mode nullable
  • $config.max_spawned_zombies nullable
  • $config.max_spawned_animals nullable
  • $config.server_max_allowed_view_distance nullable
  • $config.max_queued_mesh_layers nullable
  • $config.party_shared_kill_range nullable
  • $config.player_killing_mode nullable
  • $config.land_claim_count nullable
  • $config.land_claim_size nullable
  • $config.land_claim_dead_zone nullable
  • $config.land_claim_expiry_time nullable
  • $config.land_claim_decay_mode nullable
  • $config.land_claim_online_durability_modifier nullable
  • $config.land_claim_offline_durability_modifier nullable
  • $config.land_claim_offline_delay nullable
  • $config.dynamic_mesh_enabled nullable
  • $config.dynamic_mesh_land_claim_only nullable
  • $config.dynamic_mesh_land_claim_buffer nullable
  • $config.dynamic_mesh_max_item_cache nullable
  • $config.twitch_server_permission nullable
  • $config.twitch_blood_moon_allowed nullable
  • $config.sandbox_code nullable
objectCurrent managed game server configuration. Sensitive password and token properties are never included.
rat5.v2 only
—Required
$bm
  • $bm.active nullable
  • $bm.next
  • $bm.next.day nullable
  • $bm.next.hour nullable
  • $bm.next.minute nullable
  • $bm.next.end_day nullable
  • $bm.next.end_hour nullable
  • $bm.next.end_minute nullable
  • $bm.next.days nullable
  • $bm.next.hours nullable
  • $bm.next.minutes nullable
  • $bm.next.start nullable
  • $bm.next.end nullable
objectCurrent and upcoming blood moon timing when RAT knows it.
rat5.v2 only
—Required
$game_server_namestringConfigured game server name when RAT knows it.Initial RAT5 ServerOptional
$players_onlinestringCurrent number of players online.4Required
$players_maxstringConfigured maximum concurrent players when RAT knows it.16Optional
$uptimestringElapsed time since the current game server process started.2d 4h 10mOptional
$daystringCurrent in-game day when RAT knows it.7Optional
$hourstringCurrent in-game hour when RAT knows it.21Optional
$minutestringCurrent in-game minute when RAT knows it.30Optional
$gametimestringCurrent in-game day and time in Day N, HH:MM format when RAT knows it.Day 710, 14:51Optional
$current_timestringCurrent UTC time at event execution in HH:MM:SS format.17:37:01Required
$current_datestringCurrent UTC date at event execution in YYYY-MM-DD format.2026-06-20Required
$current_datetimestringCurrent UTC datetime at event execution in RFC3339 format.2026-06-20T17:37:01ZRequired

7. Event variables

Every event supplies only the tokens declared by its catalog entry, in addition to the runtime variables above. The compact index below lists top-level names; object fields, examples, nullability, deprecations, and templates are in the event catalog.

Event typeSourceTop-level variables
chat.global_message
Chat Global Message
telnet.chat.global_message$event_type, $event_key, $occurred_at_utc, $player.name, $chat_content, $channel_name, $platform_id, $entity_id, $player, $0, $1, $N-, $N+
chat.server_message
Chat Server Message
telnet.chat.server_message$event_type, $event_key, $occurred_at_utc, $speaker_name, $chat_content, $channel_name, $0, $1, $N-, $N+
discord.message_received
Discord Message
discord.message_received$event_type, $event_key, $occurred_at_utc, $discord_guild_id, $discord_channel_id, $discord_channel_key, $discord_channel_name, $discord_message_id, $discord_message_timestamp, $discord_author_id, $discord_author_username, $discord_author_global_name, $discord_author_name, $discord_author_is_bot, $discord_mentions_everyone, $discord_mention_count, $discord_mentioned_user_ids, $discord_mentioned_role_ids, $discord_role_mention_count, $discord_attachment_count, $discord_embed_count, $discord_reaction_count, $discord_message_type, $discord_message_edited_at, $discord_message_pinned, $discord_message_tts, $discord_reply_message_id, $discord_reply_channel_id, $discord_reply_guild_id, $discord_reply_author_id, $discord_attachment_name, $discord_attachment_type, $discord_attachment_url, $discord_attachment_size, $discord_embed_title, $discord_embed_description, $discord_embed_url, $discord_embed_field_count, $discord_webhook_id, $discord_content_raw, $chat_content, $discord
discord.message_updated
Discord Message Updated
discord.message_updated$event_type, $event_key, $occurred_at_utc, $discord_guild_id, $discord_channel_id, $discord_channel_key, $discord_channel_name, $discord_message_id, $discord_message_timestamp, $discord_message_edited_at, $discord_author_id, $discord_author_name, $discord_mentioned_user_ids, $discord_mentioned_role_ids, $discord_attachment_count, $discord_embed_count, $discord_reply_message_id, $discord_content_raw, $chat_content, $discord
discord.message_deleted
Discord Message Deleted
discord.message_deleted$event_type, $event_key, $occurred_at_utc, $discord_guild_id, $discord_channel_id, $discord_channel_key, $discord_channel_name, $discord_message_id, $discord_message_timestamp, $discord_message_edited_at, $discord_author_id, $discord_author_name, $discord_mentioned_user_ids, $discord_mentioned_role_ids, $discord_attachment_count, $discord_embed_count, $discord_reply_message_id, $discord_content_raw, $chat_content, $discord
discord.reaction_added
Discord Reaction Added
discord.reaction_added$event_type, $event_key, $occurred_at_utc, $discord_guild_id, $discord_channel_id, $discord_channel_key, $discord_message_id, $discord_reaction_user_id, $discord_reaction_emoji, $discord_reaction_emoji_id
discord.reaction_removed
Discord Reaction Removed
discord.reaction_removed$event_type, $event_key, $occurred_at_utc, $discord_guild_id, $discord_channel_id, $discord_channel_key, $discord_message_id, $discord_reaction_user_id, $discord_reaction_emoji, $discord_reaction_emoji_id
player.joined
Player Joined
telnet.player.joined$event_type, $event_key, $occurred_at_utc, $player.name, $player
player.left
Player Left
telnet.player.left$event_type, $event_key, $occurred_at_utc, $player.name, $player
entity.killed
Entity Killed
telnet.entity.killed$event_type, $event_key, $occurred_at_utc, $killed_entity_name, $killed_entity_id, $killed_player_name, $killed_player_id, $killed_platform_id, $killed_cross_platform_id, $killer_name, $killer_entity_id, $killer_player_name, $killer_player_id, $killer_platform_id, $killer_cross_platform_id
server.unresponsive
Server Unresponsive
rat.telnet_health.unresponsive$event_type, $event_key, $occurred_at_utc, $failure_count, $failure_reason, $failure_detail, $last_responsive_at_utc, $first_failure_at_utc, $unresponsive_since_utc, $probe_interval_seconds, $probe_timeout_seconds
server.responsive
Server Responsive
rat.telnet_health.responsive$event_type, $event_key, $occurred_at_utc, $responsive_at_utc, $unresponsive_since_utc, $first_failure_at_utc, $outage_duration_seconds, $failed_probe_count, $last_health_failure_reason
text.match
Text Match
$event_type, $event_key, $occurred_at_utc, $raw_line
backup.started
Backup Started
internal.backup.started$event_type, $event_key, $occurred_at_utc, $backup_filename, $backup_destination, $backup_start_time, $backup_completion_time, $backup_duration, $backup_size, $backup_compression_type, $backup_error_message, $backup_retained_count
backup.completed
Backup Completed
internal.backup.completed$event_type, $event_key, $occurred_at_utc, $backup_filename, $backup_destination, $backup_start_time, $backup_completion_time, $backup_duration, $backup_size, $backup_compression_type, $backup_error_message, $backup_retained_count
backup.failed
Backup Failed
internal.backup.failed$event_type, $event_key, $occurred_at_utc, $backup_filename, $backup_destination, $backup_start_time, $backup_completion_time, $backup_duration, $backup_size, $backup_compression_type, $backup_error_message, $backup_retained_count
server.ready
Server Ready
internal.server.ready$event_type, $event_key, $occurred_at_utc, $server_state, $server_process_id, $server_started_at, $server_ready_at, $server_stopped_at, $server_uptime, $server_restart_reason, $server_restart_delay
server.restarting
Server Restart
internal.server.restarting$event_type, $event_key, $occurred_at_utc, $server_state, $server_process_id, $server_started_at, $server_ready_at, $server_stopped_at, $server_uptime, $server_restart_reason, $server_restart_delay
server.started
Server Start
internal.server.started$event_type, $event_key, $occurred_at_utc, $server_state, $server_process_id, $server_started_at, $server_ready_at, $server_stopped_at, $server_uptime, $server_restart_reason, $server_restart_delay
server.stopped
Server Stop
internal.server.stopped$event_type, $event_key, $occurred_at_utc, $server_state, $server_process_id, $server_started_at, $server_ready_at, $server_stopped_at, $server_uptime, $server_restart_reason, $server_restart_delay
player.new_joined
New Player Joined
internal.player.new_joined$event_type, $event_key, $occurred_at_utc, $player.name, $player
bloodmoon.started
Bloodmoon Started
telnet.bloodmoon.started$event_type, $event_key, $occurred_at_utc, $bloodmoon_day
bloodmoon.ended
Bloodmoon Ended
telnet.bloodmoon.ended$event_type, $event_key, $occurred_at_utc
custom.backpack_location
Player Backpack Location
telnet.custom.backpack_location$event_type, $event_key, $occurred_at_utc
custom.preparing_quit
Preparing Quit
telnet.custom.preparing_quit$event_type, $event_key, $occurred_at_utc
custom.server_stats
Game Server Stats
telnet.custom.server_stats$event_type, $event_key, $occurred_at_utc, $inf_time, $fps, $heap, $max, $chunks, $cgo, $ply, $zom, $ent, $items, $co, $rss
custom.start_game
Start Game
telnet.custom.start_game$event_type, $event_key, $occurred_at_utc
player.connected
Player Connected
telnet.player.connected$event_type, $event_key, $occurred_at_utc, $entityid, $name, $pltfmid, $crossid, $steam_owner, $ip, $player
player.died
Player Died
telnet.player.died$event_type, $event_key, $occurred_at_utc, $inf_gmsg, $player, $player_name
player.disconnected
Player Disconnected
telnet.player.disconnected$event_type, $event_key, $occurred_at_utc, $inf_player_disconnected, $pltfm_id, $cross_id, $owner_id, $player.name, $client_number, $player
player.kicked
Player Kicked
telnet.player.kicked$event_type, $event_key, $occurred_at_utc, $kick_type, $kick_message, $entity_id, $pltfm_id, $cross_id, $owner_id, $player.name, $client_number, $player
player.banned
Player Banned
telnet.player.banned$event_type, $event_key, $occurred_at_utc, $ban_until, $ban_reason, $entity_id, $pltfm_id, $cross_id, $owner_id, $player.name, $client_number, $player
player.spawned_in_world
Player Spawned in World
telnet.player.spawned_in_world$event_type, $event_key, $occurred_at_utc, $reason, $position, $position_x, $position_y, $position_z, $entity_id, $pltfm_id, $cross_id, $owner_id, $player.name, $client_number, $player

8. String interpolation

Quoted strings and telnet command text support {{expression}} interpolation. Expressions may include bracket access such as {{$players[0].name}}. Arrays cannot be rendered directly; select an item, use join(...) for scalar arrays, or iterate with FOR EACH. Use format(...) when numbered placeholders make a message easier to read.

log("Player {{$player.name}} triggered {{$event_type}}")
@say "Welcome {{$player.name}}"
discord_send("general", format("{0}: {1}", $player.name, $chat_content))

The complete shipped templates are maintained with their event entries in RAT 5 Events, preventing a second divergent copy in this page.

9. Persistent shared state

global.* is persisted per event definition. Two definitions using global.count do not share the same value. Persistent values may be strings, numbers, booleans, or null. Arrays and objects cannot be stored in global.*; keep them in local.* and persist only the scalar result you need. Unset a path to remove it.

set global.uses = coalesce(global.uses, 0) + 1
set global.last.player = $player.name
set global.last.at = $current_datetime

if global.uses >= 100 then
  unset global.uses
end

Preview reports proposed mutations without committing them. The Events screen in RAT 5 Client can inspect globals and remove a stored global when it is no longer needed.

10. Reusable functions

A reusable function is a separately stored, versioned rat5.v2 script containing one top-level function declaration. Names begin with a lowercase letter and contain lowercase letters, numbers, and underscores.

function announce(message)
  log(message)
  return upper(message)
end

Parameters are read-only call-frame values and may contain arrays. Reusable functions may return arrays, and each call receives fresh locals. Event tokens and the calling definition's globals remain available when the function is context-dependent. Reusable functions may call enabled reusable functions, use FOR EACH, and suspend through wait(...). Direct and indirect recursion are rejected.

RAT tracks event and function dependencies. A referenced function cannot be deleted, and renames update stored references through the event store. Disabled functions cannot be called.

11. Telnet commands and response capture

A line beginning with @ sends one normalized telnet command. Carriage returns, line feeds, and NUL characters are rejected to prevent command injection.

@say "Maintenance begins in 10 minutes"

Capture is permitted only as the complete right-hand side of a set statement. Use @@command for the one-second response timeout or @@(duration)command to override it.

set local.server_time = @@(3s)gettime
log(local.server_time)

Capture waits up to five seconds for the command queue, treats 250 ms of idle output as completion, strips an echoed command, ignores transport noise, and captures at most 64 lines or 16 KiB. Empty responses, timeout, queue failure, unsafe commands, and limit overruns produce structured runtime errors.

12. Built-in functions

The server currently exposes 98 built-ins. User-defined reusable functions appear alongside these at runtime but are installation-specific.

Action

Write information to the RAT log or pause the current script. These are useful while learning and troubleshooting.

  • log(message)
    Writes an info-level event script message to the RAT server log.
    Example: log("Player {{$player.name}} said: {{$chat_content}}")
  • debug(message)
    Writes a debug-level event script message to the RAT server log when debug logging is enabled.
    Example: debug("Matched {{$event_type}} at {{$current_datetime}}")
  • wait(milliseconds)
    Suspends only the current script instance for up to 60000 ms, then resumes later from the next statement. Pending waits are kept in memory only, so restart or shutdown drops them.
    Example: wait(1500)
  • credits_modify(player_ref, amount)
    Adds or subtracts credits for the resolved player. Amount must be an integer, and unresolved players are ignored.
    Example: credits_modify($player.name, 25)
  • credits_set(player_ref, amount)
    Sets credits for the resolved player. Amount must be an integer, and unresolved players are ignored.
    Example: credits_set($player.name, 1000)

Conversion

Change a value into text, a number, or true/false so it can be compared or displayed safely.

  • to_string(value)
    Converts a value to a string using render-time rules.
    Example: to_string(global.help_count)
  • to_number(value)
    Converts a value to a number or fails when conversion is not possible.
    Example: to_number(global.score)
  • to_bool(value)
    Converts a value to a boolean using the script truthiness rules.
    Example: to_bool(global.enabled)

Discord

Send, reply to, edit, delete, react to, pin, or inspect Discord content. These require a working Discord integration.

  • discord_send(channel_key_or_id, message)
    Sends a Discord message to a configured channel mapping key or a raw reachable Discord channel ID.
    Example: discord_send("general", format("{0}: {1}", $discord_author_name, $chat_content))
    Returns: Sends `Trekkan: hello world` to the `general` channel mapping.
    `channel_key_or_id` accepts an enabled script-target mapping key or a numeric channel ID in the configured guild.
    `message` is limited to 2000 characters after trimming.
    Raw `<@...>`, `<@&...>`, `@everyone`, and `@here` text is displayed without notifying anyone. Use the Discord mention helpers to authorize notifications.
    Requires the bot to view the channel and send messages.
  • discord_embed(channel_key_or_id, title, description, color?, url?, footer?, image_url?, thumbnail_url?)
    Sends a Discord embed to a configured channel mapping key or a raw reachable Discord channel ID. Sends the embed only; no separate plain-text message body is included. Description-only embeds are allowed, trailing optional arguments may be omitted, colors must use #RRGGBB, and URLs must be http/https.
    Example: discord_embed("general", "Server Alert", format("{0}: {1}", $event_type, $chat_content), "#ff8800")
    Returns: Sends one orange embed titled `Server Alert` with the rendered event text.
    Arguments after `description` are optional and must be supplied in signature order.
    `color` must be `#RRGGBB`; URL, image, and thumbnail values must use HTTP or HTTPS.
    Title is limited to 256 characters, description to 4096, footer to 2048, and total embed text to 6000.
    This legacy form sends no plain-text content and supports no fields, author, timestamp, or footer icon; use `discord_embed_send` for those features.
    Requires View Channel, Send Messages, and Embed Links.
  • discord_embed_send(channel_key_or_id, embed_object)
    Sends a structured Discord embed object. Supports content, author, timestamp, footer icons, images, thumbnails, and deterministically ordered fields.
    Example: set local.embed.content = format("{0}", discord_mention_user($discord_author_id)) set local.embed.title = "Server Alert" set local.embed.description = $chat_content set local.embed.color = "#ff8800" set local.embed.timestamp = $occurred_at_utc set local.embed.author.name = "RAT" set local.embed.author.url = "https://example.com" set local.embed.author.icon_url = "https://example.com/rat.png" set local.embed.footer.text = "Automated" set local.embed.footer.icon_url = "https://example.com/footer.png" set local.embed.image_url = "https://example.com/image.png" set local.embed.thumbnail_url = "https://example.com/thumb.png" set local.embed.fields.field_01.name = "State" set local.embed.fields.field_01.value = "Online" set local.embed.fields.field_01.inline = true discord_embed_send("general", local.embed)
    Returns: Sends the structured embed and safely mentions only `$discord_author_id` in its plain-text content.
    Supported root properties: `content`, `title`, `description`, `color`, `url`, `timestamp`, `image_url`, and `thumbnail_url`.
    Author properties: `author.name`, `author.url`, and `author.icon_url`. URLs/icons require `author.name`.
    Footer properties: `footer.text` and `footer.icon_url`. The icon requires footer text.
    Fields are objects under `fields`; each requires `name` and `value`, with optional boolean `inline`. Field keys must be valid RatScript identifiers and are sorted alphabetically.
    Up to 25 fields are allowed. Field names are limited to 256 characters and values to 1024; aggregate embed text is limited to 6000.
    `timestamp` must be RFC3339. All URL properties must use HTTP or HTTPS.
    Only `content` can generate notifications, and only mention-helper values propagated through `format(...)` are authorized.
  • discord_status(kind, text?)
    Updates the active Discord bot's scripted activity/custom status for the live session only. Supports clear, playing, watching, and custom. Repeating the same normalized request is a no-op, and clear removes the current scripted override without persisting anything across reconnects.
    Example: discord_status("playing", format("Watching {0} players", $player_count))
    Returns: Sets the bot activity to `Playing Watching 4 players` for the current Discord session.
    `kind` supports `playing`, `watching`, `custom`, and `clear`.
    `playing`, `watching`, and `custom` require non-empty text. `clear` accepts no text.
    Status changes are session-only and are not persisted across reconnects. Repeating the same normalized value is a no-op.
  • discord_reply(channel_key_or_id, message_id, message, mention_replied_user?)
    Replies to a Discord message. The replied user is not notified unless the final argument is true.
    Example: discord_reply("general", $discord_message_id, "Acknowledged", false)
    Returns: Replies `Acknowledged` to `$discord_message_id` without notifying the original author.
    `message_id` must be a numeric Discord message ID in the target channel.
    `mention_replied_user` defaults to false. Set it to true only when the reply should notify the original author.
    Mentions inside `message` remain default-deny unless constructed with Discord mention helpers.
    Requires View Channel, Send Messages, and Read Message History.
  • discord_edit(channel_key_or_id, message_id, message)
    Edits a message created by the Discord bot.
    Example: discord_edit("general", local.message_id, "Updated status")
    Returns: Replaces the bot message content with `Updated status`.
    The bot can edit only messages it created. `message_id` must be numeric and the replacement is limited to 2000 characters.
    Raw mention syntax does not notify; use Discord mention helpers for explicitly authorized mentions.
  • discord_delete(channel_key_or_id, message_id)
    Deletes a Discord message when the bot has permission.
    Example: discord_delete("general", local.message_id)
    Returns: Deletes the selected Discord message.
    `message_id` must be numeric. Deleting another user's message requires Manage Messages.
    The target channel must be an enabled script target or a reachable channel in the configured guild.
  • discord_react(channel_key_or_id, message_id, emoji)
    Adds a reaction to a Discord message.
    Example: discord_react("general", $discord_message_id, "👍")
    Returns: Adds 👍 to `$discord_message_id`.
    `emoji` accepts a Unicode emoji such as `👍` or Discord custom-emoji format such as `name:123456789012345678`.
    Requires Add Reactions and Read Message History; custom emoji may require Use External Emoji.
  • discord_pin(channel_key_or_id, message_id)
    Pins a Discord message.
    Example: discord_pin("general", $discord_message_id)
    Returns: Pins `$discord_message_id` in the target channel.
    Requires Manage Messages. `message_id` must be numeric.
  • discord_unpin(channel_key_or_id, message_id)
    Unpins a Discord message.
    Example: discord_unpin("general", $discord_message_id)
    Returns: Removes the pin from `$discord_message_id`.
    Requires Manage Messages. `message_id` must be numeric.
  • discord_thread_start(channel_key_or_id, message_id, name, archive_minutes?)
    Starts a thread from a Discord message. Archive minutes may be 60, 1440, 4320, or 10080.
    Example: discord_thread_start("general", $discord_message_id, "Incident discussion", 1440)
    Returns: Creates `Incident discussion` from `$discord_message_id` and auto-archives it after 1440 minutes of inactivity.
    `name` is required and limited to 100 characters.
    `archive_minutes` defaults to 1440 and must be one of 60, 1440, 4320, or 10080. Availability depends on guild features.
    Requires Create Public Threads and Send Messages in Threads.
  • discord_mention_user(user_id)
    Builds a user mention and authorizes only that user mention when the value is sent to Discord.
    Example: discord_mention_user($discord_author_id)
    Returns: <@456789012345678901>
    `user_id` must contain only digits.
    The returned value carries a whitelist for exactly that user. Preserve it with `format(...)` and pass the result directly to a Discord message, reply, edit, or structured embed `content`.
  • discord_mention_role(role_id)
    Builds a role mention and authorizes only that role mention when the value is sent to Discord.
    Example: discord_mention_role("123456789012345678")
    Returns: <@&567890123456789012>
    `role_id` must contain only digits.
    The returned value carries a whitelist for exactly that role. Whether it notifies depends on Discord role mentionability and bot permissions.
  • discord_mention_everyone()
    Builds an explicit @everyone mention. This is a high-impact notification and should be used sparingly.
    Example: discord_mention_everyone()
    Returns: @everyone
    Requires `[discord.automation_options].allow_mass_mentions = true`; otherwise sending fails.
    This authorizes Discord's `everyone` mention type and therefore applies to `@everyone` or `@here` text in the same message.
  • discord_mention_here()
    Builds an explicit @here mention. This is a high-impact notification and should be used sparingly.
    Example: discord_mention_here()
    Returns: @here
    Requires `[discord.automation_options].allow_mass_mentions = true`; otherwise sending fails.
    This authorizes Discord's `everyone` mention type and therefore applies to `@everyone` or `@here` text in the same message.
  • discord_user_has_role(user_id, role_id)
    Returns true when the user is a member of the configured Discord guild and currently has the specified role.
    Example: discord_user_has_role($discord.author.id, "567890123456789012")
    Returns: true
    Parameters: user_id (string); role_id (string)
    Return type: boolean
    Both arguments must be numeric Discord IDs; role names are not accepted.
    Returns false when the user is not in the configured guild or does not have the role.
    Discord configuration or connection failures are reported as runtime errors.
  • discord_user_in_guild(user_id)
    Returns true when the user is currently a member of the configured Discord guild.
    Example: discord_user_in_guild($discord.author.id)
    Returns: true
    Parameters: user_id (string)
    Return type: boolean
    `user_id` must be a numeric Discord ID.
    Returns false when Discord reports that the user is not a member of the configured guild.
    Discord configuration or connection failures are reported as runtime errors.
  • discord_channel_exists(channel_key_or_id)
    Returns true when a configured channel mapping key or numeric channel ID resolves inside the configured Discord guild.
    Example: discord_channel_exists("general")
    Returns: true
    Parameters: channel_key_or_id (string)
    Return type: boolean
    Accepts a configured channel mapping key or a numeric Discord channel ID.
    Returns false when the channel does not exist or belongs to another guild.
    The mapping does not need to be enabled as a script target for this existence check.
  • discord_role_exists(role_id)
    Returns true when the numeric role ID exists in the configured Discord guild.
    Example: discord_role_exists("567890123456789012")
    Returns: true
    Parameters: role_id (string)
    Return type: boolean
    `role_id` must be a numeric Discord ID; role names are not accepted.
    Returns false when the role is absent from the configured guild.
    Discord configuration or connection failures are reported as runtime errors.

Game Server

Broadcast messages and start, stop, restart, or inspect the managed game server. Review these carefully before enabling them.

  • gs_start()
    Starts the game server. Fire-and-forget; the script does not wait for the server to finish starting.
    Example: gs_start()
  • gs_stop(reason?)
    Stops the game server. An optional reason string is logged. Fire-and-forget.
    Example: gs_stop("Scheduled maintenance")
  • gs_restart(reason?)
    Restarts the game server. An optional reason string is logged. Fire-and-forget.
    Example: gs_restart("Nightly restart")
  • gs_status()
    Returns the current server state as a string: "unknown", "stopped", "starting", "running", "stopping", "restarting", or "crashed".
    Example: gs_status()
  • gs_broadcast(message, broadcast_type?, channel_key?)
    Broadcasts a message via one or more channels. broadcast_type: "say" (default), "discord", "discord_embed", "log", "all". channel_key is required for discord types.
    Example: gs_broadcast("Server restarting in 5 minutes.", "say")
  • gs_countdown(seconds, action, reason?, interval?, broadcast_type?, channel_key?)
    Starts a countdown that executes action ("stop" or "restart") at zero. Fires milestone broadcasts automatically. A second call while a countdown is active is a no-op — call gs_countdown_cancel() first.
    Example: gs_countdown(300, "restart", "Nightly maintenance", 60, "say")
  • gs_countdown_cancel(message?, broadcast_type?, channel_key?)
    Cancels the active countdown without executing the action. Silent by default; pass a message to broadcast the cancellation.
    Example: gs_countdown_cancel("Restart cancelled by admin.", "say")

Logic

Test whether values exist, are empty, match text, occur in collections, or meet common conditions.

  • count(collection)
    Returns the number of elements in an array or indexed collection.
    Example: count($players)
    Returns: 4
    Parameters: collection (array)
    Return type: number
    Accepts native arrays and compatibility-indexed collections.
  • append(array, value)
    Returns a new array with the value appended.
    Example: append([], "Alice")
    Returns: ["Alice"]
    Parameters: array (array); value (any value)
    Return type: array
    Returns a copy and never mutates the input array.
    Arrays are limited to 256 elements.
  • contains_value(collection, value)
    Returns true when a scalar collection element equals the supplied value.
    Example: contains_value(local.names, "Alice")
    Returns: true
    Parameters: collection (array); value (string, number, boolean, or null)
    Return type: boolean
    Values are compared without changing their types. Object and array elements are skipped.
  • empty(value)
    Returns true when the value is null or an empty string.
    Example: empty($chat_content)
  • exists(value)
    Returns true when the value is not null.
    Example: exists(global.last_help_player)
  • coalesce(a, b, ...)
    Returns the first non-null value.
    Example: coalesce(global.help_count, 0)

Lookup

Find structured information, such as a player record. Lookups can return null when no unique result exists.

  • player(name_or_id)
    Returns a structured player object for the matching current player name or stored identifier. Assign the result to a local before reading properties like local.pinfo.name.
    Example: SET local.pinfo = player($player.name)
    Parameters: name_or_id (string)
    Return type: object (nullable)
    return.id - Stable RAT player identifier.
    return.name - Current player display name.
    return.platform_id - Primary platform identifier reported by the game.
    return.cross_platform_id - Cross-platform identifier when available.
    return.steam_id - Steam user identifier when available.
    return.eos_id - Epic Online Services identifier when available.
    return.xbl_id - Xbox Live identifier when available.
    return.platform_family - Primary platform family.
    return.platform_user_id - User-id portion of the primary platform identifier.
    return.cross_platform_family - Cross-platform identifier family.
    return.cross_platform_user_id - User-id portion of the cross-platform identifier.
    return.entity_id - Current in-game entity identifier.
    return.online - True when RAT currently considers the player online.
    return.last_seen_at - Last known UTC observation time in RFC3339 format.
    return.ip_address - Most recently observed IP address.
    return.level - Current player level.
    return.health - Current health value.
    return.stamina - Current stamina value.
    return.score - Current score.
    return.ping - Current network latency in milliseconds.
    return.deaths - Recorded death count.
    return.zombie_kills - Recorded zombie kill count.
    return.player_kills - Recorded player kill count.
    return.total_play_time_seconds - Recorded total play time in seconds.
    return.credits - Current RAT credits balance.
    return.ban_active - True when the player has an active ban.
    return.ban_reason - Current ban reason when available.
    return.ban_until - Current ban expiration in UTC when available.
    return.group - Effective RAT player group.
    return.group.id - Effective group identifier.
    return.group.name - Effective group display name.
    return.group.max_teleport_destinations - Maximum saved teleport destinations.
    return.group.teleport_cooldown_seconds - Teleport cooldown in seconds.
    return.position - Last known player position.
    return.position.x - World X coordinate.
    return.position.y - World Y coordinate.
    return.position.z - World Z coordinate.

Math

Calculate, round, limit, or randomly select numeric values.

  • abs(value)
    Returns the absolute numeric value.
    Example: abs(-10)
  • min(a, b, ...)
    Returns the smallest numeric value.
    Example: min(1, 2, 3)
  • max(a, b, ...)
    Returns the largest numeric value.
    Example: max(1, 2, 3)
  • round(value)
    Rounds a number to the nearest whole value.
    Example: round(12.5)
  • floor(value)
    Rounds a number down.
    Example: floor(12.5)
  • ceil(value)
    Rounds a number up.
    Example: ceil(12.5)
  • clamp(value, min, max)
    Clamps a number into the provided range.
    Example: clamp(global.score, 0, 100)
  • chance(percent)
    Returns true with the requested percentage probability from 0 through 100.
    Example: chance(25)
    Returns: true or false
    Parameters: percent (number)
    Return type: boolean
    `percent` may be fractional and must be between 0 and 100 inclusive.
    `chance(0)` is always false and `chance(100)` is always true.
  • is_between(value, min, max)
    Returns true when a number is inclusively between the supplied minimum and maximum.
    Example: is_between($player.level, 10, 25)
    Returns: true
    Parameters: value (number); min (number); max (number)
    Return type: boolean
    Both boundaries are inclusive.
    A minimum greater than the maximum is a runtime error.

Player

Read player status, groups, distances, positions, areas, balances, and leaderboard information.

  • player_has_group(player_ref, group_ref)
    Returns true when the uniquely resolved player's effective RAT group matches the supplied group ID or display name.
    Example: player_has_group($player.id, "VIP")
    Returns: true
    Parameters: player_ref (string); group_ref (string)
    Return type: boolean
    `player_ref` uses the same unique player resolution rules as `player(...)`.
    `group_ref` matches either the effective group ID or display name, case-insensitively.
    The default group counts as the player's effective group. Unresolved or ambiguous players return false.
  • player_exists(player_ref)
    Returns true when the reference uniquely resolves to a stored player.
    Example: player_exists("Steam_76561197970441157")
    Returns: true
    Parameters: player_ref (string)
    Return type: boolean
    Accepts a RAT player ID, unique display name, platform ID, Steam ID, EOS ID, or Xbox ID.
    Returns false when there is no match or more than one player matches.
  • player_online(player_ref)
    Returns true when RAT currently considers the uniquely resolved player online.
    Example: player_online($player.id)
    Returns: true
    Parameters: player_ref (string)
    Return type: boolean
    Uses RAT's current stored online state for the uniquely resolved player.
    Unresolved or ambiguous players return false.
  • player_banned(player_ref)
    Returns true when the uniquely resolved player has an active ban.
    Example: player_banned($player.id)
    Returns: false
    Parameters: player_ref (string)
    Return type: boolean
    Returns the active-ban state for the uniquely resolved player.
    Unresolved or ambiguous players return false.
  • player_distance(player_a, player_b)
    Returns the unrounded three-dimensional distance between two players' latest known positions, or null when unavailable.
    Example: player_distance($player.id, "TargetPlayer")
    Returns: 312.47
    Parameters: player_a (string); player_b (string)
    Return type: number (nullable)
    Calculates Euclidean distance using unrounded X, Y, and Z coordinates.
    Returns null when either player is unresolved, ambiguous, or lacks a complete known position.
  • player_distance_from(player_ref, x, y, z)
    Returns the unrounded three-dimensional distance from a player's latest known position to the supplied coordinates, or null when unavailable.
    Example: player_distance_from($player.id, 1250, 70, -840)
    Returns: 84.32
    Parameters: player_ref (string); x (number); y (number); z (number)
    Return type: number (nullable)
    Calculates Euclidean distance using the player's unrounded X, Y, and Z coordinates.
    Returns null when the player is unresolved, ambiguous, or lacks a complete known position.
    Coordinates must be finite numbers.
  • player_in_area(player_ref, x1, y1, z1, x2, y2, z2)
    Returns true when a player's latest known position is inside or on the boundary of the 3D box defined by two opposite corners.
    Example: player_in_area($player.id, 1200, 60, -900, 1300, 100, -800)
    Returns: true
    Parameters: player_ref (string); x1 (number); y1 (number); z1 (number); x2 (number); y2 (number); z2 (number)
    Return type: boolean
    The two coordinate triples are opposite corners of an axis-aligned 3D box.
    Corner order does not matter, and all six boundaries are inclusive.
    Returns false when the player is unresolved, ambiguous, or lacks a complete known position.
    Coordinates must be finite numbers.
  • in_area(inner_x1, inner_y1, inner_z1, inner_x2, inner_y2, inner_z2, outer_x1, outer_y1, outer_z1, outer_x2, outer_y2, outer_z2)
    Returns true when the first 3D box is entirely inside or on the boundary of the second 3D box.
    Example: in_area(1210, 65, -890, 1290, 95, -810, 1200, 60, -900, 1300, 100, -800)
    Returns: true
    Parameters: inner_x1 (number); inner_y1 (number); inner_z1 (number); inner_x2 (number); inner_y2 (number); inner_z2 (number); outer_x1 (number); outer_y1 (number); outer_z1 (number); outer_x2 (number); outer_y2 (number); outer_z2 (number)
    Return type: boolean
    Each pair of coordinate triples defines opposite corners of an axis-aligned 3D box.
    Corner order does not matter, and containment includes all six boundaries.
    Partial overlap is not containment and returns false.
    Coordinates must be finite numbers.
  • player_leaderboard(metric, limit, row_template?, separator?)
    Returns a formatted leaderboard using current stored player data. The default row template is "{rank}. {player.name} - {formatted_value}".
    Example: player_leaderboard("zombie_kills", 10, "#{rank} {player.name}: {formatted_value}", "\n")
    Parameters: metric (string); limit (number); row_template (string, optional); separator (string, optional)
    Return type: string
    Available metrics:
    deaths - Recorded death count.
    zombie_kills - Recorded zombie kill count.
    player_kills - Recorded player kill count.
    total_play_time_seconds - Recorded total play time.
    score - Current recorded score.
    level - Current recorded player level.
    credits - Current RAT credits balance.
    Available row-template fields:
    {rank} - One-based ordinal rank.
    {metric} - Canonical leaderboard metric key.
    {metric_label} - Human-readable metric label.
    {value} - Raw numeric metric value.
    {formatted_value} - Metric-aware display value.
    {player.id} - Stable RAT player identifier.
    {player.name} - Current player display name.
    {player.online} - Whether RAT currently considers the player online.
    {player.level} - Current player level, or blank when unavailable.
    {player.score} - Current score, or blank when unavailable.
    {player.deaths} - Recorded death count, or blank when unavailable.
    {player.zombie_kills} - Recorded zombie kill count, or blank when unavailable.
    {player.player_kills} - Recorded player kill count, or blank when unavailable.
    {player.total_play_time_seconds} - Recorded total play time in seconds, or blank when unavailable.
    {player.credits} - Current RAT credits balance.
    {player.last_seen_at} - Last known UTC observation time, or blank when unavailable.
  • player_leaderboard_entry(metric, position)
    Returns one structured leaderboard entry, or null when that position has no eligible player. Assign the result to a local before reading its properties.
    Example: player_leaderboard_entry("zombie_kills", 1)
    Parameters: metric (string); position (number)
    Return type: object (nullable)
    return.rank - One-based ordinal rank.
    return.metric - Canonical leaderboard metric key.
    return.metric_label - Human-readable metric label.
    return.value - Raw numeric metric value.
    return.formatted_value - Metric-aware display value.
    return.player - Ranked player.
    return.player.id - Stable RAT player identifier.
    return.player.name - Current player display name.
    return.player.platform_id - Primary platform identifier reported by the game.
    return.player.cross_platform_id - Cross-platform identifier when available.
    return.player.steam_id - Steam user identifier when available.
    return.player.eos_id - Epic Online Services identifier when available.
    return.player.xbl_id - Xbox Live identifier when available.
    return.player.platform_family - Primary platform family.
    return.player.platform_user_id - User-id portion of the primary platform identifier.
    return.player.cross_platform_family - Cross-platform identifier family.
    return.player.cross_platform_user_id - User-id portion of the cross-platform identifier.
    return.player.entity_id - Current in-game entity identifier.
    return.player.online - True when RAT currently considers the player online.
    return.player.last_seen_at - Last known UTC observation time in RFC3339 format.
    return.player.ip_address - Most recently observed IP address.
    return.player.level - Current player level.
    return.player.health - Current health value.
    return.player.stamina - Current stamina value.
    return.player.score - Current score.
    return.player.ping - Current network latency in milliseconds.
    return.player.deaths - Recorded death count.
    return.player.zombie_kills - Recorded zombie kill count.
    return.player.player_kills - Recorded player kill count.
    return.player.total_play_time_seconds - Recorded total play time in seconds.
    return.player.credits - Current RAT credits balance.
    return.player.ban_active - True when the player has an active ban.
    return.player.ban_reason - Current ban reason when available.
    return.player.ban_until - Current ban expiration in UTC when available.
    return.player.group - Effective RAT player group.
    return.player.group.id - Effective group identifier.
    return.player.group.name - Effective group display name.
    return.player.group.max_teleport_destinations - Maximum saved teleport destinations.
    return.player.group.teleport_cooldown_seconds - Teleport cooldown in seconds.
    return.player.position - Last known player position.
    return.player.position.x - World X coordinate.
    return.player.position.y - World Y coordinate.
    return.player.position.z - World Z coordinate.
  • credits_balance(player_ref)
    Returns the current credits balance for the resolved player, or null when no unique player match is found.
    Example: credits_balance($player.name)

String

Build, search, normalize, split, format, and join text or scalar collections.

  • join(collection, separator)
    Renders scalar collection elements joined by the separator.
    Example: join(local.names, ", ")
    Returns: Alice, Bob
    Parameters: collection (array); separator (string)
    Return type: string
    Every element must be a scalar value; objects and nested arrays are rejected.
  • format(template, value1, value2, ...)
    Formats a string with numbered placeholders like {0} and {1}.
    Example: format("Player {0} said {1}", $player.name, $chat_content)
  • contains(value, search)
    Returns true when the plain-text search value appears within the source string.
    Example: contains(lower($chat_content), "!help")
  • contains_any(value, search1, search2, ...)
    Returns true when any supplied plain-text search value appears within the source string.
    Example: contains_any(lower($chat_content), "help", "admin", "support")
    Returns: true
    Parameters: value (string); search1 (string); search2... (string, optional)
    Return type: boolean
    Searches are plain text and case-sensitive; use `lower(...)` when case should be ignored.
    At least one search value is required. An empty search value matches every string.
  • equals_ignore_case(a, b)
    Returns true when two rendered strings are equal without case sensitivity.
    Example: equals_ignore_case($chat_content, "!HELP")
    Returns: true
    Parameters: a (string); b (string)
    Return type: boolean
    Renders both values as strings and compares them with Unicode-aware case folding.
  • matches(value, pattern)
    Returns true when the string matches a bounded RE2 regular expression.
    Example: matches($chat_content, "^![a-z_]+$")
    Returns: true
    Parameters: value (string); pattern (string)
    Return type: boolean
    Uses Go's RE2 syntax, which does not support backreferences or look-around assertions.
    Input is limited to 8192 characters and the pattern to 512 characters.
    Invalid patterns and oversized values are runtime errors.
  • starts_with(value, prefix)
    Returns true when the source string begins with the provided prefix.
    Example: starts_with($player.name, "[Admin]")
  • ends_with(value, suffix)
    Returns true when the source string ends with the provided suffix.
    Example: ends_with($player.name, "_bot")
  • lower(value)
    Converts a string to lowercase using culture-invariant rules.
    Example: lower($player.name)
  • upper(value)
    Converts a string to uppercase using culture-invariant rules.
    Example: upper($player.name)
  • trim(value)
    Trims leading and trailing whitespace.
    Example: trim($chat_content)
  • trim_start(value)
    Trims leading whitespace.
    Example: trim_start($chat_content)
  • trim_end(value)
    Trims trailing whitespace.
    Example: trim_end($chat_content)
  • replace(value, from, to)
    Replaces the first plain-text match in a string.
    Example: replace($chat_content, " ", " ")
  • replace_all(value, from, to)
    Replaces every plain-text match in a string.
    Example: replace_all($chat_content, " ", " ")
  • substring(value, start, length?)
    Returns a substring from the provided start index, optionally limited by length.
    Example: substring($chat_content, 0, 24)
  • length(value)
    Returns the rendered string length.
    Example: length($chat_content)
  • concat(a, b, ...)
    Concatenates rendered values into a single string.
    Example: concat($player.name, ": ", $chat_content)
  • left(value, count)
    Returns the leftmost count characters from a string.
    Example: left($player.name, 3)
  • right(value, count)
    Returns the rightmost count characters from a string.
    Example: right($player.name, 3)
  • pad_left(value, length, pad?)
    Pads a string on the left to the requested width.
    Example: pad_left($player.name, 12, ".")
  • pad_right(value, length, pad?)
    Pads a string on the right to the requested width.
    Example: pad_right($player.name, 12, ".")
  • index_of(value, search)
    Returns the first zero-based index of a substring or -1 when absent.
    Example: index_of($chat_content, "!")
  • last_index_of(value, search)
    Returns the last zero-based index of a substring or -1 when absent.
    Example: last_index_of($chat_content, "!")
  • pluralize(count, singular, plural?)
    Returns singular when count equals 1; otherwise returns the supplied plural or singular with s appended.
    Example: pluralize($players_online, "player", "players")
    Returns: players
    Parameters: count (number); singular (string); plural (string, optional)
    Return type: string
    Returns `singular` only when count equals exactly 1.
    When `plural` is omitted, the default is `singular` with `s` appended.
    The function returns the selected word only; it does not include the count.

Teleport

Manage teleport destinations and move players. These functions perform live game actions.

  • tp_dc(player_ref)
    Returns the player's current teleport destination count. Unresolved players return 0.
    Example: tp_dc($player.name)
  • tp_mdc(player_ref)
    Returns the player's maximum teleport destination count. Unresolved players return 0.
    Example: tp_mdc($player.name)
  • tp_list(player_ref)
    Returns teleport destinations as newline-delimited text: name => (x, y, z[, dir]). Unresolved players return an empty string.
    Example: tp_list($player.name)
  • tp_add(player_ref, destination, x, y, z, direction?)
    Adds or updates a saved teleport destination for the resolved player.
    Example: tp_add($player.name, "home", 10, 65, -2, "n")
  • tp_remove(player_ref, destination)
    Removes a saved teleport destination for the resolved player.
    Example: tp_remove($player.name, "home")
  • tp_go(player_ref, destination)
    Teleports the resolved player to a saved destination. Missing destinations are ignored.
    Example: tp_go($player.name, "home")
  • tp_to(player_ref, x, y, z, direction?)
    Teleports the resolved player to explicit coordinates.
    Example: tp_to($player.name, 100, 70, -100, "e")
  • tp_to_ground(player_ref, x, z, direction?)
    Teleports the resolved player to x/z using y=-1.
    Example: tp_to_ground($player.name, 100, -100, "s")
  • tp_to_player(player_ref, target_player_ref)
    Teleports the resolved player to another player's current position.
    Example: tp_to_player($player.name, "TargetPlayer")
  • tp_offset(player_ref, dx, dy, dz)
    Teleports the resolved player by an integer offset from their current position.
    Example: tp_offset($player.name, 0, 1, 0)

Time

Convert durations and compare stored timestamps with the current event time.

  • duration_seconds(value)
    Parses a non-negative duration such as 30s, 5m, or 2h and returns its length in seconds.
    Example: duration_seconds("5m")
    Returns: 300
    Parameters: value (string)
    Return type: number
    Uses duration units such as `ms`, `s`, `m`, and `h`; units may be combined, as in `1h30m`.
    Negative and invalid durations are runtime errors. Fractional seconds are preserved.
  • elapsed_seconds(datetime)
    Returns seconds elapsed between an RFC3339 timestamp and the current event time.
    Example: elapsed_seconds($player.last_seen_at)
    Returns: 3600
    Parameters: datetime (string)
    Return type: number (nullable)
    `datetime` must use RFC3339. Null input returns null.
    Uses the event's `$current_datetime`, so previews are evaluated relative to their selected occurrence time.
    Future timestamps produce negative results.

13. Limits and failure behavior

14. Complete examples

Welcome every currently online player

$players is a snapshot taken when this script starts. This example sends one message per online player.

for each local.player in $players
  gs_broadcast(format("Welcome, {0}!", local.player.name), "say")
end

Persistent chat-command counter

Event type: chat.global_message

set local.message = lower(trim($chat_content))

if local.message == "!status" then
  set global.status_uses = coalesce(global.status_uses, 0) + 1
  gs_broadcast(
    format("Server: {0}; players: {1}/{2}; uses: {3}",
      gs_status(), $players_online, $players_max, global.status_uses),
    "say"
  )
end

Discord reply with a safe mention

Event type: discord.message_received

if equals_ignore_case(trim($chat_content), "!ack") then
  discord_reply(
    $discord_channel_id,
    $discord_message_id,
    format("{0} acknowledged", discord_mention_user($discord_author_id)),
    false
  )
end

Leaderboard announcement

set local.board = player_leaderboard("zombie_kills", 10)
discord_send("general", local.board)

Check whether a player position is in an area

This example can be used with a player event such as player.spawned_in_world. player_in_area(...) checks the player's latest known position when that event runs. It does not continuously monitor the area between events.

if player_in_area($player.id, 1200, 60, -900, 1300, 100, -800) then
  log(format("{0} is inside the protected area", $player.name))
end

Check whether one area fits inside another

in_area(...) compares two boxes rather than looking up a player. The first six coordinates define the box being tested; the final six define the containing box. Touching the boundary is allowed, but partial overlap returns false.

if in_area(
  1210, 65, -890, 1290, 95, -810,
  1200, 60, -900, 1300, 100, -800
) then
  log("The proposed area fits inside the protected area")
end

Safe player lookup

set local.pinfo = player($player.name)
if exists(local.pinfo.id) then
  debug(format("Resolved {0} as {1}", local.pinfo.name, local.pinfo.id))
else
  debug(format("Could not uniquely resolve {0}", $player.name))
end
Recommended workflowStart from the selected event's shipped template, validate often, and preview against a captured snapshot before enabling live actions.
Related referenceSee RAT 5 Events for dispatch, ordering, managed definitions, execution status, and the complete event catalog.