Configuration

RTP keeps its license and runtime settings in one config file.

Main sections

SectionPurpose
SETTINGSGlobal mode, dimension locking, limits, warmup/cancel behavior and safe-location exclusions.
MESSAGES / MESSAGES-DISPLAYMessage text plus chat/action-bar routing.
WORLD-SETTINGSPer-world radius, center and cooldown.
RTP-MENUDimension and server menu layout, materials, lore and click sound.
RTP-QUEUEMatchmaking, partner distance, warmup, cooldown, broadcasts, action bar and music.
DATABASEOptional shared unlock storage: MariaDB, MySQL, PostgreSQL or SQLite.
NETWORKRedis cross-server discovery and Velocity routing settings.

Default config

yaml
license-key: "PUT-LICENSE-HERE"

# ============================================================
#  RTP - Cross-server Random Teleport
#  CanvasMC / Folia 26.1.2
#
#  Color formats supported in all messages & menus:
#    - Legacy:   &a, &c, &l, ...
#    - HEX:      &#RRGGBB  or  #RRGGBB
# ============================================================

SETTINGS:
  # Single-server mode. When true there are no regions and no server picker sub-menu:
  # clicking a dimension (or using /rtp <dimension>) teleports directly on THIS server.
  # Leave false for the cross-server setup with the region/server sub-menu.
  SINGLE-SERVER: false
  # Lock the nether/end until a player has entered that dimension at least once.
  # When false, every dimension is always available.
  LOCK-DIMENSIONS: true
  # Whether anyone may skip the RTP and /rtpqueue cooldowns.
  #   false - the cooldown applies to everybody, operators and you included.
  #   true  - players with rtp.bypass.cooldown skip it.
  # rtp.bypass.cooldown used to be default:op, which meant every operator held it without
  # being granted anything - so staff never had a cooldown, and an owner who set one and
  # tested it in game saw no cooldown at all. The permission is default:false now AND has to
  # be enabled here, so granting the bypass is two deliberate steps.
  COOLDOWN-BYPASS: false
  # Max players using RTP simultaneously (per backend server).
  PLAYERS-IN-RTP: 3
  # Max tries to find a valid RTP location before failing.
  MAX-ATTEMPTS: 16
  # In seconds. Players with rtp.bypass.countdown skip this and the /rtpqueue warmup entirely
  # and teleport as soon as a location is found. That permission is default:false, so nobody
  # holds it - operators included - until it is granted.
  TELEPORT-COUNTDOWN: 5
  TELEPORT-COUNTDOWN-SOUND: "ENTITY_ENDERMAN_TELEPORT"
  TELEPORT-SUCCESSFULLY-SOUND: "ENTITY_ENDERMAN_TELEPORT"
  # Sound played when a teleport is cancelled (by moving or taking damage).
  TELEPORT-CANCELLED-SOUND: "ENTITY_VILLAGER_NO"
  # Cancel the teleport if the player moves during the countdown.
  CANCEL-ON-MOVE: true
  # Cancel the teleport if the player takes damage during the countdown.
  CANCEL-ON-DAMAGE: true
  UNAVAILABLE-BLOCKS:
    - "LAVA"
    - "WATER"
  UNAVAILABLE-BIOMES:
    - "BEACH"

