Skip to content

Condition System ​

Use conditions to decide whether an operation is allowed to continue. Recipes, strengthening, skills, items, GUI buttons, and actions all rely on them

Unified block ​

Every module uses condition as the unified entry point for a condition block; CoreLib parses it through ConditionBlock

yaml
condition:
  type: all_of
  entries:
    - '%player_level% >= 10'
    - '%money% >= 1000'
  required_count: 0
  invalid_as_failure: true
FieldTypeRequiredDefaultRangeMeaning
condition.typestringNoall_ofall_of, any_of, none_of, at_least, exactlyCombination mode; an unrecognised value falls back to all_of
condition.entrieslistNo[]string expressions, type: expression nodes, nested groupsCondition entries
condition.required_countintegerNo0non-negative integerRequired passing count for at_least and exactly; under at_least a value of zero or less is treated as 1
condition.invalid_as_failurebooleanNotruetrue, falseTreat invalid or unevaluatable configuration as failure
condition.on_pass.actionslist<\string>No[]action pipeline linesActions to run when the condition passes, when supported by the caller
condition.on_fail.actionslist<\string>No[]action pipeline linesActions to run when the condition fails, when supported by the caller
condition.on_fail.block_outputbooleanNofalsetrue, falseBlock output on failure, used by output-producing modules such as Cooking
condition.on_fail.messagestringNo""MiniMessage textFailure message for modules such as Item equipment checks

Combination modes ​

ValueMeaning
all_ofEvery condition must be true. Use for strict gates
any_ofAt least one condition must be true. Use for alternative unlock paths
none_ofEvery condition must be false. Use for exclusion checks
at_leastAt least required_count conditions are true. Use for substitutable requirements
exactlyExactly required_count conditions are true. Use for precise matching

required_count only applies to at_least and exactly: under at_least a value of zero or less is treated as 1, and under exactly it is max(0, required_count). When the entry list is empty the group always returns true

To nest groups, write an entry with its own type and entries:

yaml
condition:
  type: all_of
  entries:
    - type: any_of
      entries:
        - '%vip_level% >= 1'
        - '%player_level% >= 50'
    - '%money% >= 5000'

You can also write an expression entry in object form. The expression must go in the expression field; condition and value are not read, so an entry using them has an empty expression and stops working

yaml
condition:
  type: all_of
  entries:
    - type: expression
      expression: '%player_level% >= 20 && %money% >= 1000'

Besides expressions and nested groups, the action system's target selectors add typed nodes (entity type, health, state, permissions, third-party mob-system identity) on top of the same entries / type / required_count syntax; the combination modes are identical

Expression operators ​

CoreLib's boolean expression engine evaluates the condition expressions you write

OperatorMeaningExample
==Equal%phase% == "success"
!=Not equal%world% != "world_nether"
<Less than%level% < 10
<=Less than or equal%star% <= 5
>Greater than%score% > 100
>=Greater than or equal%player_level% >= 20
&&AND%level% >= 10 && %money% >= 100
||OR%rarity% == "rare" || %rarity% == "epic"
!NOT!%locked%
()Grouping(%a% > 0 && %b% > 0) || %admin%

The engine tries numeric evaluation first. When a side cannot be evaluated numerically, only string == / != comparison is supported, so quote string right-hand values

How invalid_as_failure behaves ​

This flag decides what happens when an entry cannot be evaluated at all — a missing variable, a syntax error, or an optional plugin that is not loaded

  • invalid_as_failure: true (default): an unevaluatable entry fails the whole group and the operation is blocked. Recommended for production, so a config mistake cannot let players bypass a restriction
  • invalid_as_failure: false: an unevaluatable entry is skipped and does not count toward the result. Useful while developing, or when an entry depends on an optional plugin

When every entry is skipped this way, the group returns true under invalid_as_failure: false and false under invalid_as_failure: true

yaml
condition:
  invalid_as_failure: true
  entries:
    - '%attribute_attack% >= 100'

Variable sources ​

The %name% variables in a condition expression are injected by the calling module, so the available set differs per context:

ContextCommon variables
Strengthen%star%, %level%, %recipe_id%
Forge%quality%, %recipe_id%, %material_count%
Skills%skill_level%, %skill_id%, %cooldown%
Gem%gem_level%, %slot_count%, %gem_type%
Item triggers%item_id%, %trigger_type%
General%player_level%, %money%, %world%, %has_permission_xxx%

Check each module's own page for the variables it actually injects. A missing variable fails the condition when invalid_as_failure is true

PlaceholderAPI ​

When PlaceholderAPI is installed, %placeholder% tokens in condition expressions are resolved before evaluation

yaml
condition:
  entries:
    - '%player_level% >= 30'
    - '%vault_eco_balance% >= 10000'

PAPI placeholders return strings. A value carrying colour codes or non-numeric characters can break numeric comparison, so prefer placeholders that return plain numbers

Examples ​

Basic permission check ​

yaml
condition:
  type: all_of
  entries:
    - type: expression
      expression: '%has_permission_emaki.forge.use% == true'
  on_fail:
    message: '<red>You do not have permission to use the forge.'

At least N conditions ​

yaml
condition:
  type: at_least
  required_count: 3
  entries:
    - '%strength% >= 50'
    - '%agility% >= 50'
    - '%intelligence% >= 50'
    - '%vitality% >= 50'
    - '%luck% >= 50'

Actions on failure ​

yaml
condition:
  type: all_of
  entries:
    - '%player_level% >= 30'
    - '%money% >= 5000'
  on_fail:
    actions:
      - 'play_sound sound=minecraft:entity.villager.no volume=1 pitch=1'
      - 'send_message text="<red>Requires level 30 and 5000 money.</red>"'

Advice ​

Use clear failure messages for players. For important restrictions, keep invalid configuration as failure to avoid bypasses