Warp Rules

Configure teleport costs and other effects and limitations on teleportation.

Waystones now uses Shogi for configuring warp rules.

The warpRequirements option now lives in the rules config category and uses Shogi syntax. If you are migrating an older config, see the migration guide below for the syntax changes.

Warp Settings

The warpSettings option is a simpler layer that is evaluated before warpRequirements. Use it for variables that tune the default rules without replacing the full rule list.

The default settings are:

$xp_per_block = 0.01
$min_xp_cost = 0
$max_xp_cost = 27
$interdimensional_xp_cost = 27
$inventory_button_cooldown = '300s'

For example, changing $xp_per_block adjusts distance-based XP cost, and changing $inventory_button_cooldown adjusts the inventory button cooldown.

These settings only matter if your warpRequirements reference them. If you previously customized warpRequirements, reset it to the new default and re-apply your changes if you want warpSettings to take effect.

Current Defaults

The default rules.warpRequirements value is:

$uses_xp #= and(any(source(is_waystone), source(is_warp_stone)), not(target(is_fleeting_memorial)))
$uses_xp -> $xp_points_cost = $distance * $xp_per_block
$uses_xp + is_interdimensional -> $xp_points_cost = $interdimensional_xp_cost
$uses_xp -> $xp_points_cost = clamp($xp_points_cost, 0, $max_xp_cost)
is_warp_stone -> damage_item(80)
is_inventory_button -> cooldown_cost('inventory_button', $inventory_button_cooldown)

This means XP costs apply to regular waystone travel and warp stones by default, while scrolls and other methods do not use the default XP cost unless your rules add one.

Waystones-Specific Conditions and Wrappers

FunctionDescription
source(...)Evaluates the nested effect or condition against the source waystone.
target(...)Evaluates the nested effect or condition against the target waystone.
name_equals('name')Checks whether the current effective waystone name exactly matches the given string.
name_contains('text')Checks whether the current effective waystone name contains the given text.
is_dimension('namespace:path')Checks whether the current effective waystone dimension matches the given dimension.
involves_dimension('namespace:path')Checks whether either the source or target side of the warp is in the given dimension.
is_within_distance(number)Checks whether the target waystone is within the given straight-line distance.
is_interdimensionalChecks whether the warp crosses dimensions.
is_warp_plateChecks whether the effective waystone is a warp plate.
is_portstoneChecks whether the warp was initiated from a portstone.
is_waystoneChecks whether the effective waystone is a regular waystone.
is_sharestoneChecks whether the effective waystone is any sharestone.
is_inventory_buttonChecks whether the warp was initiated from the inventory button.
is_scrollChecks whether the warp item is any scroll.
is_bound_scrollChecks whether the warp item is a bound scroll.
is_return_scrollChecks whether the warp item is a return scroll.
is_warp_scrollChecks whether the warp item is a warp scroll.
is_portal_scrollChecks whether the warp item is a portal scroll.
is_warp_stoneChecks whether the warp item is a warp stone.
is_globalChecks whether the effective waystone is global.
is_ownerChecks whether the player using the warp owns the effective waystone.
has_ownerChecks whether the effective waystone has an owner.
is_with_petsChecks whether the teleporting entity has pets that would come along.
is_with_passengersChecks whether the teleporting entity has passengers.
is_with_leashedChecks whether the teleporting entity has leashed mobs.
is_warp_portalChecks whether the effective waystone is a warp portal.
is_fleeting_memorialChecks whether the effective waystone is a fleeting memorial.
is_twinboundChecks whether the effective waystone is a Twinbound Feather target.

Sharestone variants: is_amethyst_sharestone, is_copper_sharestone, is_diamond_sharestone, is_emerald_sharestone, is_gold_sharestone, is_lapis_sharestone, is_prismarine_sharestone, is_redstone_sharestone, is_ruined_sharestone

Context Variables

VariableDescription
$distanceStraight-line distance from the entity to the target waystone.
$leashedNumber of leashed mobs included in the teleport.
$petsNumber of pets included in the teleport.
$passengersNumber of passengers included in the teleport.
$ownerUsername of the effective waystone owner, when known.
$ownerIdUUID of the effective waystone owner, when known.

Common Built-In Shogi Effects

Waystones also supports Shogi's built-in effects. The following ones are the most useful for writing warp rules.

