Waypoint Configuration
Author attunable fast-travel shrines — the interactable block that makes one, and the registry a milestone's waypoint reward resolves against.
An attunable waypoint is a shrine a player discovers, interacts with, and thereafter can travel back to. Attuning is the reward; the travel itself is the recall item’s existing interruptible channel, redirected to whichever waypoint the player has picked on the world map.
There are two halves to authoring one, and most content only needs the first:
- The shrine itself — a
waypoint:block on an interactable. Interacting with it attunes it. This is all a normal shrine needs, and it is the only form that works for a shrine placed by world generation. - The registry (
waypoint-config.yaml) — a table of fixed sites with known coordinates, so an Almanac milestone whose reward isfamily: waypointhas something to resolve its id to.
How attunement works
- A player interacts with a shrine within its
interact-range. If the shrine is behind an access lock, the lock is checked first — a denied interaction attunes nothing. - The attunement records the player’s own position, not the shrine’s. A waypoint returns the player to a spot they were already standing in, which is by construction somewhere they fit; a shrine’s own origin may sit inside its hitbox.
- Attunements are per player and saved with them. Two players in one world attune independently, and a joiner arrives with none.
- Re-interacting with a shrine already attuned refreshes its recorded position rather than adding a second entry.
- The shrine gives no built-in feedback beyond the map updating. If you want a visible or audible response, add it in the shrine’s own
server-on-interactscript (see Lua Hooks) or by changing its state.
The player then opens the world map, where every attunement appears in a travel list (and, for the world being drawn, as a marker). Picking one only sets a destination — nothing teleports. The next time the player uses their recall item, the channel completes at that waypoint instead of at home. Picking the already-selected entry again clears it, and recall goes back to home.
Because the destination is spent by the recall channel, waypoint travel inherits that channel’s rules: it takes time, and taking a hit interrupts it.
Making an interactable a shrine
Add a waypoint: block to an entry in your interactable-config.yaml:
interactables:
- name: TODO_NAME
hitbox:
width: 2.0
height: 3.0
breakable: false
waypoint:
id: TODO_NAME
display-name: TODO_NAME
| Field | Required | Description |
|---|---|---|
id | yes | Stable identifier for the site, namespaced to <mod>:<id> internally. This is what a player’s attunement set records, and what a milestone reward names. See Id rules below. |
display-name | yes | What the player reads for this site on the world map. Required — without it the map would have to fall back to the raw id, which is an internal identifier and not written to be read. |
There is deliberately no position here: the position comes from the player at attune time, which is what lets the same shrine be placed anywhere, including by world generation.
breakable: false is not required but is usually right — a fast-travel target that can be mined away is a trap.
Two shrines, one attunement
Two interactables may share an id on purpose: attuning either one attunes the same entry, and the most recently touched position wins. Use it when one logical destination has several physical approaches.
The waypoint registry
A milestone reward carries only an id, so a site granted that way needs its world, position and name declared up front. That is what waypoint-config.yaml is for. A procedurally-placed shrine cannot be granted this way — nothing knows where it is until the world generates — so a milestone-granted waypoint has to be an authored, fixed site.
Register the file in your mod’s manifest (mods/<YourMod>/<YourMod>.yaml):
waypoint-config: waypoint-config.yaml
Then create the file it points to, relative to your mod’s folder:
waypoints:
- id: TODO_NAME
world: Genesis
position:
x: 1280
y: -64
display-name: TODO_NAME
| Field | Required | Description |
|---|---|---|
id | yes | The site’s id, matching the waypoint.id on its interactable if it has one. Namespaced to <mod>:<id>. |
world | yes | The world the site is in, as named in the world registry. |
position | yes | A { x, y } map of block coordinates the player arrives at. Nested rather than two sibling keys so a half-specified location is a load error instead of a silent (0, 0). |
display-name | yes | What the player reads for this site on the world map. |
Unknown keys are rejected: a misspelled field is a load-time error naming the bad key, not a silently-ignored one.
A duplicate id fails the second entry — otherwise which one a reward resolved to would depend on load order.
Paying one out from a milestone
With the site registered, an Almanac milestone can grant it:
milestones:
- id: TODO_NAME
chapter: discoveries
metric: worlds
threshold: 3
reward:
family: waypoint
id: TODO_NAME # the registry id above
The grant is applied on the player’s next tick, and is idempotent — a reward already attuned does nothing. A reward naming a site no waypoint-config.yaml declares is logged as a warning and stays recorded, so it applies later if the entry is added.
Id rules
A mod may only declare waypoint ids in its own namespace. Writing id: OtherMod:their_shrine in your config is a load-time error, in both the interactable block and the registry — otherwise a mod could declare a site under another mod’s namespace and have its own shrine satisfy that mod’s reward. Referring to another mod’s waypoint is fine; declaring one is not.
A bare id: shrine_a in mod Creation becomes Creation:shrine_a. Writing that qualified form yourself is allowed and is not double-prefixed.
Complete Example
interactable-config.yaml:
interactables:
- name: TODO_NAME
hitbox:
width: 2.0
height: 3.0
requires-supporting-blocks: true
breakable: false
interact-range: 6.0
light:
magnitude: 8.0
color: [180, 240, 200]
waypoint:
id: TODO_NAME
display-name: TODO_NAME
scripts:
server-on-interact: /interactables/waypoint-shrine/scripts/server_interact.lua
waypoint-config.yaml:
waypoints:
- id: TODO_NAME
world: Genesis
position:
x: 1280
y: -64
display-name: TODO_NAME
Last updated