Nexal RTP
Free random teleport plugin with biome selection, configurable presets, safe location finding, and hooks for GriefPrevention, Factions, and WorldGuard. Designed to drive exploration while keeping your server safe from griefing.
Features
- Random Teleportation:
/rtpteleports players to a random safe location using configurable presets called "places". - RTP Presets (Places): Admins define named places (e.g. Wilderness, Nether, Resource World) each with their own world, radius, cooldown, cost, and biome filter.
- Place Selection GUI:
/rtpopens a menu with the player's own info on top (total RTPs, last RTP, places ready), glass accents in the corners, and the places centered seven to a row, over several pages when there are many. Each place shows its world, distance, cost and cooldown, and one state: ✔ Ready (with an enchanted glint), ✘ on cooldown with the time left counting down live, ✘ too expensive with the player's balance, or ✘ locked with the permission it needs. Clicking a place that is not ready says why and keeps the menu open. Places without their own icon get one for their world type (overworld, nether, end, custom). Every text, material and sound is in theplace-guisection ofmessages.yml. - Biome Selection: Each place can optionally restrict teleport destinations to specific biomes (FOREST, PLAINS, OCEAN, etc.), checked where the player would stand.
- Lag-Free Safe Location Search: The search tries one spot per tick instead of loading dozens of chunks at once, and loads chunks asynchronously on Paper. Players land on solid ground only: never in or under water, in lava, over the void, or on cactus, magma, fire, powder snow or berry bushes. World border bounds are respected.
- Cooldowns: Per-player, per-place cooldowns with permission-based bypass (
nexalrtp.bypass.cooldown). - Teleport Warmup: Configurable warmup timer with action bar countdown and particle effects. Cancels if the player moves.
- Economy Integration: Optional per-place cost via Vault, charged when the player arrives. Players see the cost in the GUI; bypass permission available.
- GriefPrevention Hook: Optionally avoids landing inside claimed land (soft dependency).
- Factions Hook: Optionally avoids landing in faction territory (soft dependency).
- WorldGuard Hook: Optionally avoids landing inside any WorldGuard region (soft dependency).
- World Border Respect: Only generates coordinates within the world's configured border.
- Admin RTP Others:
/rtp admin teleport \<player> [place]to force-RTP another player, bypassing all checks, and reports whether they arrived. - Admin GUI:
/rtp adminopens a menu to edit the plugin settings (default behaviour, warmup, water landing, attempts, hooks) and every place (radius, cooldown, cost, attempts, center, permission, biomes) without touching YAML. - Admin Place Management: Create and delete places in-game with
/rtp admin createand/rtp admin delete, or delete them from the admin GUI. - PlaceholderAPI Integration: Placeholders for total RTPs, per-place cooldowns, and teleport status.
- Dual Storage (JSON + SQL): All player data stored in JSON or MySQL/MariaDB, written off the main thread, with export/import commands.
- Full Message Customization: All messages in
messages.ymlwith MiniMessage gradient colors and sounds.
Technologies
- Paper API 1.20.1+: Minecraft server API (Spigot compatible)
- Utilizer: Configuration, messages, items, tasks, GUI system
- ACF: Annotation-based command framework
- nexal-core: JSON and SQL persistence (MariaDB/MySQL)
- PlaceholderAPI: Placeholder integration (optional)
- Vault: Economy integration (optional)
- GriefPrevention: Claim avoidance (optional)
- Factions: Territory avoidance (optional, FactionsUUID)
- WorldGuard: Region avoidance (optional)
Commands
Player Commands
| Command | Description | Permission |
|---|---|---|
/rtp | Open RTP GUI or teleport to default place | nexalrtp.use |
/rtp \<place> | Teleport to a specific RTP place | nexalrtp.use |
/rtp help | Show help menu | None |
Admin Commands
| Command | Description | Permission |
|---|---|---|
/rtp admin | Open the admin menu (settings and places); shows the admin help from the console | nexalrtp.admin |
/rtp admin help | Show admin help | nexalrtp.admin |
/rtp admin reload | Reload configuration | nexalrtp.admin |
/rtp admin teleport \<player> [place] | RTP another player, then report whether they arrived | nexalrtp.admin |
/rtp admin create \<name> | Create a new RTP place centered where you stand (letters, digits, - and _) | nexalrtp.admin |
/rtp admin delete \<name> | Delete an RTP place | nexalrtp.admin |
/rtp admin export | Export data to JSON | nexalrtp.admin |
/rtp admin import | Import data from JSON | nexalrtp.admin |
Permissions
| Permission | Description | Default |
|---|---|---|
nexalrtp.use | Basic RTP usage | true |
nexalrtp.gui | Open the RTP GUI | true |
nexalrtp.place.\<name> | Access a specific RTP place | varies |
nexalrtp.place.* | Access all RTP places | op |
nexalrtp.bypass.cooldown | Bypass cooldown | op |
nexalrtp.bypass.cost | Bypass economy cost | op |
nexalrtp.bypass.warmup | Bypass warmup timer | op |
nexalrtp.admin | Admin commands | op |
Placeholders
Requires PlaceholderAPI.
| Placeholder | Description |
|---|---|
%nexalrtp_total% | Player's total RTP count |
%nexalrtp_cooldown_\<place>% | Remaining cooldown for a place (formatted, e.g. "5m 30s") |
%nexalrtp_cooldown_seconds_\<place>% | Remaining cooldown in raw seconds |
%nexalrtp_last_rtp% | Time since last RTP (e.g. "2m 15s ago") |
%nexalrtp_is_teleporting% | Whether the player is currently teleporting ("Yes" or "No") |
Configuration
config.yml
# What /rtp with no arguments does: "gui" or "teleport"
default-behavior: gui
# Which place to use when default-behavior is "teleport"
default-place: wilderness
warmup:
seconds: 3 # Warmup time (0 to disable)
cancel-on-move: true # Cancel if player moves during warmup
action-bar: true # Show countdown on action bar
particle: PORTAL # Particle effect during warmup
safe-location:
allow-water: false # Allow landing on the surface of water (never under it)
max-attempts: 50 # Spots tried per RTP for places without their own max-attempts (one per tick)
hooks:
griefprevention: true # Avoid GriefPrevention claims
factions: true # Avoid Factions territory
worldguard: true # Avoid any WorldGuard region (the global region does not count)
places:
wilderness:
display-name: "<gradient:#2ECC71:#52D68A>\<bold>Wilderness\</bold>\</gradient>"
description: "Teleport to a random location in the wilderness"
material: GRASS_BLOCK # Icon in the /rtp GUI; leave out for the icon of the world type
world: world
center: # Point the radius is measured from
x: 0
z: 0
radius: 5000 # Furthest a player can land from the center, in blocks
min-radius: 200 # Closest a player can land to the center, in blocks
cooldown: 300 # Seconds before the same player can use it again (0 = none)
cost: 0 # Money charged per teleport through Vault (0 = free)
biome-filter: [] # Empty = all biomes; or list specific biomes
max-attempts: 50 # Spots tried; leave out to use safe-location.max-attempts
permission: "" # Required permission (empty = all players)
storage:
type: json # "json" or "sql"
sql:
host: localhost
port: 3306
database: minecraft
username: root
password: ""
messages.yml
All messages are fully customizable with MiniMessage gradient colors, sounds, and titles. The place-gui section holds the /rtp menu: its title, corner glass, icons per world type, locked icon, glint, sounds, header, the lore of each place state (ready, cooldown, too-expensive, locked) and the page and close buttons. Messages missing from an older messages.yml fall back to the built-in ones.
Everything in config.yml except the storage connection, the warmup particle and each place's name, icon and description can also be changed in game through /rtp admin.
Database Schema
When using SQL storage, the plugin creates the following table:
rtp_users
| Column | Type | Key | Description |
|---|---|---|---|
id | VARCHAR(36) | PK | Player UUID as string |
total_rtps | INT | Total number of RTPs performed | |
last_rtp_time | BIGINT | Epoch timestamp of last RTP | |
cooldowns_json | TEXT | JSON map of place → last-use timestamp |
Installation
- Download the plugin JAR
- Place in your server's
/pluginsfolder - Start/restart the server
- Configure
config.ymlto set up your RTP places - Optionally configure
messages.ymlto customize messages - Reload with
/rtp admin reload
Storage Migration
To migrate from JSON to SQL:
- Use
/rtp admin exportto export current data - Change
storage.typetosqlinconfig.yml - Fill in SQL credentials
- Restart the server (the storage backend is chosen at startup, so
/rtp admin reloaddoes not switch it) - Use
/rtp admin importto import the exported data