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-registered —
HomePlaceholders(namespacehomes) is registered once, globally, onRootPlaceholderContainerduringonEnable.%homes_*%therefore resolves anywhere AstralCore evaluates a placeholder (menus, dialogs, etc.), not just inside AstralHomes messages.Message-scoped —
HomeandWarpareComplexPlaceholders in their own right, but nothing registers them globally. Each service call builds a freshPlaceholderContainer(viaAstralPaperAPI.createPlaceholderContainer(player)ornew PlaceholderContainer()) and seeds it with the specificHome/Warp/target player for that one message, immediately before callingHomesMessages.<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 |
|---|---|---|
| ItemProvider<Home> |
|
| Boolean |
|
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:
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 |
|---|---|---|
| String | The home's name. |
| NetworkLocation | The home's location — a bare reference is the object itself; chain into the sub-keys below. |
| int | Coordinates, truncated to |
| float | Look direction. |
| String | World name on the owning server. |
| 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 |
|---|---|---|
| UUID | Primary key. |
| String | Warp name, as typed to |
| String | Server group the warp routes to ( |
| double | Coordinates — not cast to |
| float | Look direction. |
| 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 |
|---|---|---|
| String | The other party in a teleport request — |
| String | The acting player's name — from the core |
| int | The player's configured home limit — |
| String | Human-readable warmup duration ( |
<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 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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.