EffectDescription
if(condition = ..., then = ..., else = ...)Evaluates the given condition and returns either the then or else value or effect result.
clamp(value, min, max)Clamps a numeric value to the specified minimum and maximum.
clamp_min(value, min)Enforces a minimum value without changing larger values.
clamp_max(value, max)Enforces a maximum value without changing smaller values.
xp_points_cost(xp)Charges the specified amount of XP points if the overall rule evaluation succeeds.
xp_level_cost(level)Charges the specified amount of XP levels if the overall rule evaluation succeeds.
item_cost('namespace:path', count)Requires and consumes the specified item count if the overall rule evaluation succeeds.
damage_item(amount)Damages the triggering warp item, such as a warp stone, by the specified amount.
cooldown_cost('id', 'duration')Applies a blocking cooldown that can refuse later warps until it expires.
add_cooldown('id', 'duration')Applies a non-blocking cooldown marker that later rules can check.
refuse('message')Stops the warp and shows the player the specified message.
dismount()Forces the teleporting entity to dismount before teleporting.

Generic Shogi conditions and advanced built-ins are intentionally not duplicated here. For inventory, biome, block, vehicle, cooldown, and other generic checks, refer to the Shogi documentation.

Migration to Shogi

Syntax Changes

Legacy warpRequirements lines use this format:

[conditions] modifier(args)

The new rules.warpRequirements option uses Shogi syntax instead:

condition -> effect(...)
condition1 + condition2 -> effect(...)
condition1, condition2 -> effect(...)
!condition -> effect(...)
  • + means AND.
  • , means OR.
  • ! negates a condition.

Legacy bracketed condition lists were AND, not OR. In other words, [condition1, condition2] modifier() becomes condition1 + condition2 -> effect(...), not condition1, condition2 -> effect(...).

Negated legacy aliases also become explicit negation:

  • is_not_interdimensional -> !is_interdimensional
  • source_is_not_waystone -> !source(is_waystone())

Source and target conditions move into wrappers:

  • source_is_* -> source(is_*())
  • target_is_* -> target(is_*())

Checks that refer to the teleport item or button become direct conditions without source(...):

  • source_is_warp_stone -> is_warp_stone
  • source_is_inventory_button -> is_inventory_button
  • source_is_scroll -> is_scroll

String-like values should be quoted:

  • messages
  • waystone names
  • dimensions
  • item ids
  • cooldown ids
  • durations

Durations should use Shogi duration syntax such as '300s'.

Old vs New Defaults

The default 1.21.1 teleports.warpRequirements value is:

[is_not_interdimensional] scaled_add_xp_cost(distance, 0.01)
[is_interdimensional] add_xp_cost(27)
[source_is_warp_plate] multiply_xp_cost(0)
[source_is_warp_stone] add_durability_cost(80)
[target_is_global] multiply_xp_cost(0)
min_xp_cost(0)
max_xp_cost(27)
[source_is_inventory_button] add_cooldown(inventory_button, 300)

The default rules.warpRequirements value is:

$uses_xp #= any(source(is_waystone), source(is_warp_stone))
$uses_xp -> $xp_points_cost = $distance * $xp_per_block
$uses_xp + is_interdimensional -> $xp_points_cost = $interdimensional_xp_cost
$uses_xp -> $xp_points_cost = clamp($xp_points_cost, 0, $max_xp_cost)
is_warp_stone -> damage_item(80)
is_inventory_button -> cooldown_cost('inventory_button', $inventory_button_cooldown)

Old Conditions To New Conditions

Legacy conditionShogi condition
is_interdimensionalis_interdimensional
is_not_interdimensional!is_interdimensional
source_is_warp_platesource(is_warp_plate())
source_is_waystonesource(is_waystone())
source_is_sharestonesource(is_sharestone())
source_is_portstoneis_portstone
source_is_inventory_buttonis_inventory_button
source_is_scrollis_scroll
source_is_bound_scrollis_bound_scroll
source_is_return_scrollis_return_scroll
source_is_warp_scrollis_warp_scroll
source_is_portal_scrollis_portal_scroll
source_is_warp_stoneis_warp_stone
target_is_warp_platetarget(is_warp_plate())
target_is_waystonetarget(is_waystone())
target_is_sharestonetarget(is_sharestone())
target_is_globaltarget(is_global())
target_is_warp_portaltarget(is_warp_portal())
target_is_fleeting_memorialtarget(is_fleeting_memorial())
target_is_playertarget(is_twinbound())
source_name_equals(Foo)source(name_equals('Foo'))
source_name_contains(Foo)source(name_contains('Foo'))
target_name_equals(Foo)target(name_equals('Foo'))
target_name_contains(Foo)target(name_contains('Foo'))
source_is_dimension(minecraft:the_end)source(is_dimension('minecraft:the_end'))
target_is_dimension(minecraft:the_end)target(is_dimension('minecraft:the_end'))
involves_dimension(minecraft:the_end)involves_dimension('minecraft:the_end')
is_within_distance(100)is_within_distance(100)
has_cooldown(inventory_button)has_cooldown('inventory_button')
has_cooldown_above(inventory_button, 60)is_cooldown_above('inventory_button', '60s')
Any *_not_* or not_* aliasUse ! with the positive Shogi condition

Old Modifiers And Effects To New Effects

Direct Mappings

