You wrote "tag:
" instead of "tag=
", that doesn't work. And it's also the reason why the page here formatted it into a tag for this site.
Yes, functions have better performance and you don't need command blocks at all anymore, except if you want to activate them using redstone (like a button).
Function do not abort on error, so that can't be the reason why the last commands don't seem to work. Maybe a missing /reload
?
Your real problem is that the players can wait arbitrarily long until they click "respawn", so no fixed delay would help you. What you can instead do is detecting when they have respawned. This can for example be done by checking if they are at a location (because dead players are nowhere*):
/execute as @a[scores={deaths=1..},distance=0..] run <command>
This distance=0..
might seem useless, because you're testing for a distance of 0 or more from the command block, but what it does is only activating if you have an alive player in the same dimension. You could also do the same for Nether and End, but since you want to detect respawning, that's not necessary. Dead players have no location, so their distance from the command block isn't 0 or more, it's nothing.
*This got a bit more complicated in 1.15, because the player is still registered as being at their death location for about a second after dying. That could be very helpful in some cases, I think it even used it in an answer here already, but it complicates this case. Now you need to check if they are not at any location first and then at a location again:
execute as @a[tag=!dead,scores={deaths=1..}] unless entity @a[scores={deaths=1},distance=0..] run tag @s add dead
execute as @a[tag=dead,distance=0..] run <command>
execute as @a[tag=dead,distance=0..] run scoreboard players set @s deaths 0
execute as @a[tag=dead,distance=0..] run tag @s remove dead
The first command is the real magic: Every player who died gets tagged, but only once no player who died can be found at any location anymore. This still fails if another player is currently in its death animation, I don't think this can be avoided.
Then you just run whatever command you want at a player that used to be at no location, but is at some location now. Finally, you reset the scoreboard (implied in my 1.14 solution) and the tag.
Best Answer
For functions there is a built-in way to do this:
So if you for example want to execute the function named "test" in the namespace "abc" in 1 hour, which equals 3 in-game days, you can use any of these commands:
Unit postfixes for minutes, hours etc. do not exist. The in-game days unit is not affected by sleeping or
/time
.If you have changed your mind, you can abort a scheduled function execution like this:
If you want to schedule multiple executions, you can use
append
instead ofreplace
. If you want to replace all existing schedules of this function with the current one, you can usereplace
or just provide no mode at all,replace
is the default.To loop execution, you can simply use the
/schedule
command at the end of your function. Usually you'll want to do this under some condition, so that it doesn't keep looping forever.If you cannot or do not want to use functions or
/schedule
, you can still use the old scoreboard timer method. This needs a little bit more resources, because it actively does something every tick, but it shouldn't cause noticeable lag.As a preparation, you need a scoreboard:
The "
dummy
" type is one that is not affected by anything except commands.In a repeating command block or ticked function, execute this command:
The name "
$timer
" cannot possibly be a real player name, so it is a good choice for a dummy player name. If you do not want it to show up in a scoreboard sidebar display, start the name with a#
character.Now you can do something once the timer reaches your desired number of ticks like this:
If you want to do something repeatedly after 5 seconds, simply replace
100
with100..
. If you want a variable starting time, compared to someone else's score, you can for example use>= @p points
instead ofmatches 100
.If you want to repeat something every x seconds/minutes/…, you can just reset the timer after you have done whatever you want to do with it. So at the end of your command block chain or ticked function, you put this:
This concept can also be used to do something every x times something happens. To do this, simply increase the timer only conditionally instead of every tick, for example like this:
But make sure to change whatever the command is checking for directly afterwards, otherwise it keeps ticking up by 1 every tick as long as the condition is matched.