I've spent all day researching exactly how time works in SC2, and I'm here to document the results of my findings.

Ticks Per Second vs Game Speed

The scripting engine runs with a certain number of ticks per second depending on the current game speed setting. To calculate this, you can simply take the base number of updates per second in normal speed (32) and multiply it by the current game speed modifier (retrievable by using the GameGetSpeed() native). Yes, it actually does use non-integer values for the number of updates per second, so do not round to the nearest integer or your timing calculations will become inaccurate.

Now, about the Wait function. Using either Wait(0, c_timeReal) or Wait(0, c_timeGame) has precisely the same effect: the function will resume during the very next tick. This means that a 0.0 Wait loop will iterate during every single tick of the scripting engine. ANY other value than 0.0 will cause the next tick to be skipped. The number of iterations per second will be decided by your current game speed as shown in the chart above. The actual duration of a Wait 0.0 is equal to the Tick Duration on the chart above. In other words, the speed at which 0.0 loops iterate scales directly with the adjustment of the game speed.

Timers and Wait >0

Timers and the Wait function when used with non-0 values both share something in common, and that is that they are incapable of expiring on every tick of the scripting engine. They will only expire every OTHER tick. This means that a Wait 0.00001 loop will expire half as quickly as a Wait 0 loop! The minimal expiration time of timers and non-0 wait loops for each game speed is listed in the chart below. If your wait or timer duration isn't a multiple of those values, it may cause a rather large amount of inaccuracy which has the potential to compound in itself if you repeatedly restart the wait or timer.

Here's the first thing you should know: StarCraft 2's perception of real time does not match match your clock's perception of real time. The game engine is meant to pretend that time is not elapsing during any lag or slowdown. If you watch SC2's real time (viewable in the debug menu with an option), it will never progress quite as quickly as a clock, and the more stuff that's going on in your map, the larger the gap will become. If you have large amounts of slowdown, SC2 may believe that time is passing much more slowly than it really is. Also, time does not advance while a player is lagging. During optimal conditions, SC2's real time may fall behind a clock by about 1 second each minute.

Tracking Real Time

Starcraft 2 lacks a native to return the current amount of elapsed real time. You can use this simple function to do so:

It is possible to view the current elapsed game time by using the native GameGetMissionTime(). However, you can expect 3 strange behaviors out of this native: first, it only updates the time it will return on every other tick of the scripting engine. Second, its time output is directly scaled by the game speed modifier, i.e. in fastest mode, time will pass 40% more quickly. Third, the passage of time will also be influenced by SC2's perception of real time, as described above.

Real Time vs Game Time

With Waits and Timers, you have the option to use either c_realTime or c_gameTime. As we mentioned before, this distinction has no effect on 0.0 wait timers. It is simply up to you whether you would prefer to have your waits and timers speed up or slow down based on the game speed modifier, or whether you would like for them to expire in the same amount of real time regardless of game speed. There should be different times that each is appropriate.

I will update this guide to contain any new information discovered about the topics addressed above, so feel free to contribute anything else you discover.