As of Bedrock v1.19.10 a new /execute
command is now available through the Additional Creator Features experimental toggle. Just like when Java edition first got this new syntax back in the Aquatic Update, it caused some trouble, because it introduces some new concepts and changes the way you should be using /execute
.
This guide aims to explain these concepts to you, allowing you to easily adapt to the changes and use them to their fullest potential. Readers are expected to have some basic knowledge of the old /execute
syntax.
DISCLAIMER: The new
/execute
syntax is currently an experimental feature and will likely be expanded in future updates. This guide on the other hand might not. This guide was last updated at 15/08/2022.
Context is information passed to each command behind the scenes. For instance, whenever you use relative coordinates (~
or ^
), it will take the position and rotation that is stored within the command's context to calculate the resulting coordinates.
By default, a command's context is inherited from the executor. Are you executing a command from chat? It will take your position and rotation. Are you executing from a command block? It uses the block's position instead (and the rotation will be x0 y0).
The /execute
command's primary purpose has always been to allow users to modify this context. Let's have a look at the below commands using the old /execute
syntax, and assume they are all ran by command blocks:
# Summon a creeper at the CMD block
/summon creeper ~ ~ ~
# Summon a creeper at every player
/execute @a ~ ~ ~ summon creeper ~ ~ ~
# Summon a creeper at 0,0,0 for every player in the world
/execute @a 0 0 0 summon creeper ~ ~ ~
In both the 2nd and 3rd command, we essentially tell the game to run a /summon
command for every player, either at their location, or in case of the 3rd command at 0,0,0. In both cases, it runs new commands at a different location than the original.
We know both position and rotation are stored inside context, but so is the "executor". The executor is the entity running the command (if applicable), but using /execute
it can (and will) be changed.
The current executor can always be targeted with the @s
variable. Opposed to the otherwise commonly used @p
or @e[c=1]
, this is a more safe and most importantly performant way to select targets.
# Bad
/execute @a ~ ~ ~ say @p
^^
# Good
/execute @a ~ ~ ~ say @s
Both commands will do the same (unless of an unlikely case where right after teleporting multiple player the nearest player won't always be the player itself), but the thing to take away is that when we start using the new /execute
syntax you can no longer avoid @s
. On top of that, it performs better, makes your code easier to understand, and is more convenient to write.
NOTE: Context is preserved when calling functions. If you call a function, all of the context used for calling that function will be applied to every command inside that function.
The new /execute
command gives the user better control over which context to keep and replace. It is still able to do everything the old command is capable of however. If you wanted to replicate its behavior, it would look like this:
# Old syntax
/execute @a ~ ~-1 ~ detect 0 0 0 bedrock 0 setblock ~ ~ ~ stone
# New syntax
/execute as @a at @s positioned ~ ~-1 ~ if block 0 0 0 bedrock 0 run setblock ~ ~ ~ stone
Now, this seems like a mouthful. Fear not however, most likely your commands won't all have to look like this from on.
The beauty of this new syntax is that you get to choose over which "components" you need. You can put them in whatever order you need, and use them multiple times. The below commands are all completely valid.
# Set a block at each player's location
/execute at @a run setblock ~ ~ ~ stone
# If the block 10 blocks below the nearest player's location is bedrock, summon a creeper at each player's location
/execute at @p if block ~ ~-10 ~ bedrock 0 at @a run summon creeper ~ ~ ~
Using the as <target>
component you can change the command's executor. This changes whichever entity @s
references to.
# Have each player say their own name
/execute as @a run say @s
Using the at <target>
component you can change the command's position and rotation to match that of an entity.
# Place a block below each player's feet
/execute at @a run setblock ~ ~-1 ~ stone
WARNING: You will commonly combine
as
andat
. It is essential you understand how to use the@s
selector for this. Running/execute as @a at @p
is NOT the same as/execute as @a at @s
and will yield unwanted behavior.
Another option is positioned as <target>
, which changes the position but leaves the rotation as-is.
# Place a block at each player's location, one meter into the direction the player closest to the CMD block was facing.
/execute at @p positioned as @a run setblock ^ ^ ^1
NOTE: At the moment you rarely ever will need to use
positioned as <target>
, due to the lack of any meaningful components to change the rotation only. Java Edition also hasrotated ...
andfacing ...
components which can be used to change rotation in various ways, which I suspect and hope will soon make their way into Bedrock soon.
Using positioned <coords>
you can change the the position without having to reference an entity.
# Summon a creeper 10 blocks above the CMD block
/execute positioned ~ ~10 ~ run summon creeper ~ ~ ~
The new syntax also adds various new ways to add implement conditions into your commands, which may very well be the most exciting thing about this new syntax. We'll have a deep dive into these in the following section.
Once you've added all the components you need, you can add the run <command>
component and it will run that command. This is generally the last in your chain of components, but it is not required, which might be useful if you want to detect the output of certain conditions through a chain command block.
A condition is nothing more than a term that has to be validated before the command can be ran. There are several ways you could do this:
- With target selectors:
# NOTE: Old execute syntax /execute @a[scores={test=1}] ~ ~ ~ say I have a test score of 1!
- Using the (old)
/execute
'sdetect
keyword:# NOTE: Old execute syntax /execute @a ~ ~ ~ detect ~ ~-1 ~ bedrock 0 say I am standing on bedrock!
- With conditional command blocks.
None of these are very convenient however, and often bring unwanted side effects, like having to add /execute
in front of your command, which then changes the context again. Let's say you want each player that does NOT have a creeper within 10 blocks them to say a message in chat:
# Correct but inconvenient. Requires extra commands.
/execute @e[type=creeper] ~ ~ ~ tag @a[r=10] add hasCreepersNearby
/execute @a[tag=!hasCreepersNearby] ~ ~ ~ say There are no creepers nearby!
/tag @a remove hasCreepersNearby
The issue really is that the old /execute
command does multiple things, even when you don't want it to do all of them.
There are some commands like /testforblocks
that are essentially conditions, but they require a conditional command block to capture the result of that condition, which when using functions also isn't ideal.
Since the old command was always used to evaluate conditions, it only makes sense that the new command enhances that capability and improves on the previous limitations. It does so with the following two components, if ...
and unless ...
. Both work the same, with the only difference being that unless ...
checks if the condition is false instead of true.
Using if entity <target>
you can check if an entity exists without having to change context or invoke a certain command.
# Send a message if a creeper is found
/execute if entity @e[type=creeper,c=1] run say There's a creeper somewhere!
Using if block <coords> <identifier> (<data>|<blockstates>)
you can check if a block exists at a specific position. Its arguments are identical to that of the /testforblock
command.
# Have a player send a message when they stand on bedrock
/execute as @a at @s if block ~ ~-1 ~ bedrock 0 run say I'm standing on bedrock!
Using if blocks <corner1> <corner2> <source> (masked|all)
you can check if an area of blocks matches those of another area. Its arguments are identical to that of the /testforblocks
commands.
# Have each player who stands on the same block as the one that's on 0,0,0 send a message
/execute as @a at @s if blocks ~ ~-1 ~ ~ ~-1 ~ 0 0 0 all run say I'm standing on the same block that's on 0,0,0!
Using if score ...
you can check and compare scores in various ways. These bring some massive improvements, especially if you're using functions:
- You can test scores of so-called "fake players" (previously required conditional CMD blocks), which improves your code in various ways.
- You can easily compare scores between entities (previously required multiple scoreboard operations).
If you want to compare an existing value to a predefined range of values, you can use if score <name> <scoreboard> matches <range>
.
# Setup
/scoreboard objectives add kills dummy
/scoreboard players set team1 kills 15
# Send a message if team 1 has 10 or more kills
/execute if score team1 kills matches 10.. run say Team 1 has 10 or more kills!
We can also compare it to another score using if score <name> <scoreboard> <operator> <name> <scoreboard>
.
# Setup
/scoreboard objectives add kills dummy
/scoreboard players set team1 kills 15
/scoreboard players set team2 kills 12
# Send a message if team 1 has 10 or more kills
/execute if score team1 kills > team2 kills run say Team 1 has more kills than team 2!
- Putting another
execute
command after arun
statement. Redundant.# Bad /execute as @a run execute at @s run summon creeper ~ ~ ~ ^^^^^^^^^^^ # Good /execute as @a at @s run summon creeper ~ ~ ~
- Using the
run
component immediately after/execute
. Redundant.# Bad /execute run say Hihi ^^^^^^^^^^^^ # Good /say Hihi
- Using
as @s
. If you need to check if the executor is an entity, useif entity @s
instead. Redundant otherwise.# Bad /execute as @s run say I am not a command block or function! ^^^^^ # Good /execute if entity @s run say I am not a command block or function!
- Using
@p
or@e[c=1]
as a substitute to@s
. Leads to worse performance and makes your code harder to both read and write.# Bad /execute at @a if score @p test matches 10.. run setblock ~ ~-1 ~ stone ^^ # Good /execute as @a at @s if score @s test matches 10.. run setblock ~ ~-1 ~ # Best /execute at @a[scores={test=10..}] run setblock ~ ~-1 ~
- Not using fake players for global storage. Leads to worse performance and makes your code harder to both read and write.
# Bad /execute if score @e[type=armor_stand,name=team1] kills matches 10.. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ # Good /execute if score team1 kills matches 10..
- Using the same argument selectors and context-changing components repeatedly. Depending on the scale can lead to significantly worse performance.
# Bad /execute as @a run function foo/bar # -- Function foo/bar.mcfunction /execute at @s[tag=myTag,scores={kills=10..,lives=1}] run setblock ~ ~ ~ wool 1 /execute at @s[tag=myTag,scores={kills=10..,lives=2}] run setblock ~ ~ ~ wool 2 /execute at @s[tag=myTag,scores={kills=10..,lives=3}] run setblock ~ ~ ~ wool 3 /execute at @s[tag=myTag,scores={kills=10..,lives=4}] run setblock ~ ~ ~ wool 4 /execute at @s[tag=myTag,scores={kills=10..,lives=5}] run setblock ~ ~ ~ wool 5 ^^ ^^^^^^^^^ ^^^^^^^^^^ # Good /execute as @a[tag=myTag,scores={kills=10..}] at @s run function foo/bar # -- Function foo/bar.mcfunction /execute if score @s lives matches 1 run setblock ~ ~ ~ wool 1 /execute if score @s lives matches 2 run setblock ~ ~ ~ wool 2 /execute if score @s lives matches 3 run setblock ~ ~ ~ wool 3 /execute if score @s lives matches 4 run setblock ~ ~ ~ wool 4 /execute if score @s lives matches 5 run setblock ~ ~ ~ wool 5