HeroEngine Forums
Welcome, Guest. Please login or Register for HeroCloud Account.

Author Topic: Theory of a Timer part 1  (Read 1794 times)

keeperofstars

  • General Accounts
  • *
  • Posts: 998
    • View Profile
    • StarKeeper Online
Theory of a Timer part 1
« on: Oct 11, 15, 09:56:25 PM »

Wanted to provide another round of thought and guideance on how to utilize timers efficiently. All to often I help / aid teams that have went overkill on timers. Timers seem like a natural or simplistic way to keep track of time, but that is not the use of a timer. However, so often I will see ability systems driven by timers, etc.

Timers have one simple purpose and only one really trying to use them for something other than this one simple purpose probably means you need to rethink why you are using a timer. That purpose is to have an action / piece of code run at a recurring time over and over for a duration of time.

While a lot of people can understand that purpose they don't understand it's full meaning or what application it leaves. So lets cover a few examples of when to use timers and when to not use timers. Then we will do a few deep dives into a couple of situations where i frequently see timers inappropriately used and ways to remove the timers from game play.

Good use of timers

  • GUI refresh - there are lots of things that need refreshed on the HUD / GUI use a single timer to update them all at once.
  • Player Health regeneration - using a timer to preform health regeneration event
  • Performing a Channel type ability or resource drain - so for example while sprinting consume stamina, or while holding down the fire button decrease ammo and fire weapon.
  • System Wide counter / status check - I'll explain more in deep dive, but this is a timer used by a system to preform updates / refreshes to that system.

Bad use of timers

  • Tracking Cooldowns - don't use individual timers to keep track of cooldowns for anything
  • Keeping track of time past in game - don't use timers to determine how long it has been since an event occured or how long between events
  • Checking or clearing a true / false switch - I've seen lots of uses where a timer will be used to say after X time do Y event. This leans back to using system wide status check but not on an individual bases.

Ok so lets dig into why I say good and bad. I think the best example which covers a common scenario that frequents bad timers, and contains a solution that is transfering a timer to a good scenario is the best way to start.

That is the cooldown timer. Often times you will see people using a timer to determine when an ability is available for use and how long it will be before that ability is available again. We have all seen it you use the ability the icon grays out and you get a nice 20 seconds appearing over the ability and counting down second by second. Once it's complete the icon goes bright again and can be used.

Lets review the setup for the timer in the bad use scenario.
Ability is used
Ability gray's the icon
Sets can use value to false
starts timer
Timer ticks once a second and updates the text value of the gui field with how much time is remaining on ability.
When timer ticks and the time is zero timer sets can use value to true and un-gray's the ability icon.

The problem with that is in most case scenarios there are at least 5 - 10 abilities for a player regardless of game play type. In RPGs usually at least 10. In FPS usually a reload timer happens when bullets out, or in case of some weapons when used. Etc. In a social game like farmville the thought is to use a timer for each crop. In this case a massive amount of timers going on.

So how do we fix the timer issue with a more efficient manner?
We create a system timer. You might as what is a system timer? It's a timer who's job is to preform a wide variety of updates across a set of items at one time instead of several timers doing things individually.

Lets break down the cooldown timer. The reason we need a timer is to update the GUI and provide feedback to the player about the cooldown remaining on the ability, and to un-gray the ability when we can use it again.
We can accomplish all of that by creating one timer that refreshes our ability bar. So instead of each ability getting it's own timer we create the ability bar refresh timer. You might ask well how would that work. So lets break down all the components that end up being needed.

At player login we check all abilities and see if any are presently in cooldown. If so we start the ability bar timer and add the ability's ID to our "oncooldown list", if not then there is no point to start the timer till the player uses an ability. Once started the timer ticks once ever 0.5 seconds. You can adjust this time frame depending on use of refresh. But for a cooldown / ability timer 0.5 will be plenty cause we only displaying whole seconds to the player in most cases.

So lets walk through the ability setup some then we will cover the action of using ability.
The ability will need a few fields setup on it to manage.

Time ability performed
- this will be a timestamp field that gets set when the ability is used
Cooldown Duration - how long the cooldown needs to be.
Cooldown time leftd - This field might be optional depending on how you want your gameplay setup.

Now lets talk though the using ability. This is assuming a player has not used any ability at this point.

  • Player clicks on AbilityA
  • TimeAbilityPerformed gets set to current time
  • We add AbilityA to the list of abilities on cooldown. - I usually just store this as a field on the player node but can be stored anywhere with the player.
  • We start AbilityRefreshTimer set it's tick to be 0.5 seconds
  • OnTick forEach item in the AbilitiesOnCooldown field we check the current time - TimeAbilityPerformed field and check to see if that value is greater than or equal to cooldownDuration field
  • If true we remove AbilityA from Abilities onCooldown and check if the list is empty if so we stop the refresh timer. We un-gray the icon and set CooldownTimeLeft to zero.
  • If false we take the value of currentTime - TimeAbilityPerformed and set it as our new cooldown text, and wait for next tick

