WARNING: This article was written for Stencyl 2.x. With the release of Stencyl 3.0, some of this information may be outdated. An update to this article may come in the near future.
This is a “Stencyl For Noobs” guide! This is meant to be a good, concise guide for the beginner or a refresher for the more experienced.
Timed Events
What we’re learning: How timed events work, and why they are so tricky to deal with.
Contents
Blasted Timed Events!
How The Delays Work
Six Important Details about Timed Events
* * * * *
Blasted Timed Events!
This has got be one of the greatest thorns in the side for new Stencylers. To the uninitiated, these events look simple to understand. But this is not necessarily the case, particularly when all havoc breaks loose in your code and you don’t have the slightest inkling as to what you did wrong. Thus the reason for this guide. I’m going to equip you with some do’s and don’ts of timed events.
First, let’s establish our two timed events: the “Do After” and “Do Every”. “Do After”, as the name implies, waits the specified amount of time before executing the code within its listener. “Do Every” behaves like multiple “Do After”s, executing every X seconds based on what you specified in the blank.
(GOTCHA: “Do Every”s wait the specified amount of seconds before executing code for the first time; they do not run the first time at zero seconds when initiated. In that regard they truly do behave like multiple “Do After” events.)
This would seem simple enough to understand, but confusion often reigns when you insert this into your code and things go completely haywire. Why wouldn’t code like this work?
If you tried something like this, what would end up happening is once your health got too low, chances are you would be bombarded with a chorus of low health blips over and over again, even if your health went back up above the threshold. What’s the deal?
How The Delays Work
In order to understand just how these tricky timed events work, think of them like time bombs. When you come to one of these events, Stencyl puts the enclosed code in a “time bomb”, sets the timer, and puts it in the background. When the timer expires, it executes the code. “Do After” does this only once, while “Do Every” keeps resetting the timer and re-executing the code (until you cancel that. More on that below.)
Make sense? Now consider the faulty scenario above. Notice how its in the “Always” wrapper? What’s happening is simple: “Always” executes every frame. That means every frame that health is below the specified amount, Stencyl is firing one of our “time bombs” into the background. Twenty frames later, you have have twenty [b]repeating[/b] time bombs sitting in the background.
See, when Stencyl passes over a timed event, it doesn’t care about other “time bombs” its already fired off; it fires off another one (as it should). The same thing happens with “Do After”. If you fire off multiple “Do After” time bombs that are all trying to modify the same piece of data, for instance, they could easily interfere with one another (refer to the introduction of the article listed in #2 below for more on that).
Six Important Details about Timed Events
So how do you manage these slipperly little events? Down below are six things you should keep in mind:
1.) Watch your usages of timed events in the “Always” wrapper. It can be done reliably, but not without some moderate, airtight conditional checking. There is an example below, using the “Do After”. Notice how another “Do After” can’t be fired off until the one before it is done. As such, make sure NOTHING ELSE modifies that waiting boolean.
2.) Cancel “Do Every” loops when you are done with them. The cancel block can be found directly below the “Do Every” block in the palette. Use some sort of conditional INSIDE of the “Do Every” loop to execute the cancel when the time comes. As mentioned before, you don’t want these piling up in the background (there is an example of a “Do Every” with a cancel block in this tutorial.)
3.) You cannot cancel “Do After” once it has been fired off. That is, if you set a “Do After” at five seconds, you can’t come back three seconds later and say “never mind”. This is important to bear in mind for lengthy delays or for scenarios where you might need to extend the time period for repeat commands. Refer to the tutorial mentioned in #2 if you need a way around those restrictions.
4.) When you fire off a timed event, you only set the timer once. This is more relevant to “Do Every” than “Do After”. If you say something like “Do Every (Random Number between 1 and 10) Seconds”, it will select ONE random number and use that the entire time. Randomizing the delay will work better with “Do After”, since you have to make a new one (and thus grab a new random number) every time you want it to fire off. Look at the example for #1; all you would need to do is put the random number block where the delay attribute is to get the basic idea.
5.) Data can change over the course of a delay. Say you create a bubble actor that you want to pop 2 seconds later. Don’t create the actor, wait 2 seconds, and then use “Kill Last Created Actor”. Another actor may have been spawned in that time! A more reliable method would be to store the created actor in an attribute, and then kill it through the attribute. Be warned though: make sure you don’t change the data inside that actor attribute during the 2 second delay either!
6.) Before executing code after a delay, make sure the referenced actor(s) is still alive! As I mentioned before, these timed events are put off to the side for a later execution. If the actor using it or an actor referenced inside it is killed before then, you might run into problems, so make sure you run a conditional for “Self Is Alive” if you foresee a problem or if there is any chance the actor in question will be killed during the delay.
Leave a Reply