The benefit of having a fixed 'step size' for your simulation might not be immediately apparent, however it has obvious benefits when trying to synchonrize network games, or work with physics libraries (eg ODE) which can go non-deterministic when working with a variable step size...
This is what my new general game loop looks like. If I ever need to implement frame-skipping, I believe I'll need to write some more code at line 27, to detect if every frame is being skipped... :-) I use this loop to generate Tick and Render events which get handled elsewhere.
1 import pygame
2 from pygame.locals import *
4 def main():
8 #time is specified in milliseconds
9 #fixed simulation step duration
10 step_size = 20
11 #max duration to render a frame
12 max_frame_time = 100
14 now = pygame.time.get_ticks()
16 #handle events
17 if QUIT in [e.type for e in pygame.event.get()]:
20 #get the current real time
21 T = pygame.time.get_ticks()
23 #if elapsed time since last frame is too long...
24 if T-now > max_frame_time:
25 #slow the game down by resetting clock
26 now = T - step_size
27 #alternatively, do nothing and frames will auto-skip, which
28 #may cause the engine to never render!
30 #this code will run only when enough time has passed, and will
31 #catch up to wall time if needed.
32 while(T-now >= step_size):
33 #save old game state, update new game state based on step_size
34 now += step_size
38 #render game state. use 1.0/(step_size/(T-now)) for interpolation
40 if __name__ == "__main__":
Update: Thanks to a suggestion from Marius in the comments, the loop is now environmentally friendly. :-)