Why I created this thread I've seen a few threads talking about timers and tasks but all the useful information is surrounded by other posts saying "learn PHP" or "learn the PocketMine-API", these threads have some useful information but don't really give you a clear answer on how to create a timer or use tasks. Why do I need a task? Creating tasks in your plugins allows you to create timers, delayed tasks, repeating tasks and much much more. Just let your creativity flow and experiment with the infinite amount of possibilities. So how do I create a timer? To create a timer you will need to use a repeating task. Repeating tasks will run after the specified amount of ticks have passed and will continue to do so until stopped. Creating a repeating task that executes every 20 ticks will create a task that runs every second, here's an example of how to schedule a repeating task: PHP: public function createTask() { $task = new YourTask($this); // A class that extends pocketmine\scheduler\PluginTask // The Task handler $h = $this->getServer()->getScheduler()->scheduleRepeatingTask($task, 20); // Set the task's handler $task->setHandler($h);} This will create the task but you will have no easy way of tracking your task instance, to easily track your tasks you should create an array and store it to keep track of them all. Here's an example of how to do that: PHP: // The PHP file that will runpublic $tasks = [];public function createTask() { $task = new YourTask($this); // A class that extends pocketmine\scheduler\PluginTask // The Task handler $h = $this->getServer()->getScheduler()->scheduleRepeatingTask($task, 20); // Set the task's handler $task->setHandler($h); // Add the task to the array $this->tasks[$task->getTaskId()] = $task->getTaskId();} This will add the ID of the task to the $this->tasks array each time you create one. The easiest way to create the task or timer is to create another class (PHP file), here's an example of a basic task: PHP: <?phpnamespace name\space;use pocketmine\scheduler\PluginTask;use plugin\Main;class YourTask extends PluginTask { public $plugin; public $seconds = 0; public function __construct(Main $plugin, Player $player, $time) { parent::__construct($plugin); $this->plugin = $plugin; } public function getPlugin() { return $this->plugin; } public function onRun($tick) { // Sends a message to the console with how many seconds the task has been running for $this->getPlugin()->getLogger()->info("YourTask has run for " . $this->seconds . "!"); // Checks if $this->seconds has the same value of 10 if($this->seconds === 10) { // Tells the console that the task is being stopped and at how many seconds $this->getPlugin()->getLogger()->info("YourTask has run for " . $this->seconds . " and is now stopping..."); // Calls a function from your Main that removes the task and stops it from running $this->getPlugin()->removeTask($this->getTaskId()); } // Adds 1 to $this->seconds $this->seconds++; }} So you've got your task set up and running but your wondering how to cancel it and stop it from running. The easiest way to cancel a task is to create a function in your Main class that cancels a task, it should look something like this: PHP: public function removeTask($id) { // Removes the task from your array of tasks unset($this->tasks[$id]); // Cancels the task and stops it from running $this->getServer()->getScheduler()->cancelTask($id);} That's the basics of how to create a simple repeating task and how to use one as a timer. I hope this helped you or was of some use to you If there is anything I missed or anything you would like me to add be sure to let me know! Note: This thread was originally posted at Forums.PocketMine.net, I have just copied the post over with some minor changes (yes it was a thread I created and I am going to add a link to the post on there too).
This is very inaccurate as an introduction in a tutorial. It will make people mistaken that you must use it for minigames (which is not true) (do I have to use a timer if I hold a parkour race with no time limit?), or that it is mainly for making minigames and other things don't need it so importantly. I suggest these three words be deleted. Strongly discourage any classes to be named with the same class names as those in PocketMine. This is not always necessary!
Fixed. Fixed. In the past when I've tried to cancel tasks without setting the handler quite often the task wouldn't cancel properly and setting the handler seemed to fix this. However, it might've changed since I tested this last so I'll check up on it a bit later.
Two things to emphasize: Scheduled tasks are reset if server restarts. Scheduled tasks are to do something at a certain time point in the future (in terms of English grammar, "will do" something), not to keep a condition for a certain time period in a length of future ("is going to be" something)
According to ServerScheduler::addTask and TaskHandler::__construct, the task handler is automatically set when the task is scheduled. Are you sure $task->setHandler($h) is required?
I had this issue a while back, and had to call setHandler() manually, or no cancel... Looks like it was fixed in this commit from october https://github.com/pmmp/PocketMine-MP/commit/7145e16bcea80024ad599a5bd938a1a005b34090
Could you please read? It clearly states it is the one from forums.pocketmine.net, just reposted. It's the same person too, in case you wonder.