MESSAGES:
  COOLDOWN: "&cYou can't rtp for another {remaining}s."
  MAX-PLAYERS: "&cToo many players are using RTP right now. Please try again later."
  WORLD-NOT-EXIST: "&cThe world does not exist."
  SEARCHING: "&7Teleporting..."
  MAX-ATTEMPTS: "&cCould not find a safe location after {attempts} attempts."
  DESTINATION-DISABLED: "&cThis RTP destination is currently disabled."
  LOCKED: "&c🔒 Locked!\n&7Enter this dimension to unlock RTP in it!"
  TELEPORT-COUNTDOWN: "&7Teleporting in &#FF0000{countdown}s"
  TELEPORT-SUCCESS: "&7You teleported to a random location"
  TELEPORT-CANCELLED: "&cTeleport cancelled because you moved."
  SERVER-OFFLINE: "&cThat server is currently unavailable."
  NO-SERVERS: "&cThere are no available servers for this destination."
  NO-PERMISSION: "&cYou don't have permission to do that."
  PLAYER-ONLY: "&cThis command can only be used by players."
  RELOADED: "&aRTP configuration reloaded."
  SETWORLD-SET: "&aRTP world for &f{dimension}&a set to &f{world}&a."
  SETWORLD-USAGE: "&cUsage: /rtp setworld <overworld|nether|end> <world>"
  # /rtpqueue messages.
  QUEUE-JOINED: "&7You joined the RTP queue. &fRun /rtpq again to leave."
  # Broadcast when a player begins waiting. {player} is the player's name.
  QUEUE-BROADCAST-JOIN: "&#FFE300{player} &7is searching for another player to RTP with!\n&7Type &#FFE300/rtpq &7to join the queue."
  QUEUE-BROADCAST-USAGE: "&cUsage: /rtpqueuebroadcast <player> <on|off>"
  QUEUE-BROADCAST-PLAYER-NOT-FOUND: "&cThat player is not online."
  QUEUE-BROADCAST-ENABLED: "&aQueue join broadcasts are now enabled for &f{player}&a."
  QUEUE-BROADCAST-DISABLED: "&aQueue join broadcasts are now disabled for &f{player}&a."
  QUEUE-BROADCAST-SAVE-FAILED: "&cThe preference changed for this session but could not be saved."
  QUEUE-LEFT: "&cYou left the RTP queue."
  QUEUE-MATCH-FOUND: "&aMatch found with &f{player}&a! Teleporting you together..."
  QUEUE-WARMUP: "&7Teleporting in &#FF0000{countdown}s"
  QUEUE-TELEPORT-CANCELLED: "&cTeleport canceled!"
  QUEUE-COOLDOWN: "&cYou can't use the RTP queue for another {remaining}s."
  QUEUE-TELEPORT-SUCCESS: "&7You were teleported near &f{player}&7."
  QUEUE-NO-LOCATION: "&cCould not find a safe location. Please queue again."
  QUEUE-PARTNER-LEFT: "&cYour match is no longer available. Please queue again."
  QUEUE-UNAVAILABLE: "&cThe RTP queue is unavailable right now."

# Choose where each message appears. A key listed under ACTION-BAR-MESSAGE-KEYS is shown in the
# action bar (when ACTION-BAR is true, otherwise it falls back to chat); every other message is
# shown in chat (when CHAT is true).
MESSAGES-DISPLAY:
  CHAT: true
  ACTION-BAR: true
  ACTION-BAR-MESSAGE-KEYS:
    - TELEPORT-COUNTDOWN
    - SEARCHING
    - TELEPORT-SUCCESS
    - TELEPORT-CANCELLED
    - QUEUE-WARMUP
    - QUEUE-TELEPORT-CANCELLED

# Per-world RTP ranges and cooldowns. Keys are world names.
# You can also set them in game: /rtp setworld <dimension> <world>.
WORLD-SETTINGS:
  world: # Overworld name
    MAX-RADIUS: 25000
    MIN-RADIUS: -25000
    CENTER-X: 0
    CENTER-Z: 0
    COOLDOWN: 5 # In seconds
  world_nether:
    MAX-RADIUS: 3000
    MIN-RADIUS: -3000
    CENTER-X: 0
    CENTER-Z: 0
    COOLDOWN: 5 # In seconds
  world_the_end:
    MAX-RADIUS: 15000
    MIN-RADIUS: -15000
    CENTER-X: 0
    CENTER-Z: 0
    COOLDOWN: 5 # In seconds

