My favorites | Sign in
Project Home Downloads Wiki Issues Source
New issue   Search
  Advanced search   Search tips   Subscriptions
Issue 428: Pyglet Clock Timings - Problem with schedule_interval
5 people starred this issue and may be notified of changes. Back to list
Status:  Invalid
Owner:  ----
Closed:  Dec 2012

Sign in to add a comment
Reported by, Jun 27, 2009
I believe there is a problem with the underlying calculations for 
schedule_interval specifically when it's running alongside something that 
is scheduled every frame (presumbly because this adds extra tick time).

On my system the following code outputs dt values of average 30ms rather 
than 16ms, infact it's pretty much never 16ms.

import pyglet

window = pyglet.window.Window(800, 600, vsync=True)    

def update(dt):    
    if dt > 0.017:
        print dt

def idle(dt):
pyglet.clock.schedule_interval(update, 1/60.)    


Having looked at the underlying code for how schedule_interval works I 
think it is incorrectly setting the items next_ts (the next time it will 
be scheduled).

Within and the call_scheduled_functions method there it actually 
calculates the next_ts at one point and then will immediatly change a few 
lines down. See "item.next_ts = ts + item.interval"

Which means it will set the next_ts to be the current time (well the 
current tick time) plus our interval, since time would have elapsed since 
this call is made it means it is always going to be more than just the 
interval from the last time it ran.

For example if the "last time" was 100 "current time" was 110 then 
the "next time" would get calculated to be 126 and each time it comes 
through it will be slightly more than the just a 16ms interval between.
Instead it should be the "last time" + the interval so in this case 116.

I'm not sure if i've explained that very well but the timings do come 
across very strange when using schedule_interval in this manner.

I have refactored this code (attached is the entire with comments 
see line 307) to how I think it should be working and given it some tests, 
it looks on the whole much more well behaved. I still do see a fair amount 
of higher than 20ms values but not nearly as much and these could be the 
results from timer inaccuracies.

System Information:
Windows 7 64bit Quad Core (Q6600) Python 2.6.3
Pyglet version is straight from the main trunk however I was experienceing 
this on 1.1.3 as well (major difference though is the trunk version 
correctly uses time.clock on windows and not time.time)
35.9 KB   View   Download
Jun 29, 2009
I have to unfortuantly conclude that my above reasoning was incorrect.

I was still getting some odd timings so I sat down and thought about it some more, 
what is currently being done does make sense. If the newly calculated next scheduled 
time is not going to happen we have to set it to be the current time + the interval 
or that instance won't get called.

I am still having unreliably timings though, a large quantity of greater than 30ms 
however I have not got to the bottom of this.

Although I realise my original summary of the problem was incorrect I still think 
there is something amiss with these timings and therefore still an issue, I will 
update if I discover anything.

Aug 14, 2009
AFAIK, the accuracy of Pyglet's timing under windows is limited by the reliability and resolution of the windows 
timing functions, which are usually accuracte to no more than 10ms. Things can get even more hairy when 
multiple cores are used. Thus, some of your issue may relate to that. See a previous discussion on pyglet-

Aug 16, 2009
Project Member #3
In the example, you're asking for a "synchronized" window (vsync=True). If your vertical refresh rate is around 
30Hz, then you cannot pretend to be faster than 1/30. (~ 0.333). Can you try the same with vsync=False ?

Aug 20, 2009

It's been awhile since I looked at this issue myself so I'm a little foggy as to the
details now.

I don't think it's related to vsync though I appreciate that it would effect the timings.
I actually think it's more related to schedule_interval, that for me on my system did
not produce accurate timings and the code used is different to the standard schedule

Additionally was changed in the trunk after 1.3 was released for windows to
use time.clock for timings which uses QueryPerformanceCounter under the hood which is
far more reliable on Windows. This may have had an effect on initial timing results.

In the end I decided to effectively just update as fast as I can with vsync disabled
and using the pyglet.clock.schedule function.
This seems to produce better timings at any rate.

I do still need to do some more proper testing on various systems to see if there is
still an issue.
Aug 21, 2009
Project Member #5
Please try the maintenance branch r2516 and see if it helps.
Aug 22, 2009
As far as I can tell that branch does exactly what the trunk is doing which is what 
i'm running this against. Which is to use time.clock for underlying timings on 

I just did a quick run of example code with schedule_inteval attempting to update at 
an interval of 1/60. which as stated before in my eyes should give around 16ms with 
some variance, instead this is actually giving me more a steady 20ms with variance.

This is only on this machine i've tested with at the moment though.
Aug 22, 2009
Project Member #7
I've been looking into a similar issue (issue 445) and there's notes collected there 
that may be helpful.  

It's looking to me like the windows clock should be revamped in 1.2.
Apr 28, 2012
Project Member #8
Any windows users willing to have a crack at this?
Labels: OpSys-Windows
Jul 21, 2012

I was looking at the new pyglet (1.2 alpha1) release and it occurred to me that this bug I made was kind of left hanging.

Using my original timer script above, I do still get 30ms update from schedule_interval with 1/60, however this is in windowed mode, in fullscreen mode I do get more likely lower timings with a few exceptions.

Looking about there is a lot of confusion regarding this however, I've seen a few other posts talk about the fact they get lower timings when using schedule_interval when they expect to get it as high as they requested.
If it's just a case that schedule_interval is not guaranteed to give you exactly the interval you wanted, perhaps a note in the documentation to say this, is all that is needed.

Hope that at least provides some extra information on this old bug. It may be worth closing for now and if it crops up again (as perhaps a more substantial problem) then it can be re-examined in a new light.
Dec 4, 2012
Are you really sure it's not just a matter of vsync being enabled? I had the same problem, ~30ms dt's no matter how small I set the schedule_interval, until I disabled vsync. Remember that the run loop that drives the pyglet.clock timers is what calls the page flip, so it blocks (I assume) until the flip completes, thus the timers won't update any faster than your refresh rate (and in fact update somewhat slower, I'm guessing because of the wait for the next frame?). When I turn off vsync, schedule_interval can run in excess of 1000 ticks a second on my system. 
Dec 12, 2012
Project Member #11
Going by comment 10 and no other recent activity I'm closing this issue.
Status: Invalid
Sign in to add a comment

Powered by Google Project Hosting