Timers are for chumps - GS optimization tips

1356

Comments

  • domeniusdomenius Member Posts: 108
    These timers do not exhibit run to completion behavior. You can trick the engine into giving you similar functionality, or work around it. In some cases you may have to use run to completion timers, but avoid this whenever possible.

    You can use a separate rule and an extra attribute to do this. Essentially you create a timer with a Boolean toggle rather than the actual code you want run, then place the code in a simpler rule toggled by the Boolean. Once the code you want run is completed (you may need to track this with another rule) you can toggle the Boolean off. As the Boolean cycles, your events are fired and are not limited by the cycling of the math timers themselves, which can in turn give your events enough time to run properly.
  • glyniusglynius Member Posts: 231
    Hey...this is great tip, i replaced all my timers on my new game, i had everywhere timers because needed, and now i see great difference on performance and speed. THANKS!!!
  • ericzingelerericzingeler Member Posts: 334
    edited December 2012
    This is a great tutorial. I have an addition that I picked up a while back on the forums (I'm not claiming this as my idea or creation, just stumbled across it).

    The following will allow you to loop extremely fast while also waiting for your instructions within the loop to complete:

    2 Attributes:

    1. timeStamp (real) = 0
    2. loopSwitch (boolean) = false

    2 Rules, + activator (optional):

    1. Loop Rule:

    If Self.Time > timeStamp

    [Your instructions]...

    @end of loop
    Change attribute loopSwitch = 1

    2. Loop Switch Rule:

    If loopSwitch = true

    Change attribute timeStamp = Self.Time + 0.005
    Change attribute loopSwitch = 0

    Activator:

    If you don't want the loop to fire on actor start and want to start it with an action, change the loop condition to >=

    example: Self.Time >= time.Stamp

    Then, throw this in some other outside action:

    Change attribute timeStamp = Self.Time + 0.005

    Note:

    I always use .005 as it seems fast enough, but it appears to work all the way down .00001.
  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949
    @eezing. This is awesome! I've been trying to figure out a faster loop method because I'm using it to build and search tables so often. In a quick test (see attached), it's twice as fast as my current method. Thanks for posting that.

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

  • carlblanchetcarlblanchet Member Posts: 755
    Since I'm replacing many many timers, won't all the extra self attributes reduce performance too? Or do self attributes make that little of a difference to the performance?
  • domeniusdomenius Member Posts: 108
    The addition of attributes does have a performance overhead, but it is significantly less than what a native timer takes. The difference is that the attributes use physical memory to store, whereas timers use processing power. From experience, I can say that processing power is more often our limiting factor on performance than physical memory.

    The memory used by a single attribute is fairly small, especially compared to game assets such as graphics or sounds. In practice, the memory overhead of these timers is nearly negligible.
  • LeonardDeveloperLeonardDeveloper Member Posts: 4,630
    Pretty Juicy stuff @domenius
    A pleasure to bringing this kind of quality to the community - Keep it up!
  • adilsulaimanadilsulaiman Member Posts: 2
    Hey @domenius
    Electric brain wave to delve so deep into the core architecture of this baby and gettin us a refined way of speeding up our games man really. I am having one problem, the alternate mod way for creating the every timer works great when you use real numbers but when i try to fetch a number for timing using the rand function, the timer goes haywire and just does not time correctly.

    For example, i am looking to spawn a character after a random duration of say 5-10 seconds. I have my mod1 set up to 0.05 sec. When i create a when mod1=self.time%rand(5,10) rule, several characters are spawned 1-2 seconds after the other. This is peachy if you use a static number which is say 5 seconds in place of the random function. :/
  • SocksSocks London, UK.Member Posts: 12,822
    @adilsulaiman

    Try generating the random number outside of the rule.

    So . . . Change attribute 'MyRandomNumber' to random (5,10)

    Then . . . If mod1=self.time%MyRandomNumber . . .

  • domeniusdomenius Member Posts: 108
    @adilsulaiman. If you are using longer iteration times, such as in your example, the easiest fix is to create a new mod value. If you simply set mod to a larger value, for your example I would try 1, it should work just fine.

    The problem you are encoutering is caused by floating-point accuracy issues. Since you are feeding rand an integer value, it outputs an integer value. When we compare the integer to a very small number (this case, 0.05) the equation is never given a chance to flip between its on and off state. You might be able to fix this by simply stating rand(1.0,5.0), though I've had mixed results in practice. The best solution is modifying the mod value; as stated above.

    Let me know if it works!

    Domenius
  • adilsulaimanadilsulaiman Member Posts: 2
    @Socks , now my spawning engine purrs happily, thank you!

    @domenius That did not do it no, instead i saw three actors instead of just the two spawning at 1 second intervals between each other. Although i understand the anomaly and i would think that playing around with the mod would ultimately fix this irregularity but the @Socks way is quicker albeit at the expense of another native variable!

    Thank you guys!
    Adil
  • EricTippettEricTippett Member Posts: 45
    This seems to work for almost everything.
    However, I tried the For Timer Workaround for an animation and the animation no longer animates. It works perfectly in the Timer Behavior, but not with this.
    I wasn't sure why and it works for everything but animations.
    Anyone have a solution for this or should I just go back to the For Timer Behavior?
  • master200012master200012 Member Posts: 372
    I'm not positive, but I'm guessing when you used the For timer behavior, "Run to completion" was active? If so, I think (-I think-) that this workaround only does this without the "run to completion active," in which case your animation will stop after a certain point.

    But I'm not sure of this. Can anyone confirm?
  • dr2391dr2391 PRO Posts: 78
    Ok sorry if this has been asked/stated in this thread already but I've been using something like

    if mod1 > self.time%.1

    change attribute
    self.size.width to 100-( self.Position.Y /9)

    so that the actor gets smaller as it moves up the screen. I did this because I read that constrain is performance heavy like timers. My question is, is this way any better than using a constrain instead?
  • domeniusdomenius Member Posts: 108
    @dr2391

    Yep, using this technique as a drop-in replacement for constrains is very efficient, and advised wherever possible!
  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949
    Here's an updated Study of Loops that demonstrates (and compares speeds of) several looping algorithms that have been mentioned.

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

  • KiwiLeeKiwiLee Member Posts: 181
    @tatiang - Thanks for this. I'll give some of these a whirl!
  • SingleSparqSingleSparq Member Posts: 1,339
    @tatiang not sure why but your zip always shows up as an image and not downloadable on safari or Firefox for me. On iPad I can click it and the text shows as a link that I then mail to myself to get it to download but not sure why it never works on regular browsers.(or its just mine?)
  • SocksSocks London, UK.Member Posts: 12,822
    Here's an updated Study of Loops that demonstrates (and compares speeds of) several looping algorithms that have been mentioned.

    @tatiang

    Great stuff tatiang, really interesting stuff.

    The 'time stamp' method seems like the way to go if you want very fast iterations, I noticed that changing the interval time from 0.005 to 0.00001 made it no faster, I'm guessing somewhere around 0.005 is this method's limit ?
  • RThurmanRThurman Member, Sous Chef, PRO Posts: 2,879
    The 'time stamp' method does seem to be the fastest looping method. The interval threshold seems to be at about .01. Anything higher (for example .02) will almost double the time it takes to complete 500 iterations. But anything lower (for example .005) does not appreciably increase the speed. Anything under .01 continues to fluctuate around 9-10 seconds to complete 500 iterations (including as low as 0.0).

    Interesting stuff!
  • SocksSocks London, UK.Member Posts: 12,822
    edited January 2013
    @RThurman

    Just tested this, you are pretty spot on, the limit seems to be about 0.01 - I tested 0.015 against 0.01 (running at the same time) and it takes around 2,000 iterations before you see 0.01 pull very slightly ahead - so 0.01 seems to be number.

    I wonder is there is any advantage/disadvantage to using 0.01 as opposed to 0.0001 as they both loop at the same speed, would 0.01 give the loop more time to execute its function/contents ?
  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949
    @SingleSparq I haven't heard that from other people, but if you ever need the .zip file just let me know and I can send it to you directly. I've been able to download the .zip after I post it using Firefox.

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

  • KiwiLeeKiwiLee Member Posts: 181
    @SingleSparq I found that I needed to log in to the forums for the ZIP to be recognised as a downloadable file rather than a picture in Safari on my mac!
  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949
    I found that I needed to log in to the forums for the ZIP to be recognised as a downloadable file rather than a picture in Safari on my mac!
    @SaladStraightShooter I was able to verify this.

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

  • SocksSocks London, UK.Member Posts: 12,822
    edited January 2013
    @tatiang

    Once again, cheers for uploading your 'A Study of Loops v0.2 2' file, I've now managed to use parts of it in a project I am working on and it's made an enormous difference.

    :)>-
  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949
    @Socks, you're welcome. As I wrote in the project file, I can't take credit for any of it, but I did decide to compile it in one place.

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

  • RThurmanRThurman Member, Sous Chef, PRO Posts: 2,879
    edited January 2013
    I wonder is there is any advantage/disadvantage to using 0.01 as opposed to 0.0001 as they both loop at the same speed, would 0.01 give the loop more time to execute its function/contents ?
    You reach the theoretical limit of GameSalad at .015. (That's about 60 frames a second.) Anything less isn't going to speed up a processor that is set to fire at around 60 frames a second.

    About the fastest loop GameSalad can achieve (using the method @ericzingler describes above) would be something like this:

    When self.Time > self.oldTime
    --(Do your thing. Whatever it may be.)
    --Change Attribute: resetOldTime To: true

    When resetOldTime is true
    -- Change Attribute: self.oldTime To: self.time
    -- Change Attribute: resetOldTime To: false
  • SocksSocks London, UK.Member Posts: 12,822
    edited January 2013
    @RThurman

    Cheers for the response.

    You reach the theoretical limit of the GameSalad at .015. (That's about 60 frames a second.) Anything less isn't going to speed up a processor that is set to fire at around 60 frames a second.
    Got it ! So even though an iPad (for instance) can run a lot faster than 60 fps - GameSalad is set up to run at a maximum frame rate of 60fps ?
    About the fastest loop GameSalad can achieve . . .
    Yep, your example is pretty much what @tatiang had in his example.
    By the way, the limit of loop speed seems to sit somewhere around 0.013.

    In the time it takes 0.008 to reach 10,000 iterations . . .

    0.008 gets to 10,000
    0.010 gets to 10,000
    0.012 gets to 10,000
    0.013 gets to 10,000
    0.0135 gets to 9998
    0.01355 gets to 9996
    0.014 gets to 9994
    0.015 gets to 9976.

  • SingleSparqSingleSparq Member Posts: 1,339
    @tatiang okay that makes sense! I'm always logged in on my iPad but safari Mac never keeps me logged in. Mystery solved.
  • dukie234dukie234 Member Posts: 12
    Hey guys I've been trying to used this new timer method to replace my timed animation. I usually use two GS timer to do the animation. "EVERY" timer for generating random animation time, and "FOR" timer nested in it and run to completion checked to play the animation. I've been using this new method of timer to replace GS standard EVERY timer and nested the the new FOR method in it but its not working.

    When I used the new EVERY timer alone the animation would stop prematurely (i'm using 6 images with 10fps/sec), this is also happened when i'm using GS EVERY timer, thats why i put another GS FOR timer to run the animation for a given time. Now i know that this new EVERY timer method doesn't support random formula directly and you must created another rules with attributes to store the random number, so i takeout the random number and use static number instead to no avail.

    So how can that kind of nesting method of timers can be replaced with the NEW and improved timer? How can I select the frame rate of animation using this new timer method?

    Cheers! ;P
Sign In or Register to comment.