Legacy modifierShogi equivalent
refuse(message)refuse('message')
dismount()dismount()
add_cooldown(id, seconds)cooldown_cost('id', '<seconds>s')
add_soft_cooldown(id, seconds)add_cooldown('id', '<seconds>s')

XP Point Cost Patterns

Legacy modifierShogi pattern
add_xp_cost(n)$xp_points_cost = $xp_points_cost + n
multiply_xp_cost(n)$xp_points_cost = $xp_points_cost * n
scaled_add_xp_cost(distance, s)$xp_points_cost = $xp_points_cost + $distance * s
scaled_multiply_xp_cost(distance, s) or legacy typo variants$xp_points_cost = $xp_points_cost * $distance * s
min_xp_cost(n)$xp_points_cost = clamp_min($xp_points_cost, n) or clamp(...)
max_xp_cost(n)$xp_points_cost = clamp_max($xp_points_cost, n) or clamp(...)

XP Level Cost Patterns

Legacy modifierShogi pattern
add_level_cost(n)$xp_level_cost = $xp_level_cost + n
multiply_level_cost(n)$xp_level_cost = $xp_level_cost * n
scaled_add_level_cost(distance, s)$xp_level_cost = $xp_level_cost + $distance * s
scaled_multiply_level_cost(distance, s)$xp_level_cost = $xp_level_cost * $distance * s
min_level_cost(n)$xp_level_cost = clamp_min($xp_level_cost, n) or clamp(...)
max_level_cost(n)$xp_level_cost = clamp_max($xp_level_cost, n) or clamp(...)

Durability Cost Patterns

Legacy modifierShogi pattern
add_durability_cost(n)$damage_item = $damage_item + n
multiply_durability_cost(n)$damage_item = $damage_item * n
scaled_add_durability_cost(distance, s)$damage_item = $damage_item + $distance * s
scaled_multiply_durability_cost(distance, s)$damage_item = $damage_item * $distance * s
min_durability_cost(n)$damage_item = clamp_min($damage_item, n) or clamp(...)
max_durability_cost(n)$damage_item = clamp_max($damage_item, n) or clamp(...)

Item Cost Patterns

Legacy modifierShogi pattern
add_item_cost(minecraft:diamond, n)$diamond_cost = $diamond_cost + n then item_cost('minecraft:diamond', $diamond_cost)
multiply_item_cost(minecraft:diamond, n)$diamond_cost = $diamond_cost * n then item_cost('minecraft:diamond', $diamond_cost)
scaled_add_item_cost(distance, minecraft:diamond, s)$diamond_cost = $diamond_cost + $distance * s then item_cost('minecraft:diamond', $diamond_cost)
scaled_multiply_item_cost(distance, minecraft:diamond, s)$diamond_cost = $diamond_cost * $distance * s then item_cost('minecraft:diamond', $diamond_cost)
min_item_cost(minecraft:diamond, n)$diamond_cost = clamp_min($diamond_cost, n) then item_cost('minecraft:diamond', $diamond_cost)
max_item_cost(minecraft:diamond, n)$diamond_cost = clamp_max($diamond_cost, n) then item_cost('minecraft:diamond', $diamond_cost)

Cooldown Patterns

Legacy modifierShogi pattern
multiply_cooldown(id, n)$cooldown_duration = $cooldown_duration * n then cooldown_cost('id', $cooldown_duration)
scaled_add_cooldown(id, distance, s)$cooldown_duration = $cooldown_duration + $distance * s then cooldown_cost('id', $cooldown_duration)
scaled_multiply_cooldown(id, distance, s)$cooldown_duration = $cooldown_duration * $distance * s then cooldown_cost('id', $cooldown_duration)
min_cooldown(id, n)$cooldown_duration = clamp_min($cooldown_duration, '<n>s') or clamp(...), then cooldown_cost('id', $cooldown_duration)
max_cooldown(id, n)$cooldown_duration = clamp_max($cooldown_duration, '<n>s') or clamp(...), then cooldown_cost('id', $cooldown_duration)
multiply_soft_cooldown(id, n)$cooldown_duration = $cooldown_duration * n then add_cooldown('id', $cooldown_duration)
scaled_add_soft_cooldown(id, distance, s)$cooldown_duration = $cooldown_duration + $distance * s then add_cooldown('id', $cooldown_duration)
scaled_multiply_soft_cooldown(id, distance, s)$cooldown_duration = $cooldown_duration * $distance * s then add_cooldown('id', $cooldown_duration)
min_soft_cooldown(id, n)$cooldown_duration = clamp_min($cooldown_duration, '<n>s') or clamp(...), then add_cooldown('id', $cooldown_duration)
max_soft_cooldown(id, n)$cooldown_duration = clamp_max($cooldown_duration, '<n>s') or clamp(...), then add_cooldown('id', $cooldown_duration)