RTP-MENU:
  TITLE: "&8ʀᴀɴᴅᴏᴍ ᴛᴇʟᴇᴘᴏʀᴛ"
  SIZE: 27
  PLACEHOLDER: false
  # Sound played when clicking a button in any RTP menu.
  # Accepts a namespaced key ("minecraft:block.note_block.hat") or a Bukkit Sound enum ("BLOCK_NOTE_BLOCK_HAT").
  CLICK-SOUND:
    SOUND: "minecraft:block.note_block.hat"
    VOLUME: 1.0
    PITCH: 1.9
  DECORATION-BUTTON:
    DISPLAY-NAME: ""
    LORE:
      - ""
  BUTTONS:
    # Main-menu lore placeholders:
    # {dimension}, {world}, {min-distance}, {max-distance}, {border},
    # {keep-inventory}, {players-in-world}, {players}, and {ping}.
    OVERWORLD:
      DISPLAY-NAME: "&#22FF00ᴏᴠᴇʀᴡᴏʀʟᴅ"
      MATERIAL: "GRASS_BLOCK"
      SLOT: 11
      WORLD: "world"
      ENABLED: true
      LORE:
        - "&7Description"
        - ""
        - "&#22FF00Information:"
        - "&fDrops you at a random spot in the &#22FF00Overworld"
        - "&fAnywhere between &#22FF00{min-distance} &fand &#22FF00{max-distance} &fblocks away"
        - ""
        - "&#22FF00Settings:"
        - "&#22FF00⚑ &fBorder: &#22FF00{border} x {border}"
        - "&#FFE300♻ &fKeep Inventory: &#FFE300{keep-inventory}"
        - "&#55FFFF♟ &fPlayers in World: &#22FF00{players-in-world}"
        - ""
        - "&#FFE300▸ CLICK To Teleport"
    NETHER:
      DISPLAY-NAME: "&#FF3939ɴᴇᴛʜᴇʀ"
      MATERIAL: "NETHERRACK"
      SLOT: 13
      WORLD: "world_nether"
      ENABLED: true
      LORE:
        - "&7Description"
        - ""
        - "&#FF3939Information:"
        - "&fDrops you at a random spot in the &#FF3939Nether"
        - "&fAnywhere between &#FF3939{min-distance} &fand &#FF3939{max-distance} &fblocks away"
        - ""
        - "&#FF3939Settings:"
        - "&#22FF00⚑ &fBorder: &#22FF00{border} x {border}"
        - "&#FFE300♻ &fKeep Inventory: &#FFE300{keep-inventory}"
        - "&#55FFFF♟ &fPlayers in World: &#22FF00{players-in-world}"
        - ""
        - "&#FFE300▸ CLICK To Teleport"
    THE_END:
      DISPLAY-NAME: "&#E0DC8Cᴛʜᴇ ᴇɴᴅ"
      MATERIAL: "END_STONE"
      SLOT: 15
      WORLD: "world_the_end"
      ENABLED: true
      LORE:
        - "&7Description"
        - ""
        - "&#E0DC8CInformation:"
        - "&fDrops you at a random spot in the &#E0DC8CEnd"
        - "&fAnywhere between &#E0DC8C{min-distance} &fand &#E0DC8C{max-distance} &fblocks away"
        - ""
        - "&#E0DC8CSettings:"
        - "&#22FF00⚑ &fBorder: &#22FF00{border} x {border}"
        - "&#FFE300♻ &fKeep Inventory: &#FFE300{keep-inventory}"
        - "&#55FFFF♟ &fPlayers in World: &#22FF00{players-in-world}"
        - ""
        - "&#FFE300▸ CLICK To Teleport"

  # Sub-menu shown after clicking a dimension. Lists every backend server on the
  # network that offers that dimension, with region detection and live ping/players.
  SERVER-MENU:
    TITLE: "&8sᴇʟᴇᴄᴛ sᴇʀᴠᴇʀ"
    SIZE: 27
    PLACEHOLDER: false
    DECORATION-BUTTON:
      DISPLAY-NAME: ""
      LORE:
        - ""
    # Slots the server buttons are placed into, in order.
    SLOTS: [10, 11, 12, 13, 14, 15, 16]
    BUTTON:
      DISPLAY-NAME: "&#22FF00{region}"
      # Default material when no region material matches.
      MATERIAL: "PAPER"
      LORE:
        - "&fClick to randomly teleport"
        - ""
        - "&7Server: &#FF0000{server}"
        - "&7Players: &#FF0000{players}"
        - "&7Ping: &#FF0000{ping}ms"
    # When true {region} shows a clean region name (Asia/Europe/...); when false it shows the raw server name.
    REGION-DISPLAY: true
    # When true, every server button in the sub-menu uses the SAME material as the dimension button
    # in the main menu (e.g. Overworld -> GRASS_BLOCK), ignoring REGION-MATERIALS / BUTTON.MATERIAL below.
    USE-DIMENSION-MATERIAL: false
    # Per-region materials. Region is detected from the server name keywords.
    REGION-MATERIALS:
      asia: "YELLOW_CONCRETE"
      europe: "BLUE_CONCRETE"
      north-america: "RED_CONCRETE"
      south-america: "LIME_CONCRETE"
      oceania: "CYAN_CONCRETE"
      africa: "ORANGE_CONCRETE"
      middle-east: "PURPLE_CONCRETE"
      unknown: "PAPER"

