Filters
Filters are true/false conditions about players, blocks, or the match in general. Other modules use filters to decide if and when things should happen to those players, blocks, or the entire match.
Filters are built from matchers and modifiers. Matchers are specific questions, like
- is it made of wood?
- are they on the Red Team?
- is it inside region X?
- has the match run past 5 minutes?
Modifiers can combine questions using logic, such as
- A and B
- A or B
- not A
- (A or B) and not (A and B)
Modifiers can also transform the meaning of questions, or answers, in various ways.
Dynamic Filters
The documentation for other modules will explain where filters can be used, and how the filter affects the module's behavior. Generally, other modules use filters in one of two ways:
- Passively, which means whenever the module wants to do its thing, it will check the filter to decide if it should be done or not.
- Dynamically, in which case the filter will notify the module when it's time to do something, and who or what it should be done to.
Only filters labeled Dynamic are capable of the latter. Modules that require dynamic filters will say so in their documentation.
Abstaining
Some filters do not make sense in certain contexts. For example, you cannot ask if a block is on the Red Team, or if a player is made of wood, or if the match is inside a region.
Some modules will generate an error if you try to use the wrong type of filter, but other modules may allow it. When a filter does not apply to a particular decision, it will abstain from that decision, and things will behave as they would if the filter did not exist. Generally, you should avoid using filters in such a way that they can abstain, since it tends to be confusing.
However, the event rules module uses filter abstention to make very complex conditions easier to express: It accepts a chain of filters, and uses the first filter in the chain that doesn't abstain.
Filters can be forced to abstain using the <allow>
and <deny>
modifiers.
Defining Filters
Filters can be defined inside the top-level <filters>
element,
and assigned an id
used to reference them elsewhere.
<filters>
<any id="filter-name">
<!-- Filter elements -->
</any>
<team id="viridescent-team-filter">viridescent-team</team>
<!-- More filters-->
</filters>
Inline Filters
Inline filters allow you to write an expression that internally creates a filter whenever a filter ID is requested. This is useful for scenarios where you may need to create a one-off filter.
<variables>
<variable id="some_variable" scope="match"/>
</variables>
<actions>
<trigger filter="some_variable=5" scope="match">
<action>
<message text="The variable is exactly 5!"/>
</action>
</trigger>
<!-- Note that 5.. is alternative syntax for [5, oo) -->
<trigger filter="some_variable=5.." scope="match">
<action>
<message text="The variable is 5 or more!"/>
</action>
</trigger>
</actions>
<filters>
<all>
<not>
<filter id="holding-gap">
</not>
<variable var="missing_gaps">1..</variable>
</all>
<!-- The pulse filter below uses the inline equivalent of these filters. -->
<holding id="holding-gap">
<item material="golden apple"/>
</holding>
<pulse id="can-give-gap" duration="0.05s" period="0.1s" filter="all(not(holding-gap), missing_gaps=1..)"/>
</filters>
Matcher Elements
Filter matchers test for specific conditions or properties of things.
Generic Filters
Generic filters can apply to anything.
Element | Description | |
---|---|---|
<filter id="filter1"/> | Reference a filter by its ID. | Dynamic |
<always/> | Matches/allows everything. Can be referenced with the ID always . | Dynamic |
<never/> | Matches nothing/denies everything. Can be referenced with the ID never . | Dynamic |
<time>duration</time> | Filter if the specified time period has elapsed since the match started. | Dynamic |
<match-started/> | Filter if the match has started (running or finished). | Dynamic |
<match-running/> | Filter if the match is running. | Dynamic |
<match-finished/> | Filter if the match is over. | Dynamic |
<objective>objective-id</objective> | Match if the objective is completed. | Dynamic |
<flag-carried>flag-id</flag-carried> | Match if the flag is being carried by anyone. | Dynamic |
<flag-dropped>flag-id</flag-dropped> | Match if the flag is dropped on the ground. | Dynamic |
<flag-returned>flag-id</flag-returned> | Match if the flag is at the return-point. | Dynamic |
<flag-captured>flag-id</flag-captured> | Match if the flag has been captured. | Dynamic |
Spatial Filters
These type of filters apply to anything with a physical location.
Element | Description |
---|---|
<void/> | Match if there is an air block at Y=0 in the vertical column of this location. |
<blocks region="region-1"> </blocks> | Match for original blocks that exist on the map during match load. |
All region types |
Block Filters
Element | Description |
---|---|
<material>block</material> | Matches blocks by their Material name. Accepts a Single Material Pattern. |
<structural-load>2</structural-load> | Test the number of other gravity blocks that the queried block is supporting. |
Entity Filters
Element | Description |
---|---|
<spawn>spawn reason</spawn> | Matches spawn event reasons, see Mob Spawning. |
<mob>mob name</mob> | Matches mobs by their name, see Mob Spawning. |
<entity>entity name</entity> | Match entities such as projectiles, boats, dropped items, etc. |
Competitor Filters
Competitor Filters apply to teams or players when Free-for-all is enabled.
Element | Description | |
---|---|---|
<carrying-flag>flag-id</carrying-flag> | Match the team/player carrying the specified flag. | Dynamic |
<score>single number or range</score> | Match the team/player with a range of score. | Dynamic |
Player Filters
Player filters match for attributes of a certain player.
Element | Description | |
---|---|---|
<participating/> | Match if the player is participating in the match. | Dynamic |
<observing/> | Match if the player is observing in the match. | Dynamic |
<team>team</team> | Matches a team by its ID. | Dynamic |
<class>class name</class> | Match players with the specified class. | |
<kill-streak/> | Match players with a certain range or amount of kills. | |
<lives/> | Match players with a certain amount of lives. | |
<crouching/> | Match if the player is crouching. | Dynamic |
<walking/> | Match if the player is walking. | Dynamic |
<sprinting/> | Match if the player is sprinting. | Dynamic |
<grounded/> | Match if the player is on the ground. | Dynamic |
<flying/> | Match if the player is flying. | Dynamic |
<alive/> | Match if the player is participating and alive. | Dynamic |
<dead/> | Match if the player is participating and dead. | Dynamic |
<can-fly/> | Match if the player can fly. | |
<effect/> | Match if the player has a certain status effect. | |
<carrying><item material=""/></carrying> | Match if the player is carrying an item. | Dynamic |
<holding><item material=""/></holding> | Match if the player is holding an item. | Dynamic |
<wearing><item material=""/></wearing> | Match if the player is wearing an item. | Dynamic |
Carrying/Holding/Wearing Filter Attributes
These are the attributes for <carrying>
, <holding>
, and <wearing>
.
Element | Description | |
---|---|---|
amount | Match for item stacks that have a certain amount of items in a range. | Range |
ignore-durability | Ignore the durability of the item when matching. | true/false |
ignore-metadata | Ignore the metadata of the item when matching. | true/false |
ignore-name | Ignore the name of the item when matching. | true/false |
ignore-enchantments | Ignore the enchantments of the item when matching. | true/false |
Event Filters
Event Filters apply to transient events.
Element | Description |
---|---|
<cause>cause</cause> | Filter an event's cause. |
<random>decimal or range</random> | Random chance matcher. |
Damage Filters
Element | Description |
---|---|
<relation>relation</relation> | Filter an event's relation to the player. |
Modifier Elements
Filter modifiers are used to alter the meaning of other filters, and combine them into more complex conditions. These elements must contain either a single filter, or a list of filters, as their child elements.
Name | Description | |
---|---|---|
Logic - combine other filters | ||
Invert the filters result; allow if the child filter denies, deny if it allows, otherwise abstain. | Dynamic | |
Allow if only one of the child filters allows, deny if one or more allow or none allow and at least one denies, otherwise abstain. | Dynamic | |
Allow if all of the child filters allow, deny if one or more deny, otherwise abstain. | Dynamic | |
Allow if one of the child filters allows, deny if none allow and at least one denies, otherwise abstain. | Dynamic | |
Abstention - force filters to abstain | ||
Allow if the child filter allows, otherwise abstain (transform deny to abstain). | ||
Deny if the child filter allows, otherwise abstain. | ||
Query modifiers - change the question | ||
Change a player question to a team question. For example, "do they have the flag?" becomes "does their team have the flag?". | ||
Make a damage question specifically about the victim. For example, "do they have the flag?" becomes "does the victim have the flag?". Commonly used with the damage module. | ||
Make a damage question specifically about the attacker. For example, "do they have the flag?" becomes "does the attacker have the flag?". Commonly used in the damage module. | ||
Make a location question specifically about the player. For example, "is the chest inside the region?" becomes "is the player inside the region?". Commonly used with the use and block-break attributes on . | ||
Mechanisms - apply complex mechanics to other filters |
Examples
<filters>
<not id="deny-yellow-explosions">
<all>
<team>yellow</team>
<cause>explosion</cause>
</all>
</not>
</filters>
<filters>
<deny id="no-tnt">
<material>tnt</material>
</deny>
</filters>
Special Elements
Kill-Streak Filter
The kill-streak filter matches players who have a specified number of kills. The kill counter can be set to count from the start of the match or from the last time the player died. This filter is commonly used in Kill Rewards, but can also be used to restrict access to certain locations, etc.
Kill-Streak Filter Attributes
Attribute | Description | Value | Default |
---|---|---|---|
min | Match players with at least this many kills. | Number | |
max | Match players with a maximum of this many kills. | Number | |
count | Match players with exactly this many kills. Can not be mixed with the min and max attributes. | Number | |
repeat | Repeat the filter range. | true/false | false |
persistent | Do not reset a players kill count when they die. | true/false | false |
Examples
<kill-streak min="3"/> <!-- matches players with at least 3 kills -->
<kill-streak max="5"/> <!-- matches players with at most 5 kills -->
<kill-streak count="4"/> <!-- matches players with exactly 4 kills -->
<kill-streak repeat="true" count="10"/> <!-- match for every 10th kill -->
Lives Filter
The lives filter matches for players who have a specified number of lives. The Blitz module must be enabled to use this filter.
Lives Filter Attributes
Attribute | Description | Value |
---|---|---|
min | Match players with at least this many lives. | Number |
max | Match players with a maximum of this many lives. | Number |
count | Match players with exactly this many lives. Cannot be mixed with the min and max attributes. | Number |
Examples
<lives min="3"/> <!-- matches players with at least 3 lives -->
<lives max="5"/> <!-- matches players with at most 5 lives -->
<lives count="1"/> <!-- matches players with exactly 1 life -->
Score Filter
The score filter matches if the player or team's score is a equal to a single value or within a range of values. The value can be an exact amount or a interval specifying a range. Only whole numbers are valid.
Examples
<!-- Match if a team (or player) has a score of 20. -->
<score>20</score>
<!-- Match if a team (or player) has a score from 5 to 10. -->
<score>[5,10]</score>
<!-- Match if a team (or player) has a score of 5 or greater. -->
<score>[5,oo)</score>
<!-- Match if the red team has a score of 50. -->
<score team="red-team">50</score>
Rank Filter
The rank filter matches if the player or team's rank is a equal to a single value or within a range of values. The value can be an exact amount or a interval specifying a range. Only whole numbers are valid.
Examples
<!-- Match if team (or player) is ranked 2nd on the scoreboard -->
<rank>2</rank>
<!-- Match if team (or player) is ranked from 1 to 3 on the scoreboard. -->
<rank>[1,3]</rank>
<!-- Match if the blue team is ranked first. -->
<rank team="blue-team">1</rank>
Variable Filter
The variable filter matches if a given variable is a certain value or range. The value can be an exact amount or a interval specifying a range. Decimal numbers can be used.
Examples
<!-- Match if next_post has a value of 1 -->
<variable id="next-blue" var="next_post">1</variable>
<!-- Match if t_score is ≥ 100 -->
<variable id="reached-score" var="t_score">[100,oo)</variable>
<!-- Match if red team's t_score is 20 -->
<!-- (The variable must have the team score for it to work) -->
<variable id="red-reached-score" team="red-team" var="t_score">20</variable>
Random Filter
This filter will randomly ALLOW
or DENY
when evaluated in the context of an event.
Its value is a decimal fraction between 0 and 1, representing the probability of ALLOW
.
The value can also be an interval, in the form [0, 1)
.
When the filter is evaluated, a random number is chosen, and the filter passes if the number falls within the filter's interval.
Multiple filters applied to the same object at the same instant will use the same random number.
So, if their intervals do not overlap, the filters will never both pass at the same time.
Using intervals in this way, any number of filters can be made mutually exclusive, or their relationships can be controlled in more complex ways.
A random filter can only be applied to instantaneous events, and not to conditions that persist over some span of time.
Specifically, they can be used in the following contexts:
- Regional block change rules
- Block drop rules
- Damage rules
- Mob spawning rules
In other contexts, random filters will ABSTAIN
.
Examples
<!-- 50% chance that it will return either ALLOW or DENY -->
<random>0.5</random>
<!-- Also a 50% chance -->
<!-- Any number from 0.25 to 0.75 including 0.25 but excluding 0.75 -->
<random>[0.25, 0.75)</random>
Countdown Filter
This filter matches for up to the specified amount of time after the child filter starts matching. It never matches when the child filter doesn't match. This filter is a Dynamic Filter.
Attribute | Description | Value |
---|---|---|
duration | RequiredLength of time to match for. | Time Period |
filter | RequiredFilter when the countdown should be active. | Dynamic Filter |
message | Optional timer message to display while counting down. Only players who match the filter can see the timer. If the message contains a placeholder {0} , it will be replaced with the remaining time. | String |
<!-- Countdown 30s from the moment any player picks up the flag -->
<!-- (you could then use the countdown filter to kill them, teleport them, etc) -->
<countdown duration="30s" message="You have {0} to capture the flag!">
<carrying-flag>blue-flag</carrying-flag>
</countdown>
After Filter
This filter starts allowing sometime after a duration the child filters start allowing. This filter is a Dynamic Filter.
Attribute | Description | Value |
---|---|---|
duration | RequiredLength of time to be active after the child filter allows. | Time Period |
filter | RequiredFilter when the after filter should be active. | Dynamic Filter |
message | Optional message to display after the child filter allows. Only players who match the filter can see the message. If the message contains a placeholder {0} , it will be replaced with the remaining time. | String |
<!-- Allows 15 seconds after the player gets 1st place -->
<after duration="15s" message="1st place bonus will apply in {0}"> <!-- Automatically updates to show time -->
<rank>1</rank>
</after>
Pulse Filter
The pulse filter is special modifier filter which sends a repeating signal.
The filter activates and deactiviates for a certain duration in a time period, after
which the filter is evaluated again. The filter continues repeating if the inner filter condition is still ALLOW
.
This is mainly useful in combination with Actions & Triggers.
This filter is a Dynamic Filter.
Attribute | Description | Value |
---|---|---|
period | RequiredLength of time a pulse remains on in a cycle. | Time Period |
duration | RequiredLength of time a cycle lasts for. Must be a positive number that is shorter than the period length. | Time Period |
filter | RequiredFilter when the pulse should be active; if the filter allows, pulse will be ticking. It can be defined as a unique child element or as an attribute. | Dynamic Filter |
message | Optional timer message to display while counting down. Only players who match the filter can see the timer. If the message contains a placeholder {0} , it will be replaced with the remaining time. | String |
<filters>
<!-- Pulses activation for 15 seconds in a 60 second time period -->
<!-- ie. on for 15 seconds, off for 45 seconds -->
<!-- Filter turns off if condition doesn't meet after 60 seconds -->
<pulse id="pulse-filter" period="60s" duration="15s" filter="second-filter"/>
<!-- Pulse activates for 20 seconds in a 40 second time period -->
<!-- With the inner filter, it is always active until the match ends -->
<pulse id="other-pulse" period="40s" duration="20s">
<match-running/>
</pulse>
</filters>
Offset Filter
The Offset filter checks for blocks that are placed in the world, either using exact locations, coordinates relative to the player, or directions relative to the player.
Coordinates relative to the player are defined using ~
and behave the same like ~
does in-game.
Directions relative to the player use ^
. This can be utilized as a Dynamic Filter as long it is used
with an absolute position.
<filters>
<!-- checks for bedrock placed at this exact location -->
<offset id="hardFilter" location="10.5,5,15.5">
<material>bedrock</material>
</offset>
<!-- checks for cobblestone placed 1 block beneath the player -->
<offset id="blockUnderFeetFilter" location="~0,~-1,~0">
<material>cobblestone</material>
</offset>
<!-- checks for water placed 2 blocks *in front* of the player -->
<!-- ^<+left/-right>, ^<+up/-down>, ^<+front/-behind> -->
<offset id="inFrontFilter" location="^0,^0,^2">
<material>water</material>
</offset>
</filters>
Player Count Filter
This filter counts the number of players matching a single child filter and matches if that count is within a specified range. The child filter can be omitted, in which case all players in the match will be counted.
Player Count Filter Attributes
Attribute | Description | Value | Default |
---|---|---|---|
min | Minimum player count. | Number | 1 |
max | Maximum player count. | Number | oo (unlimited) |
participants | Include participants (players actually playing) in the count. | true/false | true |
observers | Include observers in the count. | true/false | false |
filter | Filter when players are counted. | Dynamic Filter | always |
Examples
<!-- Match if there are at least 4 players participating -->
<players min="4"/>
<!-- Match if there are 1 to 3 players sneaking in region X -->
<players min="1" max="3">
<all>
<sneaking/>
<region id="region-x"/>
</all>
</players>
Objective Filters
There are three different Objective Filters that are used:
The <completed>
filter matches when the specified objective is completed or captured by anybody.
This filter is not affected by the context in which it is applied and never abstains.
The <captured>
filter matches players or teams who currently control the specified objective.
This filter is useful for objectives that can change ownership, such as hills and flags.
For other objective types, it will match players/teams who are allowed to complete the objective.
This filter will abstain if used in a context that does not involve a specific player or team.
Alternately, <captured>
can have a team specified with the team attribute.
Then it will always test that team's control of the objective, regardless of the filtering context, and will never abstain.
<objective>
is deprecated and may be removed in future versions of PGM.
The <captured>
and <completed>
filters should be used instead.
<objective>
matches for objectives that have been completed.
The filter can also match for objectives completed by a certain team, or by anyone.
This filter is a Dynamic Filter.
Objective Filter Modules
Element | Description | Value |
---|---|---|
<completed> | Matches if anyone completed or captured the objective. | Objective ID |
<captured> | Matches for players/teams who currently control the objective. | Objective ID |
<objective> | DeprecatedMatches if any team completed the objective. | Objective ID |
Objective Module Attributes
Attribute | Description | Value | Default |
---|---|---|---|
any | Matches if any team completed the objective. | true/false | false |
team | Matches if a certain team completed the objective. | Team ID |
Examples
<!-- Match if "red-core" has been leaked -->
<completed>red-core</completed>
<!-- Match if "south-hill" is owned by anyone -->
<completed>south-hill</completed>
<!-- Match players/teams who own "north-hill" -->
<captured>north-hill</captured>
<!-- Match if Blue Team owns central-hill -->
<captured team="blue-team">central-hill</captured>
<!-- <objective> is deprecated -->
<!-- Matches if the team of the player is the one that completed objective -->
<objective>goal-id</objective>
<!-- Matches if any team has completed objective -->
<objective any="true">goal-id</objective>
<!-- Matches if red team completed or is holding the objective -->
<objective team="red-team">goal-id</objective>
Flag Filters
The flag filters allow filtering of a specific flags current state or for the player that is carrying the flag.
One important use of these filters is to implement the standard rule that a team can only capture an enemy flag when their own flag is returned.
This can be implemented easily using a <flag-returned>
as the capture-filter of a flag.
This can also be done with the nets return attribute. However, using the return attribute will return dropped flags, while using a filter will not.
The flag carried, dropped, captured, and returned filters have an optional post
attribute to only match if the flag was last returned to that post.
<!-- The blue flag is currently being carried by a player -->
<flag-carried>blue-flag</flag-carried>
<!-- The blue flag has been carried away & dropped from the red-post -->
<flag-dropped post="red-post">blue-flag</flag-dropped>
<!-- The yellow flag is standing at one of its posts -->
<flag-returned>yellow-flag</flag-returned>
<!-- The yellow flag is standing at the green-post -->
<flag-returned post="green-post">yellow-flag</flag-returned>
<!-- The cyan flag has been captured but not yet returned -->
<flag-captured>cyan-flag</flag-captured>
<!-- The player currently carrying the purple flag -->
<carrying-flag>purple-flag</carrying-flag>
Item Filters
These filters can be used to filter for players with specific items in their inventory. They accept a single item element. Only the item's type, durability/damage and meta data are compared. A item's meta data includes the item's name, enchantments, etc.
<!-- Player has a stick named 'Blue Door Key' in their inventory -->
<carrying>
<item name="Blue Door Key" material="stick"/>
</carrying>
<!-- Player is holding a clock -->
<holding>
<item material="clock"/>
</holding>
<!-- Player is wearing a chainmail chestplate -->
<wearing>
<item material="chainmail chestplate"/>
</wearing>
Event Cause Filters
Cause filters are used to filter an event or action according to its cause.
Element | Description |
---|---|
Filter an event's cause. | |
Cause: Actor Type | |
World events such as ice melting, etc. | |
Events caused by a living entity. | |
Events caused by a mob. | |
Events caused by a player. | |
Cause: Block Action | |
Events where a block is punched. | |
Events where a block is trampled. | |
Events where a block is mined. | |
Cause: Damage Type | |
(fall and void damage) | |
Effect Filter
The effect filter is used to check if a player has the same type of Status Effect specified in the filter.
Three optional attributes can be configured using min-duration
, max-duration
and amplifier
.
<!-- matches players with Saturation I that lasts at least 10 seconds -->
<effect id="filter1" min-duration="10s" amplifier="1">saturation</effect>
<!-- matches players with a saturation effect, regardless of strength or length. -->
<effect id="filter2">saturation</effect>
<!-- matches players with Night Vision II that lasts at most 30 seconds -->
<effect id="filter3" max-duration="30s" amplifier="2">night vision</effect>
<!-- matches players with Water Breathing I -->
<effect id="filter4" amplifier="1">water breathing</effect>
<!-- matches players with Night Vision II that lasts between 10-20 seconds -->
<effect id="filter5" min-duration="10s" max-duration="20s" amplifier="2">night vision</effect>
Player Relation Filters
The relation filter is used when a player is damaged to check the relation between them and the damage cause. This filter is only used in damage related contexts i.e., damage filters, and Kill Rewards.
Element | Description |
---|---|
The relation between the player and their damage cause. | |
Values | |
Event has no attacker, e.g. world damage. | |
Events caused by the player. (Same player same team) | |
Events caused by a player on the same team. (Different player same team) | |
Events caused by an enemy player. (Different team) |
Structural Load Filters
The structural load filter checks the number of gravity blocks that are attached to the queried block.
It returns ALLOW
as long as the structural load is greater than or equal to the specified value and DENY
otherwise.
This filter is very computationally expensive to apply. XML authors should ensure that it is only run when absolutely necessary, e.g. by placing other filters above it. They should also not apply it to events that modify large amounts of blocks, such as explosions. This filter requires the falling blocks module to be loaded otherwise it will default to abstain.
Example
<!-- Deny breaking structures longer than 3 blocks -->
<not>
<all>
<cause>player</cause>
<filter id="structure-blocks"/>
<structural-load>3</structural-load>
</all>
</not>
Match Phase Filter
The Match Phase Filter matches for a certain state the match is in. ie. This filter can start matching after a match ends.
Users should use the more specific <match-started/>
, <match-running/>
or <match-finished/>
filters instead of <match-phase>
.
<!-- Filter if the match has started (running or finished) -->
<match-started/>
<!-- Filter if the match is currently running -->
<match-running/>
<!-- Filter if the match is over -->
<match-finished/>
<!-- Filter if the match is actively running and participants have been created -->
<match-phase>running</match-phase>
<!-- Filter if the match has stopped running and (if possible) has announced a winner -->
<match-phase>finished</match-phase>
<!-- Filter if the match has started (running or finished) -->
<match-phase>started</match-phase>
<!-- Filter if match has been queued to transition to running and a countdown is actively progressing -->
<match-phase>starting</match-phase>
<!-- Filter if match has loaded but no countdown is given -->
<match-phase>idle</match-phase>
Void Filter
If your map is especially complex shaped you may have to use the <void/>
tag to shape your filtered region.
The <void/>
tag checks the specified regions for blocks on the bottom layer of the world.
It then creates an outline of those blocks and the specified filter is only active inside or outside that outline.
Bridges are usually not detected because they are not at y=0
.
This can be fixed by creating a invisible silhouette of the bridge with block 36
at y=0
.
Example
<filters>
<not id="no-void">
<void/>
</not>
</filters>
<regions>
<apply block="no-void" message="You may not modify the void area!">
<region>
<rectangle id="main-area" min="65,860" max="290,980"/>
</region>
</apply>
</regions>