Available Effects
Control and logic
if(condition, then, else)
Chooses between two branches based on a condition.
if(condition = is_dimension('minecraft:the_nether'), then = 180, else = 220)
$use_time = if(can_see_sky, 20, 60)
not(condition)
Negates a condition. In rule expressions, !condition is usually shorter.
not(is_player) -> failure('Players only')
!is_player -> failure('Players only')
and(...)
Requires every listed condition to match. In expressions, + is the usual syntax.
and(is_player, can_see_sky) -> true
is_player + can_see_sky -> true
any(...)
Matches when any listed condition matches. In expressions, , is the usual syntax.
any(is_dimension('minecraft:the_nether'), is_dimension('minecraft:the_end')) -> 256
is_dimension('minecraft:the_nether'), is_dimension('minecraft:the_end') -> 256
use(identifier)
Imports another named Shogi rule by id.
use('pack:shared_cost_rule')
is_player -> use('pack:player_only_requirement')
Math helpers
clamp(value, min, max)
Keeps a computed value inside a range.
clamp($distance * 0.01, 0, 27)
$xp_cost = clamp($distance * 0.01, 3, 30)
clamp_min(value, min)
Raises a value up to a minimum floor.
clamp_min($height, 64)
$use_time = clamp_min($distance * 0.02, 20)
clamp_max(value, max)
Lowers a value down to a maximum ceiling.
clamp_max($height, 256)
$xp_cost = clamp_max($distance * 0.01, 27)
Context helpers
any_hand(condition)
Checks the player's main hand and offhand against the same nested condition.
any_hand(has_enchantment('minecraft:silk_touch')) -> true
any_hand(is_item('minecraft:ender_pearl')) -> refuse('Put the pearl away first')
offhand(effect)
Evaluates a nested effect using the player's offhand item context.
offhand(is_item('minecraft:totem_of_undying')) -> true
offhand(has_enchantment('minecraft:binding_curse')) -> failure('Your offhand item is cursed')
Entity, player, and item checks
is_player
Matches when the current entity context is a player.
is_player -> true
!is_player -> failure('Players only')
has_entity_tag(tag)
Checks whether the current entity has a given entity tag.
has_entity_tag('example') -> true
has_entity_tag('boss') -> refuse('Bosses cannot use this')
has_mob_effect(effect)
Checks whether the current entity has a matching status effect.
has_mob_effect('minecraft:poison') -> true
has_mob_effect('minecraft:wither') -> failure('You cannot do this while withered')
is_on_any_vehicle
Matches when the current entity is riding something.
is_on_any_vehicle -> dismount
is_on_any_vehicle -> refuse('Dismount first')
is_on_vehicle(vehicle)
Matches when the current entity is riding a specific vehicle type.
is_on_vehicle('minecraft:boat') -> true
is_on_vehicle('minecraft:minecart') -> refuse('Leave the minecart first')
has_item(item, count)
Checks whether the player inventory contains enough matching items. count defaults to 1.
has_item('minecraft:ender_pearl', 2) -> true
!has_item('minecraft:diamond') -> failure('You need a diamond')
has_empty_inventory
Matches when the player inventory is empty.
has_empty_inventory -> true
!has_empty_inventory -> refuse('Empty your inventory first')
is_wearing_any_armor
Matches when the player has any armor equipped.
is_wearing_any_armor -> true
is_wearing_any_armor -> failure('Remove your armor first')
is_item(item)
Checks whether the current item context matches a specific item.
is_item('minecraft:elytra') -> damage_item(1)
offhand(is_item('minecraft:totem_of_undying')) -> refuse('No totems in the offhand')
has_enchantment(enchantment, level)
Checks whether the current item has an enchantment at or above the given level. level defaults to 1.
has_enchantment('minecraft:unbreaking', 3) -> true
any_hand(has_enchantment('minecraft:silk_touch')) -> refuse('Silk Touch is disabled here')
Position and world checks
can_see_sky
Matches when the current block position has direct sky access.
can_see_sky -> true
!can_see_sky -> failure('You need open sky above you')
is_above_y(y)
Matches when the current position is above the given Y value.
is_above_y(200) -> true
is_above_y(200) -> failure('Too high')
is_below_y(y)
Matches when the current position is below the given Y value.
is_below_y(0) -> failure('Too low')
is_below_y(64) -> item_cost('minecraft:torch', 1)
is_at(pos)
Matches one exact block position.
is_at([0, 64, 0]) -> true
is_at([120, 72, -45]) -> refuse('This pad is disabled')
is_near(pos, distance)
Matches when the current position is within range of a target block position.
is_near([0, 64, 0], 8) -> true
is_near([120, 72, -45], 4) -> item_cost('minecraft:emerald', 1)
is_within(bounds)
Matches when the current position is inside a bounding box.
is_within([[0, 60, 0], [100, 90, 100]]) -> true
!is_within([[-32, 0, -32], [32, 320, 32]]) -> failure('Stay near spawn')
is_dimension(dimension)
Matches the current dimension id.
is_dimension('minecraft:the_end') -> 256
is_dimension('minecraft:the_nether') -> refuse('Disabled in the Nether')
is_biome(biome)
Matches the biome at the current position.
is_biome('minecraft:desert') -> true
is_biome('minecraft:deep_dark') -> failure('This is too dangerous here')
is_block(block)
Matches the block at the current position.
is_block('minecraft:respawn_anchor') -> true
is_block('minecraft:gold_block') -> item_cost('minecraft:gold_ingot', 1)
is_block_state_property(property, value)
Checks a block-state property at the current position.
is_block_state_property('powered', 'true') -> true
!is_block_state_property('enabled', 'true') -> refuse('This block is disabled')
is_entity_nearby(entity, distance, min)
Checks whether enough matching entities are within range. min defaults to 1.
is_entity_nearby('minecraft:villager', 24, 1) -> true
is_entity_nearby('minecraft:warden', 48) -> failure('A warden is nearby')
is_animal_nearby(distance, min)
Checks for nearby animals. min defaults to 1.
is_animal_nearby(16, 3) -> true
is_animal_nearby(24, 5) -> item_cost('minecraft:wheat', 1)
is_mob_nearby(distance, min)
Checks for nearby hostile mobs. min defaults to 1.
is_mob_nearby(12, 1) -> failure('Unsafe area')
!is_mob_nearby(16) -> true
is_player_nearby(distance, min)
Checks for nearby players. min defaults to 1.
is_player_nearby(12, 1) -> true
!is_player_nearby(32) -> failure('Another player must be nearby')
is_near_poi(poi, distance)
Checks for a nearby point of interest.
is_near_poi('minecraft:home', 16) -> true
!is_near_poi('minecraft:meeting', 48) -> failure('Find a village meeting point first')
Outcomes, costs, and actions
failure(message)
Returns a failure result with a message.
failure('You need more XP')
!has_item('minecraft:ender_pearl') -> failure('You need an ender pearl')
refuse(message)
Returns a refusal result with a message.
refuse('This teleport source is disabled')
is_dimension('minecraft:the_end') -> refuse('You cannot use this in the End')
dismount
Makes the player stop riding.
is_on_any_vehicle -> dismount
is_on_vehicle('minecraft:boat') -> dismount
damage_item(amount)
Damages the current item stack by a non-negative amount.
damage_item(80)
is_item('minecraft:elytra') -> damage_item(1)
item_cost(item, count)
Consumes matching items from the player inventory. count defaults to 1.
item_cost('minecraft:ender_pearl', 1)
is_dimension('minecraft:the_nether') -> item_cost('minecraft:gold_ingot', 4)
xp_points_cost(xp)
Charges raw experience points from the player.
xp_points_cost(12)
is_below_y(0) -> xp_points_cost(30)
xp_level_cost(level)
Charges whole experience levels from the player.
xp_level_cost(3)
is_dimension('minecraft:the_end') -> xp_level_cost(5)
has_advancement(advancement)
Checks whether the player has completed an advancement.
has_advancement('minecraft:story/mine_diamond') -> true
!has_advancement('minecraft:nether/root') -> failure('Enter the Nether first')
has_cooldown(identifier)
Checks whether a named Shogi cooldown currently exists.
has_cooldown('inventory_button') -> failure('Still cooling down')
!has_cooldown('daily_reward') -> true
is_cooldown_above(cooldown, duration)
Checks whether a cooldown has at least the given remaining duration.
is_cooldown_above('inventory_button', '30s') -> true
is_cooldown_above('daily_reward', '12h') -> failure('Come back later')
add_cooldown(identifier, duration)
Always adds or refreshes a named cooldown.
add_cooldown('inventory_button', '300s')
is_player -> add_cooldown('daily_reward', '24h')
cooldown_cost(identifier, duration)
Only succeeds when the named cooldown is not already active. Unlike add_cooldown, this only resolves on the server side.
cooldown_cost('inventory_button', '300s')
is_dimension('minecraft:the_end') -> cooldown_cost('end_warp', '10m')