metro

The Smoke & Mirrors of Good Countdowns, Part 2

Final product image
What You’ll Be Creating

Last time, we looked at countdowns in games, how they are set up, and what elements you can use to make them more engaging. There are much more than will fit in a single article, though!

This will continue from Part 1, which is why we will start at number seven.

Ready? Let’s go!

7: Have a Different Constant Ticking Speed

This is a
simple trick that does not even necessitate you lying to the player. You
just say “when the timer runs out” and show a ticking clock. What you
do not mention is the unit that is shown.

If you show
a “10”, the player will intuit this is
10 seconds, but the number can decrease slower than seconds would. If
you modify the value with a 0.5 multiplier, for example, it will run out after 20
seconds instead of just 10.

You can look at how this works in my Ludum-Dare game, Every Ten Seconds a Kitten Drowns.

A timer in Every Ten Seconds a Kitten Drowns
A timer in Every Ten Seconds a Kitten Drowns. The timer is slow enough to give the player a fair amount of time while still appearing very low

The
theme of the jam necessitated that 10 seconds are used, but 10 actual
seconds are a much-too-low amount of time to accomplish something
meaningful.

8: Adapt the Ticking Speed During Gameplay

This also works better if time units are not mentioned and the player is just given a rough idea of “until this happens”.

If
you have a series of panels that light up to show timer progress, you do
not need to activate them at the same rate. In fact, it will become more
intense if the first few light up quickly, and the latter ones have
more time between them. In the heat of action-packed gameplay, the player
will not realize this and will have a much more intense experience.

This
should not be employed with actual time units, as players might feel
cheated and lied to. Do not break the player’s trust in your system.

This can be seen in one level of Starfox 64, where the player has to defend a position against an approaching giant ship.

Minimap in Starfox 64
Minimap in Starfox 64.
The attacking mothership (the black circle) is moving towards the base
in the middle, giving the player a rough ticking clock of how much time
is left to destroy it

On the first glance, you get a rough idea of how much time is left, but the ship itself
appears to move at different speeds and not in a straight line.

The timer is in essence being adapted on the fly, the process of which is hidden behind smoke and mirrors.

9: Use Sounds

Countdowns do not have to be purely optical! A beep sound every few seconds will greatly enhance immersion.

Once
you have that, you can also adapt the frequency once a certain amount of
time has passed. If the beep occurs every five seconds, in the last 30
seconds of the timer the player will be notified without having to look
at the number and mentally calculate how much is left.

Similarly,  it also helps if a character comments on the progress. Having someone
say “We are halfway done!” gives you a well-framed piece of information
that is much easier to understand than parsing it from a readout.

10: Use Scaling Visuals

This works very well when the counter
is nearing its end. Whenever another second elapses, scale up
the entire counter for half a second.

In addition to color and sound, this will make it much juicier.

11: Do Something When It Reaches Zero

Make
sure a timer never goes negative—this will be confusing to a lot of
people and seem like a bug, as bugged, badly-created timers tend to do
that.

Having it flash would be a nice touch, as it again underlines the point of it having just run out.

If you have a positive timer, it is a fun element to just let it keep running and use that element as a high-score. The game Devil Daggers does a similar thing, where the main goal is “Survive 500 seconds”.

Gameplay from Devil Daggers
Gameplay from Devil Daggers

What Not to Do That Would Break the Player’s Trust

Once the rules of a timer have been established, they should remain roughly consistent,
with more leeway being allowed the less exact a timer is. The main
question should be, “How is this hidden rule benefitting the experience?”

When you slow down a timer in the last three seconds, it will make the
situation more tense and give the player a few more actual seconds to
accomplish things. Randomly slowing it down in the middle, or speeding
it up, will only break the player’s trust in your rules.

Let’s Build It

This will continue with the code-base from the last tutorial and build on it. If you haven’t checked it out yet, do so now! You can also download the finished source on the upper right of this article.

When we last left our timer, it looked like this:

Our time when we last left it

Now, new additions will make it behave more interestingly. We will continue with the countdown.cs-script, which should look like this:

Make It Beep

Let’s make our timer beep every second, so that the player will know it is decreasing even without looking at it.

First,  we need a nice blip sound effect. You can find an audio file in the
source files, or create a nice one using the free tool BFXR. Once you have one, copy it into your asset folder.

Add an AudioSource component to your countdown object via Component > Audio > AudioSource. Add this variable to the countdown script:

You also need to assign the sound file to the soundBlip variable:

Select Blip01

And add this block to the Update function:

This will check whether the timer is at the full second mark, and if so play the sound file.

The
actual workings of this code are a bit more complicated. What it does
is first round the floating-point timer to two decimal points, then
divide it by 1, and see if there is a remainder. If the remainder is
zero, it means the timer has reached a full second, and the blip sound
can be played.

If we do not do this, the system might trigger much more often, which will not be fun and conducive to a good timer.

Different Speed

This will add a multiplier which will reduce or accelerate the speed of the ticking clock. Add this variable at the beginning:

Now find the line that reduces the timer—it’s this one:

And adapt it to look like this:

If the multiplier is below 1.0 the timer will now run slower, and if it’s above 1.0 it will run quicker. Setting it at 1.0 will do nothing.

Try to experiment to find a good value! I feel a slightly lower speed, like 0.85f, will make the player feel the ticking clock more.

Slow Down When Low

Now that we have a multiplier component, we can change it during gameplay!

Go to the color-changing block of code:

Here we already have the conditions where a change in ticking speed would be appropriate, so we can just add it!

When the timer turns yellow at 20 seconds, it will now tick with 80% speed. Once it turns red, it will go down to 60% regular speed. Otherwise, it will be set to 100% speed.

Scaling When Low

Another great way to make a timer running out of time stand out more is to scale it up every passing second when low. Since we already have code that gets triggered every second, we can adapt it further!

First, we need a function to increase and decrease the size of our display. Add this function:

This is an IEnumerator, which is a type of function that can contain wait commands. We need the isBlinking variable to make sure we do not call it multiple times.

Once initiated, it will scale up the size of the object by the factor of 1.4f, wait 0.3 seconds, and then scale down again to the original size.

We call it using this special code:

An IEnumerator needs to be initiated by calling it via StartCoroutine, otherwise it will not work.

The entire block will be called when a second passes, at which point we can check if the timer is low enough to make it blink.

Blink at Zero

Let's do something when the timer runs out. Having it just sit there at zero can be boring, so let's make it blink.

First, we'll need another IEnumerator function:

This will turn the timer on and off in 1.5-second intervals. Trigger it in the block that already checks if the timer is zero.

Before running it, we need to disable the beeping and blinking at zero itself, otherwise that will collide behaviors.

Adapt the conditions in the block to check if a second has passed and also to check if the current time is more than zero:

This will make sure regular blinking and zero blinking work without interfering with each other.

The entire countdown script should look like this:

This will get the job done. You can, of course, make it more elegant and combine the commands into a more efficient code.

Conclusion

Our standard little countdown has become much more interesting and engaging. If you build this once, you can use it and plug it into any project you make, no matter how small.

Now go and put it in a game!

Leave a Comment

Scroll to Top