Chronologically confusing time managementFiled Under: Articles, Discussion, Jedi Wing 2, Updates
Yeah, StridesLib has been facing with some wierd time control issues with its cTimer class for a long long long time. So why hasn’t it blown up in its games yet? That’s because, no one really bothers! Yeah, as long as the timer doesn’t screw up their game or make them lose unfairly, I doubt I’ll ever get complaints.
So what’s so damned wrong with cTimer? Check it out!
The original cTimer class had a decent set of methods, attributes and algorithms to keep things simple but yet, being able to effect some pivotal changes in the game itself.
Its main objective: Count time without being an ass to the CPU.
While it’s a nice class to have, it does suffer from a series of strange problems. For example:
1) Who updates the time stamp value in the class?
2) It inherits from cGameObject, therefore, it has all the event handlers exposed to it for cGameObject managers to call and update (ie, via onExecute(), onRestore() ), again who calls these methods and how many times would it be called?
3) The start time stamp doesn’t get updated corrected during a deactivation event, ie, (alt-tab, Ctrl-Alt-Del, stand-by and hibernate) for some reason, leading the game to suddenly “increase” in speed in which the timers are supposed to block against. This doesn’t imply increase in framerate, it means that the effect of the waiting times technically disappear from cTimer itself.
What’s the problem?!
Problem is, there was no clear cut management or authority to handle cTimer. This is because, cTimer was designed to be an independent class or a dependent class using events.
When this happens, some things are expected when independent, other things when dependent.
This leads to a whole load of bullshit. Object Oriented programming shouldn’t be used this way!
The root problem of this class is,
1) Start time tick doesn’t get updated correctly
2) No visibility as to who is updating cTimer
3) There’s no way to determine how long the application has been deactivated once. Yes, believe me, there is no way when you put it into cTimer.
The solution?
It took me really a long time to come up with a solution that is optimized for memory and speed at the same time.
So how to do it? Simply, have a global starting time tick variable.
Step 1:
Set initial start tick - eg, 100200
Step 2:
Use cTimer as per normal, start stop watch or count down timer. There’re some exceptions here, that is, whenever you reset the cTimer instance’s own start time tick, you have to do this:
startTick = System.getTick() - initial start tick
- System.getTick() (not real code) will return the latest tick which is definitely higher than the initial start tick.
- So let’s say the latest tick is 300200, initial tick is 100200, cTimer’s start tick will be 200200.
Step 3:
In the updates which EVERYONE has to call, which is also the onExecute method, the check for timer must also change.
- If current latest tick is, let’s say 1000200 and initial tick is 100200, timer’s own start tick is 200200, timer limit is 600000 ticks, then,
- Difference is 1000200 minus ( initial tick + start tick) greater than time limit
- Meaning, 1000200 - ( 100200 + 200200 ) > 600000 which is true in this case, then the timer is done.
Step 4:
What if there’s a pause in the game with deactivation? The solution is simple, simply add the deactivated ticks directly into the initial tick and that’s it! cTimer will automatically add itself with the latest updated initial tick which is updated when the game is restored.
This will correctly update the timings without having to resort to a myraid of stupid management techniques.
Sometimes, the simplest change lead to the solution far quicker than sophisticated ones.
Lesson learnt: Don’t think complex just because you think it’s complicated.
Have fun!
Jeremy
- Permalink
- Admin
- 15 Feb 2009 1:44 AM
- Comments (0)