# /rtpqueue — matches two searching players and teleports them
# to the same random overworld spot together.
RTP-QUEUE:
  ENABLED: true
  # Distance in blocks between the two matched players.
  PARTNER-DISTANCE: 3
  # Warmup counted down for BOTH matched players before they are teleported.
  # It is cancelled by moving or taking damage (uses SETTINGS.CANCEL-ON-MOVE / CANCEL-ON-DAMAGE),
  # and a cancel by either player aborts the teleport for both. 0 = teleport instantly.
  WARMUP: 3 # In seconds
  # Cooldown before /rtpqueue can be used again after a successful queue teleport.
  # Counted on the server the player ends up on. rtp.bypass.cooldown skips it.
  COOLDOWN: 30 # In seconds
  # Broadcast QUEUE-BROADCAST-JOIN in chat when someone begins waiting.
  BROADCAST-ON-JOIN: true
  # Whether the joining player also receives their own broadcast.
  BROADCAST-INCLUDE-SELF: false
  # Sounds. Accepts a namespaced key ("minecraft:entity.player.levelup") or a Bukkit Sound enum
  # ("ENTITY_PLAYER_LEVELUP"). Empty = no sound.
  QUEUE-JOINED-SOUND: "ENTITY_EXPERIENCE_ORB_PICKUP"
  MATCH-FOUND-SOUND: "ENTITY_PLAYER_LEVELUP"
  TELEPORT-SUCCESS-SOUND: "ENTITY_ENDERMAN_TELEPORT"
  # Played on every warmup second.
  WARMUP-SOUND: ""
  # Played when the warmup is cancelled.
  WARMUP-CANCELLED-SOUND: "ENTITY_VILLAGER_NO"

  # Animated action bar shown while a player is waiting for a match.
  # {dots} cycles through FRAMES every INTERVAL-TICKS (20 ticks = 1 second).
  SEARCHING-ACTION-BAR:
    ENABLED: true
    TEXT: "&7Searching for player{dots}"
    FRAMES:
      - "."
      - ".."
      - "..."
    INTERVAL-TICKS: 10

  # One random music disc from SOUNDS is played only to the waiting player. It is
  # attached to that player, follows them, and stops on leave/match/failure/quit.
  # Accepts namespaced sounds or Bukkit enums. Add/remove list entries freely.
  SEARCHING-MUSIC:
    ENABLED: true
    SOUNDS:
      - "MUSIC_DISC_WAIT"
      - "MUSIC_DISC_MELLOHI"
      - "MUSIC_DISC_CHIRP"
    VOLUME: 1.0
    PITCH: 1.0

# Stores which dimensions each player has unlocked, so unlocks
# are shared between all your servers. When disabled, unlocks
# are saved to a local file instead.
# TYPE: MARIADB, MYSQL, POSTGRESQL or SQLITE.
# SQLITE needs no HOST/PORT/USERNAME/PASSWORD, only FILE.
DATABASE:
  ENABLED: false
  TYPE: "MARIADB"
  HOST: ""
  PORT: 3306 # PostgreSQL default is 5432
  DATABASE: ""
  USERNAME: ""
  PASSWORD: ""
  # Only used when TYPE is SQLITE.
  FILE: "unlocks.db"

# Cross-server RTP. Requires Redis, and the included
# RTP-Velocity plugin installed on every proxy.
NETWORK:
  # Enable cross-server RTP. When false the plugin is single-server only.
  ENABLED: false
  # redis -> cross-server. none -> single server.
  MODE: "redis"
  # This backend's unique name (must match the name in your proxy config).
  SERVER-NAME: "server1"
  DEBUG: false
  # Only required for MULTI-proxy setups. Address players use to reach THIS server's proxy.
  PROXY-HOST: ""
  PROXY-PORT: 25565
  REDIS:
    HOST: "127.0.0.1"
    PORT: 6379
    USERNAME: "default"
    PASSWORD: ""
    USE-SSL: false
    CHANNEL-PREFIX: "rtp:"