For functions there is a built-in way to do this:
/schedule function <function_name> <time>
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:
/schedule function abc:test 3d
/schedule function abc:test 3600s
/schedule function abc:test 72000t
/schedule function abc:test 72000
/schedule function abc:test 3d replace
…
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:
/schedule clear abc:test
If you want to schedule multiple executions, you can use append
instead of replace
. If you want to replace all existing schedules of this function with the current one, you can use replace
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:
/scoreboard objectives add timer dummy
The "dummy
" type is one that is not affected by anything except commands.
In a repeating command block or ticked function, execute this command:
scoreboard players add $timer timer 1
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:
execute if score $timer timer matches 100 run say 5 seconds are over!
If you want to do something repeatedly after 5 seconds, simply replace 100
with 100..
. If you want a variable starting time, compared to someone else's score, you can for example use >= @p points
instead of matches 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:
execute if score $timer timer matches 100 run scoreboard players set $timer timer 0
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:
execute if block ~ ~1 ~ stone run scoreboard players add $timer timer 1
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.