Waits in SC2 - oddities and solutions

Discussion in 'Starcraft 2 (SC2) Editor Help' started by Zwiebelchen, Apr 28, 2010.

  1. Zwiebelchen

    Zwiebelchen You can change this now in User CP.

    Ratings:
    +60 / 0 / -0
    Hello everyone. After reading the discussion in the smoothtimers-thread (http://www.thehelper.net/forums/showthread.php?t=149544), I did intense testing on trigger waits in Starcraft II and got some weird results that may be influence map making in the future.

    For all of my tests, I assumed that Timers are accurate - at least if used on a longer period of time. (1 second in that case)
    These are the functions I used:
    Code:
    bool gt_Nahkampfinitialisierung_Func (bool testConds, bool runActions) {
        // Actions
        if (!runActions) {
            return true;
        }
    
        Wait(1.0, c_timeGame);
        TimerStart(gv_t, 1.0, true, c_timeGame);
        while (true) {
            Wait(0.0, c_timeGame);
            gv_i=gv_i + 1;
        }
        return true;
    }
    
    bool gt_UnbenannterAuslser001_Func (bool testConds, bool runActions) {
        // Actions
        if (!runActions) {
            return true;
        }
    
        TriggerDebugOutput(1, IntToText(gv_i), true);
        gv_i = 0;
        return true;
    }
    So here are the things I found out:
    • The game engine consists of 'ticks' of 0.03125 seconds (1/32 of a second)
    • Both Timers and waits can only fire in intervals based on multiples of 0.0625 ... 0 second waits are an exception to that rule
    • It seems that some weird rounding is made for the wait input (I think because of GUI compatibility, which doesn't allow more than 4 digits). The input of 0.0626 will also result in a 0.0625 wait, whereas an input of 0.0627 will result in a 0.125 wait.
    • Using values between two 0.0625 multiples will result in the next higher interval being used, except for said rounding last-digit
    • Hosting games in Battle.net (instead of using the single-player "Test map"-mode) had absolutely no effect on waits. All results I got were exactly the same in Battle.net games. At least with nobody else in the game. However, as Battle.net games behave like ordinary multiplayer games (Higher delay on keypress events than in singleplayer), you can expect that the result will not differ in games with more than just one player
    • A waiting time of 0.00s will expire after 0.03125 seconds.
    • A waiting time higher than 0.00 seconds and lower than or equal to 0.0626 seconds will result in a "true" waiting time of 0.625 seconds
    • A waiting time of 0.03125*3 = 0.09375 seconds can not be achieved, no matter what the input parameter is - only multiples of 0.0625 are possible.
    • Timers get updated AFTER wait ticks

    So basicly, what does this tell us?

    • Using both waits and timers does not make sense, as timers get updated after waits. That means if you fire a 0.0625 second timer and a 0.0625 second wait, the timer will return 0.0625 seconds time left when the wait expired. Either use timers OR use waits. Everything else may cause nasty bugs in your script
    • Waits are able to achieve 32 fps frequencies, whereas timers can only achieve 16 fps
    • Both timers and waits are not able to achieve non-even multiples of 0.03125
    • Both flavours seem to have perfect accuracy in Battle.net - at least when used after these rules
    • Odd multiples of 0.03125 seconds may be achieved by using multiple 0.00 waits after another.


    To sum it up:
    Timer systems are not required anymore. In terms of accuracy, there is no difference between timers and waits. Always remember that timers get updated AFTER waits!
     
    • Like Like x 2
  2. Ghan

    Ghan Administrator - Servers are fun Staff Member

    Ratings:
    +773 / 0 / -0
    Very interesting. Not that I don't believe you, but it would be good to get more people to corroborate this data.
     
  3. Zwiebelchen

    Zwiebelchen You can change this now in User CP.

    Ratings:
    +60 / 0 / -0
    I could give you 100% proven results if I could get people to join my "hacked" games on Battlenet =)
     
  4. Jesus4Lyf

    Jesus4Lyf Good Idea™

    Ratings:
    +394 / 0 / -0
    I agree with everything up to here:
    Remote stopping of an instance of something is best achieved with a "timer" attachment system. I will port Smooth Timers internally to use waits, as I intended if this was discovered.

    For example, say you have a function call, SetFirstPerson(player, unit), then wait 5 seconds and call SetFirstPerson(player, null). While the unit is not null, you have to update the camera periodically. When you call null, it can be difficult to interrupt a wait-loop thread, but if you use Smooth Timers, you can just destroy the instance.

    Just adding my two cents, from my experience. :)
    Imagine using a wait loop, and then having SetFirstPerson(player, null); SetFirstPerson(player, unit) immediately. You would cause a double-up, unless very carefully worked around. ;)
     
  5. Steel

    Steel Software Engineer

    Ratings:
    +109 / 0 / -0
    How fast do things execute using -1 instead of 0? iirc it was faster in WC3.
     
  6. Renendaru

    Renendaru (Evol)ution is nothing without love.

    Ratings:
    +309 / 0 / -0
    Would be willing to if you're on the US Server. o.o
     
  7. Zwiebelchen

    Zwiebelchen You can change this now in User CP.

    Ratings:
    +60 / 0 / -0
    I'm not ... and blizzard prevents us from joining US servers >_>

    @ Jesus: Yeah I forgot about remote destruction. However, you can always just check the break condition after every wait and leave the loop when you need it. But I understand that a remotely deactivated timer might be better in terms of efficiency, as this is a one-time call instead of a periodic check.

    The thing that I dislike about timer systems is, that you need to somehow attach data to the timer, which is unnecesarily complicated in SC2 because you can not simply pass a struct to the timer. That's why - despite the remote control argument - I would still prefer waits over timers.
    But yes, for systems like FirstpersonView, where you do not really need to pass data to the timer callback, timers should be more efficient.
    For other things, especially for those where you do not need remote-canceling, you shouldn't bother to use timers, as waits are usually much easier to use.
     
  8. Troll-Brain

    Troll-Brain You can change this now in User CP.

    Ratings:
    +85 / 0 / -0
    What about this ? (actually to much lazy to test it myself)
     
  9. Zwiebelchen

    Zwiebelchen You can change this now in User CP.

    Ratings:
    +60 / 0 / -0
    GUI doesn't allow negative reals, but I will try again using custom script in some minutes.

    Okay, I tested it now. negative input for waits result in a 0.3125 second wait.
     
  10. Weep

    Weep Godspeed to the sound of the pounding

    Ratings:
    +400 / 0 / -0
    I'm sad because I could actually tell that periodic projectile motion was smoother at 0.02 than 0.03 in WC3. :(

    Does SC2's native graphics motion (eg. for unit's shots) update at the frame rate, or is it capped at 32/sec? If the latter, triggered motion would still appear identical to the game; if the former, it would stand out as subtly choppy.

    For all I know, there's going to be actual parametric motion behaviors for objects in the data editor, though. :rolleyes: [/doesn'thaveakey][/macuser]
     
  11. Saldu

    Saldu New Member

    Ratings:
    +1 / 0 / -0
    concerning the "games with more players":
    See my post here, crashed the game for me with just 2 players.
    I at least can't see something I messed up with my triggers, but if you got a map to test it we could sometime, I'm on europe, too.
     
  12. Steel

    Steel Software Engineer

    Ratings:
    +109 / 0 / -0
    Is there any difference between AI Timer, Game Timer and Real Timer?
     
  13. Zwiebelchen

    Zwiebelchen You can change this now in User CP.

    Ratings:
    +60 / 0 / -0
    Well real timer ticks continue when the game is paused and seem to not be influenced by game speed - which is useful for example for transmissions, where the amount of time needed to read them doesnt go down when the game speed is higher ;)

    For AI time ... i have absolutely no clue. I bet it has something to do with the APM of the AI or the difficulty level.
     
  14. Troll-Brain

    Troll-Brain You can change this now in User CP.

    Ratings:
    +85 / 0 / -0
    Because of the ticks i suppose the very first interval time (loop wait or periodic timer) can be less than 0.03125 and is "random", or i miss something ?
    Hard to test i think, i've no clue how to test it without any custom native like StopWatch natives for wc3.
    EDIT :
    Or maybe all events fire by themsleves in each 0.03125 ticks of game, hmm.
     
  15. Zwiebelchen

    Zwiebelchen You can change this now in User CP.

    Ratings:
    +60 / 0 / -0
    Man, why don't you just read the thread? I mean ... I pretty much tested everything and there is no doubt it's the way I wrote it, because I tested it.
     
  16. Troll-Brain

    Troll-Brain You can change this now in User CP.

    Ratings:
    +85 / 0 / -0
    We simply don't understand each other.
    I've read the whole thread, but maybe it's my lack of programming concepts which confuse you and me.
     
  17. PurgeandFire

    PurgeandFire zxcvmkgdfg

    Ratings:
    +513 / 0 / -0
    JASS:
    //--------------------------------------------------------------------------------------------------
    // Timing
    //
    // -- Time types --
    //
    // Timing functions can work with three different types of time:
    //
    //   Game Time - Takes into account the current game speed, and will pass more slowly at slower
    //               speeds, and vice versa.
    //
    //   Real Time - Passes at the same rate regardless of game speed, and approximates time passing
    //               in the real world for the user.  However, "real" time is still synchronous, and
    //               will therefore be affected by lag due to network or system issues.
    //
    //   AI Time   - Passes at the same rate as game time, but may be paused/unpaused independently
    //               of game time via triggers.  This is most commonly done to pause the AI while
    //               an in-game cinematic sequence is run.
    //
    //--------------------------------------------------------------------------------------------------


    Source: http://paste.sc2mapster.com/1979/
     
  18. quraji

    quraji zap

    Ratings:
    +143 / 0 / -0
    VERY useful information, should be stickied.

    I knew something fishy was up when in my movement system (based on unit speed) I had to multiply the result by 2. to get the units to move as fast as normal ones. It was because my 32 updates-per-second timer was actually going at 16 updates >.>

    I should have noticed this in the debugger when I had it up...I just didn't even imagine this :p
     
  19. BlowingKush

    BlowingKush I hit the blunt but the blunt hit me.

    Ratings:
    +183 / 0 / -0
    Well here is some good news.

    I suppose this got overlooked since noone has said anything about it

    The trigger engine INCREASES in speed with game speed.

    I am able to increment a variable at a rate of 45 times per second = .0222
    with a wait 0 in my while loop.

    This means if you are making an action game. Simply run your game in fast mode and decrease the movment and attack times of your units accordinally.
    This should provide better response over bnet too I hope.

    Can someone check this for me?
     

Share This Page