Astral Realms Documentation Help

Placeholders

AstralHomes exposes placeholders through AstralCore's standard %namespace_key_subkey% system — see Placeholders for the base syntax (%a_b_c%, %a_{b_c}%, $e(...)) and the ComplexPlaceholder sub-key mechanism (switch (context.next()): each case is a reachable sub-key, and a case that returns another ComplexPlaceholder lets the chain continue into it).

Two registration styles are used:

  • Root-registeredHomePlaceholders (namespace homes) is registered once, globally, on RootPlaceholderContainer during onEnable. %homes_*% therefore resolves anywhere AstralCore evaluates a placeholder (menus, dialogs, etc.), not just inside AstralHomes messages.

  • Message-scopedHome and Warp are ComplexPlaceholders in their own right, but nothing registers them globally. Each service call builds a fresh PlaceholderContainer (via AstralPaperAPI.createPlaceholderContainer(player) or new PlaceholderContainer()) and seeds it with the specific Home/Warp /target player for that one message, immediately before calling HomesMessages.<KEY>.message(player, container). These tokens only resolve inside the message they were built for.

homes_* (root)

Registered by HomePlaceholders. Both keys require the container's context to be a Player — outside a player context (context.context() is not a Player) both yield null.

Placeholder

Type

Description

%homes_homes%

ItemProvider<Home>

this.plugin.homes().findByPlayer(player.getUniqueId()) wrapped in an ItemProvider — the viewing player's own homes. Use as a layout provider: to list homes in a menu, e.g. the homes GUI.

%homes_tpRequestsEnabled%

Boolean

HomePlayerData.teleportationRequestEnabled for the player, via SyncAPI.findData. false if no player data is found.

ItemProvider itself is a ComplexPlaceholder (namespace items) with its own sub-keys — size, max-index, at_<index> (each yielding a Home, chainable into %home_*%), iterator, list:

layouts: homes: provider: "%homes_homes%"

home_*

A Home placeholder (namespace home). Seeded fresh into the message container by HomeService whenever a home-related message is sent — see Homes.

Placeholder

Type

Description

%home_name%

String

The home's name.

%home_location%

NetworkLocation

The home's location — a bare reference is the object itself; chain into the sub-keys below.

%home_location_x%/%home_location_y%/%home_location_z%

int

Coordinates, truncated to int (NetworkLocation.get() casts (int) x/y/z).

%home_location_yaw%/%home_location_pitch%

float

Look direction.

%home_location_world%

String

World name on the owning server.

%home_location_serverId%

UUID

The network server the home is on — this is what makes a home teleport cross-server aware.

Messages that carry these: HOME_CREATED (%home_name%, %home_location_x%, %home_location_y%, %home_location_z%), HOME_DELETED/HOME_TELEPORT_SUCCESS/HOME_TELEPORT_FAILURE (%home_name% only).

warp_*

A Warp placeholder. Seeded fresh into the message container by WarpCommand/WarpService whenever a warp-related message is sent — see Warps & Spawn.

Sub-key

Type

Description

id

UUID

Primary key.

name

String

Warp name, as typed to /warp set.

group

String

Server group the warp routes to (server_group column).

x/y/z

double

Coordinates — not cast to int, unlike %home_location_x/y/z%.

yaw/pitch

float

Look direction.

world

String

World name on the owning server.

Messages authored to carry these: WARP_CREATED (%warp_name%, %warp_x%, %warp_y%, %warp_z%), WARP_REMOVED/WARP_TELEPORT_SUCCESS/WARP_TELEPORT_FAILURE (%warp_name% only). NO_SPAWN_SET, SPAWN_TELEPORT_SUCCESS, and SPAWN_TELEPORT_FAILURE carry no placeholders.

Direct message tokens

Tokens registered ad hoc, per message, via registerDirect(namespace, value) (which always honors the given namespace) rather than through a model's own ComplexPlaceholder.

Placeholder

Type

Description

%target_name%

String

The other party in a teleport request — registerDirect("target", new MinecraftPlayerPlaceholder(target)). target is a full MinecraftPlayerPlaceholder (namespace player, redirected to target), so %target_uuid%, %target_online%, %target_head%, and %target_loaded% are also reachable, though only %target_name% is used in messages.yml.

%player_name%

String

The acting player's name — from the core player_* placeholder that AstralPaperAPI.createPlaceholderContainer(player) auto-registers for its owner, not something AstralHomes registers itself. In the _other request messages (sent to the other party), the container's owner is the player who just acted (accepted/declined/cancelled), so %player_name% reads as "the player who did this".

%limit%

int

The player's configured home limit — new PlaceholderContainer().registerDirect("limit", maxHomes). Carried only by HOME_LIMIT_REACHED.

%time%

String

Human-readable warmup duration (DurationParser.toHumanReadable(duration)). Carried only by WARMUP_STARTED.

<player> seen in several request messages (request-sent, request-received, request-expired, here-request-received) is a MiniMessage tag, not a %...% token — it is resolved separately from the placeholder system documented on this page.

Where each token is registered

Message key(s)

Container built by

Namespace(s) available

HOME_CREATED

HomeService.set

home (+ core player)

HOME_DELETED

HomeService.delete

home

HOME_TELEPORT_SUCCESS/HOME_TELEPORT_FAILURE

HomeService.teleport

home (+ core player)

HOME_LIMIT_REACHED

HomeService.set

limit

WARP_CREATED/WARP_REMOVED

WarpService.set/delete

warp-keyed object (see warning above) (+ core player)

WARP_TELEPORT_SUCCESS/WARP_TELEPORT_FAILURE

WarpCommand.onDefault

warp-keyed object (see warning above) (+ core player)

WARMUP_STARTED

WarmupService.warmup

time (+ core player)

REQUEST_*, HERE_REQUEST_*, REQUESTS_DISABLED, REQUEST_ALREADY_PENDING

TeleportationRequestService

target (+ core player) — see Teleport Requests

Every container above is built with AstralPaperAPI.createPlaceholderContainer(player) unless noted otherwise (HOME_LIMIT_REACHED and HOME_DELETED use a bare new PlaceholderContainer(), so they don't carry the core player_* namespace or the PlaceholderAPI fallback).

REQUEST_NO_PENDING's %target_name% is not always backed by a container: cancelLastRequest and the single-argument overload of sendResponse both send it via HomesMessages.REQUEST_NO_PENDING.message(player) (no parser at all) when no pending request is found, versus the other call sites, which pass a target-seeded container. MessageEnum.message(Audience) with no parser sends the raw component unprocessed, so %target_name% prints literally in that path.

Last modified: 25 July 2026