Now you might notice the Cooldown time left field wasn't used in that case if it was false. We will set that field mainly when the player has an ability on cooldown and exited the game, or disconnects etc. The reason for that field is to hold the time in the cooldown remaining so when the player logs back in we can adjust our time's to keep the cooldown in effect. This is where it depends on your game structure on whether or not you need that field.

You will notice we are maintaining a list of abilities on cooldown. We do this cause a player could have a massive list of abilities that would need checked we don't want to spend time or resources checking them all and doing the time comparisons on them, if they aren't in cooldown. This list of items is also helpful in other ways, i've used it to list off to my party members what abilities I can activate. Can be used also to block people from swapping in and out abilities on cooldowns as a way to bypass cooldowns. So it has lots of other uses as well.


Let finish out two more pieces to this system.

When a player logs off we will need to Set the CooldownTimeLeft to just that how much time is left on the cooldown. Which is the same calculation we do onTick with the timer.


When a player logs on we read through the list of abilitiesOnCooldown and set their abilityPerformed equal to currentTime + (cooldownDuration - CooldownTimeLeft) this will reset the system to be ready to go for the timer.
Then start the timer again let it run normally.

Lets quickly talk about some points of concern.
Such as where to run the timer. There is no need to run the timer on the server in most cases. Especially in the case of a cooldown timer. The first question I usually run into is how do you prevent cheating. Well they can update / alter that timer job all they want, the timer just making a call to the fields on the client to see if they are able to cast the ability. If they hack the ability fields on the client, you will still check on the server before you apply damage to another player that the fields are valid / clean. So at worse case you would get hit with more server validates than expected, but the amount of resources saved by running the timer on the client will be well worth it. You could be saving your servers the processing power that is equal to 10 million plus timers. That isn't something to pass over lightly. And it's something you will still have anti-cheat protection in for.

The next question i get is won't the 0.5 second timer prevent people from using their ability the moment it's available and for that answer I say. Yes, but... here is where common usage of players come into play. You have two options to work around this some. Lower the refresh to 0.25 keeping in mind a normal player won't be able to spam a keyboard, have that travel to the server, and get a feedback in less than 0.25 seconds realistically.

The other option is to change the aspect of when you allow for a check on the ability to be used. You can block the check all together if the timer hasn't cleared the ability, OR you can allow any attempt to use the ability to be tested to see if it's valid for use. Both are ok and valid as the main check will first happen on the client before being sent to the server for validations. I tend to lean on setting the timer to 0.5 seconds, or even 0.75 to keep the tick processing down and then allow the player to smash the ability button and run the checks till it's valid. The processing weight for the client that smashes will be the same, but for the player that doesn't button smash will save resources.

So the question is if the resources for the timers are being managed by the client why bother setting up the extra fields and such on the server and client to manage not using a timer. Well we addressed you wouldn't want to run a timer on the server in this case, so we need the fields on the server to prevent the clients from cheating, and since we need the fields there and we need them on the client it makes sense to not use a timer and save the client the resource hits. Which can add up greatly.

That will end part 1 for now. Wanted to see if there were follow up questions / discussions, and to break the bigger tutorial / theory up some. Walls of text can get boring at times. In part 2 I'll cover a case when a timer is the right option and why we want to use it instead of some other method.


Logged
[img]http://screencast.com/t/x7btcSSyp3h0[\img]

nocake

  • General Accounts
  • *
  • Posts: 404
    • View Profile
    • BlightMMO
Re: Theory of a Timer part 1
« Reply #1 on: Oct 13, 15, 01:11:52 PM »

Is this a good tl;dr?

Use Timestamps and a single system timer on the clientside to compare to the timestamps at a feasible interval for your game type. Don't replicate the timer to the server, replicate the timestamp and then once the client requests activation validate against your timestamp for a final server validation.

keeperofstars

  • General Accounts
  • *
  • Posts: 998
    • View Profile
    • StarKeeper Online
Re: Theory of a Timer part 1
« Reply #2 on: Oct 18, 15, 08:02:48 PM »

yes, that works / is a good setup, cause you want to do server validation at point of adjustment to things. so like during the final aspects of an attack, but no point to haggle the server with keeping tabs on things. just when you need to validate the data before it makes a lasting game change. Note change.
Logged
[img]http://screencast.com/t/x7btcSSyp3h0[\img]