This tutorial covers writing a commonly used gameplay mechanic in action games: cooldowns. A cooldown is a tool to limit the frequency at which a player can do something. This may be something like using an ability such as healing or writing chat messages. It allows you to slow the rate at which players do things either for gameplay balancing purposes or to prevent spam.
First I'll example the bad way of doing a cooldown by using
SetTimer to update state.
Say for example you have a specific action that can only be performed once every so many seconds, I see a lot of people (including Southclaws, many years ago) doing something like this:
Now this is all well and good, it works, the player won't be able to do that thing again for 10 seconds after he uses it.
Take another example here, this is a stopwatch that measures how long it takes for a player to do a simple point to point race:
These two examples are common and they may work fine. However, there is a much better way of achieving both of these outcomes, which is more way accurate and can give stopwatch timings down to the millisecond!
GetTickCount() is a function that gives you the time in milliseconds since the server process was opened.
gettime() returns the number of seconds since January 1st 1970, also known as a Unix Timestamp.
If you call either of these functions at two different times, and subtract the first time from the second you suddenly have an interval between those two events in milliseconds or seconds respectively! Take a look at this example:
Or, alternatively the
There's a lot less code there, no need for a public function or a timer. If you really want to, you can put the remaining time in the error message:
(I'm using SendFormatMessage in this example)
That's a very basic example, it would be better to convert that MS value into a string of
minutes:seconds.milliseconds but I'll post that code at the end.
Hopefully you can see how powerful this is to get intervals between events, let's look at another example
In this example, the tick count is saved to the player variable when he starts the race. When he finishes it, the current tick (of when he finished) has that initial tick (The smaller value) subtracted from it and thus leaves us with the amount of milliseconds in between the start and the end of the race.
Now lets break the code down a bit.
This is a global variable, we need to use this so we can save the tick count and retrieve the value at another point in time (in other words, use it in another function, later on)
This is when the player starts the race, the tick count of now is recorded, if this happens is 1 minute after the server started, the value of that variable will be 60,000 because it is 60 seconds and each second has a thousand milliseconds.
Okay, we now have that player's variable set at 60,000, now he finishes the race 1 minute 40 seconds later:
Here is where the calculation of the interval happens, well, I say calculation, it's just subtracting two values!
GetTickCount() returns the current tick count, so it will be bigger than the initial tick count which means you subtract the initial tick count from the current tick count to get your interval between the two measures.
So, as we said the player finishes the race 1 minute and 40 seconds later (100 seconds, or 100,000 milliseconds), GetTickCount will return 160,000. Subtract the initial value (Which is 60,000) from the new value (Which is 160,000) and you get 100,000 milliseconds, which is 1 minute 40 seconds, which is the time it took the player to do the race!
Recap and Notes
So! We learned that:
- GetTickCount returns the amount of time in milliseconds since the computer system that the server is running on started.
- And we can use that by calling it at two intervals, saving the first to a variable and comparing the two values can give you an accurate interval in milliseconds between those two events.
Last of all, you don't want to be telling your players time values in milliseconds! What if they take an hour to complete a race?
It's best to use a function that takes the milliseconds and converts it to a readable format, for instance, the earlier example the player took 100,000 milliseconds to do the race, if you told the player he took that long, it would take longer to read that 100,000 and figure out what it means in human-readable time.
This package contains a function to format milliseconds into a string.
I hope this helped! I wrote it because I've helped a few people out recently who didn't know how to use
gettime() as an alternative for timers or for getting intervals etc.