An efficient way of counting down time across multiple objects

BacktothisBacktothis Member, PRO Posts: 75

We have 10 objects. At any given time, some number of them, say X of them, will be in "Countdown Mode". When this happens, they should be decrementing a global time variable, call it CountdownTimer.

So let's say 1 object is in countdown mode. Then the timer should be decreasing in time as long as the object stays in countdown mode. So after 1 second of countdown mode, the timer has lost 1 second, etc. Now let's say we have two objects in countdown mode. Then for every amount of time those objects stay in countdown mode, the timer loses twice that amount of time. And so on, the countdown timer loses time in a linear fashion.

Right now the way I have it working is that when an object goes into countdown mode, a timer is triggered within the object which every 0.1 seconds subtracts 0.1 from CountdownTimer. It works, but it looks like sometimes the timer is off just a bit. Is there a better way of doing this?

Comments

  • HopscotchHopscotch Member, PRO Posts: 2,782
    edited March 2014

    A very well defined question! +10 for you :D

    The "just a bit off" will probably always happen if you use timers.

    I would base it off the game.Time and track the difference while "Countdown Mode" is active.

    Make an Attribute self.StartTime (real) in the actor/object.
    
    Start the object with a Change Attribute self.StartTime to game.Time
    
    Now you can have a Timer (every 0 secs) 
    
        A Rule which checks for "Countdown Mode" = True
    
            Then substracts the elapsed time (game.Time-self.StartTime) 
            from the global time variable.
    
            Then setting self.StartTime to game.Time again.
    
        In the Else section 
    
            Change Attribute self.StartTime to game.Time
    
    end if timer
    

    This still uses timers, but the countdown will be immune to any lags or spikes.

    Alternatively, keep track of the number of objects in "Countdown Mode" and subtract a multiple of seconds accordingly.

  • BacktothisBacktothis Member, PRO Posts: 75

    I've tried keep track of the number of objects and doing it that way, it works but obviously it's not quite as continuous as I'd like.

    The other method you mentioned is actually the first one I tried. The weird thing is that it would sometimes work, sometimes not work, and sometimes halt randomly at some point. I'll try it again soon as I get back on my mac, but the behavior really made no sense to me. In general I've had really odd behavior with rules that would be constantly triggered for some period of time... although I did not have an else behavior specified. I'm not sure if that would affect things, but I'll try it again.

    And actually I used the object time rather than the game time.

  • HopscotchHopscotch Member, PRO Posts: 2,782

    Theoreticly both game.Time and self.Time should work, I have noticed some odd behaviours with self.Time though.

    You say that " it would sometimes work, sometimes not work, and sometimes halt randomly at some point". Did you have the rule inside a timer that runs every 0 seconds and is set to "Run to Comletion"?

  • BacktothisBacktothis Member, PRO Posts: 75

    The condition on the rule was just isActive = true, there was no timer. Just as long as that was true it would subtract time and add. Gonna try doing it with game.Time right now though.

  • BacktothisBacktothis Member, PRO Posts: 75

    Well, when using self.Time, nothing happens. When using game.Time, it's... it's definitely taking time off at about 10 times the rate it's supposed to lol.

  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949

    Try this.

    New to GameSalad? (FAQs)   |   Tutorials   |   Templates   |   Greenleaf Games   |   Educator & Certified GameSalad User

  • BacktothisBacktothis Member, PRO Posts: 75
    edited March 2014

    @tatiang yep that method works. The thing is, I'm representing time as a sort of hp bar, rather than a number. So I'm looking for the best way that shows the bar decreasing as continuously as possible, rather than in a chunky way which is what would happen in your countdown timer.

    So just decreasing the timer interval in your example wouldn't work, because let's say you lowered it to something low like 0.3 seconds. Then when 3 blocks are active, you would be dropping by 3 "ticks" per 0.3 second, whereas the ideal behavior would look like 1 "tick" per 0.1 second. Same effect, but more continuous.

    edit - And that is why I placed a timer within each block, so that it would count down in a sort of continuous manner. But it seems timers are... rather .. not precise when used in such a fashion.

  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949

    There is a bug when decreasing a counter attribute with a timer.

    Still, this might work (attached).

    New to GameSalad? (FAQs)   |   Tutorials   |   Templates   |   Greenleaf Games   |   Educator & Certified GameSalad User

  • BacktothisBacktothis Member, PRO Posts: 75

    Hmm that would work. What's the bug involving the timer?

  • BacktothisBacktothis Member, PRO Posts: 75

    Although, now that I think about it, this is actually just a smaller case of the chunky behavior. True with 3 objects, at 0.1 second intervals, it'll look ok. But in my game often you will by sheer chance get 8 or more, so then you are going down in 0.8 second chunks which is still pretty chunky.

    I guess it gets back at the continuous vs discontinuous behavior. I could, say, modify your code so that it changes the timer interval so that under the 99% worst case condition, it would never decrease more than 0.1 at a time, but the timer would get quite small, around every 0.01 seconds, which hasn't been too reliable in my experience in being any better than the method I'm using now.

  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949

    Sorry, I should have explained. When doing something like Every 0.1 seconds change attribute game.timer to game.timer - 0.1, if you put a Display Text with game.timer in the actor, you'll see fluctuations of say 1.0, 0.9, 0.8, 0.7111111111, 0.6, 0.5, 0.43564313, 0.3, 0.2, 0.1, 0. I have a thread on this somewhere. Still, this shouldn't negatively impact a bar image.

    New to GameSalad? (FAQs)   |   Tutorials   |   Templates   |   Greenleaf Games   |   Educator & Certified GameSalad User

Sign In or Register to comment.