Timers

Since 1.0.0

One thing you most likely will end up creating on a plugin is a task or some sort of delay. While tasks and delays can easily be created just with the Bukkit API, problems start to arrise when we want to let the user know how much time is left before the task executes, what about a 30 minute timer to end a SkyWars game? It gets complicated, right? Well, not anymore. MCUtils provides a Timer system with time units adapted to Minecraft. Let's see how to use it.

import net.codersky.mcutils.time.MCTimeUnit;
import net.codersky.mcutils.time.Timer;
import net.codersky.mcutils.time.TimerTask;

// Let's create a class that starts a game and ends it after 30 minutes.

public class TimeTest {
    
    TimerTask gameTask = null;

    public void start(MCPlugin plugin) {
        gameTask = new Timer(MCTimeUnit.MINUTES, 30)
            .schedule(plugin, () -> endGame());
    }

    public void endGame() {
        // Whatever magical code ends a game.
    }
}

Easy, isn't it? Obviously, as we have skipped some important methods, for example, how can we show a player how much time is left? Well. Let's understand what a TimerTask is first.

TimerTask

As you can see, calling the schedule method on a Timer creates a TimerTask instead of returning the Timer itself, why? Well, a clone of the Timer is created and stored on said task once it is scheduled. This is because, internally, the TimerTask calls the Timer#tick() method every second until the Timer reaches zero. If you wonder what the tick method does, well, it just removes one second from the Timer. Now, let's just send the time left to every online player as an example.

TimerTask gameTask; // Assume we have a task from the previous example

public void announceTaskTime(TimerTask task) {
    // Call it before the loop to only convert the Timer to string once.
    String time = gameTask.getTimer().toString("&8:&b", true, MCTimeUnit.MINUTES);
    String timeFormatted = MCStings.applyColor("&7Time left&8: &b" + time);
    for (Player player : Bukkit.getOnlinePlayers())
        player.sendMessage(timeFormatted);
}

Now, let's explain the arguments passed to the Timer#toString method, in order:

  • "&8:&b": Just sets the separator between each time unit on the timer.

  • true: Enables "fill" mode, so 5 seconds will be displayed as 05 to fill the space.

  • MCTimeUnit.MINUTES: Probably the weird part, ensures that the timer will always display up to the MINUTES slot, so it will always display MINUTES and SECONDS, even if there are only 30 seconds left.

So if the timer has 30 seconds left, the message sent to the player will be

  • "&7Time left&8: &b00&8:&b30" (Uncolored: "Time left: 00:30")

Last updated