-
Notifications
You must be signed in to change notification settings - Fork 0
Predicates
A predicate is a lambda you use as a yes/no test. You give it a value, and it answers true or false.
The easiest way to make one is an inline lambda with a condition body:
set {is-op} to lambda (p: player): {_p} is opThis lambda takes a player and returns whether that player is op.
Storing a lambda in a global variable (
{is-op}, as above) makes Skript log a "cannot be saved" warning on load: lambdas are live code, so they can't be written to disk and won't survive a restart. The warning is harmless, and the lambda works normally until the server stops. Use a global when several triggers share the predicate, and a local ({_is-op}) when only one does.
Use passes for to run a predicate and check its answer.
set {is-op} to lambda (p: player): {_p} is op
if {is-op} passes for player:
send "you're staff" to playerA predicate runs in its own little space, so it can't see the variables around it. That's why you give it the value to test as an argument, after for.
You can also write matches or holds instead of passes. They mean the same thing.
if {is-op} matches for player:
...To check that a test fails, you have two choices:
if {is-op} doesn't pass for player:
send "not staff" to player
if not {is-op} passes for player:
send "not staff" to playerBoth do the same thing.
doesn't pass and not flip the answer of a single check. negated %lambda% (or negation of %lambda%) is different: it hands you back a new predicate that passes exactly when the original would fail. Because it's a predicate itself, you can store it, pass it around, and drop it into list operations.
set {_is-op} to lambda (p: player): {_p} is op
set {_not-op} to negated {_is-op}
if {_not-op} passes for player:
send "you're not staff" to playerThis shines when you filter a list, where there's no inline "doesn't" to reach for. Drop it into Skript's where filter:
set {_visitors::*} to all players where [{_not-op} passes for input]
send "%size of {_visitors::*}% non-op players online" to playerAdded in 1.1.0. For how where [... passes for input] filters a list, see List operations.
You can keep many predicates in a list and test them together.
add lambda (p: player): {_p} is op to {is-admin::*}
add lambda (p: player): name of {_p} is "eult" to {is-admin::*}By default, the value must pass every predicate in the list:
if {is-admin::*} passes for player: # true only if ALL of them pass
send "welcome, admin" to playerPut one of these words in front to change the rule:
| Word | Passes when... |
|---|---|
all of (the default) |
every predicate passes |
any of |
at least one passes |
none of |
no predicate passes |
if all of {mod::*} passes for {_p}: # every check passes
...
if any of {mod::*} passes for {_p}: # at least one passes
...
if none of {mod::*} passes for {_p}: # not a single one passes
...{mod::*} passes and all of {mod::*} passes mean exactly the same thing.
When "all", "any", and "none" aren't precise enough, name a number. These check how many predicates in the list pass.
| Form | Passes when... |
|---|---|
at least N of |
N or more predicates pass |
at most N of |
N or fewer pass |
exactly N of |
exactly N pass |
if at least 2 of {requirements::*} passes for {_p}: # two or more hold
send "access granted" to {_p}
if exactly 3 of {requirements::*} passes for {_p}: # all three, no more, no less
send "full clearance" to {_p}
if at most 0 of {requirements::*} passes for {_p}: # not a single one
send "you meet none of them" to {_p}They line up with the words above: at least 1 of is any of, and at most 0 of is none of. Added in 1.2.0.
If the list is empty:
-
all ofandany of-> never pass (there's nothing that passed). -
none of-> always passes (nothing passed, which is what it wants). - counting quantifiers compare against a count of zero, so
at most N ofandexactly 0 ofpass, whileat least N of(with N of 1 or more) does not.
A predicate is a clean way to filter a listener. Put it right in the where part.
set {is-stone} to lambda (b: block): {_b} is stone
listen for block break where {is-stone} passes for event-block:
on trigger:
send "stone!" to event-playerskLambda comes with two ready-made predicates: always() and never(). They ignore whatever you give them: always() always passes, never() never does.
if always() passes for player: # always true
send "everyone sees this" to player
if never() passes for player: # always false
send "nobody sees this" to playerThey slot in anywhere a predicate is expected. One handy use is a feature flag you flip by swapping a single line:
set {_gate} to always() # change to never() to close the gate for everyone
if {_gate} passes for player:
send "gate open" to playerThey also work as list filters. See List operations.
- A lambda that returns anything other than
truecounts as not passing. - You can pass more than one value after
forif your predicate takes more than one argument.
For more on making lambdas, see Lambdas.
Guides
Reference





