XNA stops calling
Draw while the game window is being resized or moved.
Why? Is there a way to prevent this behaviour?
(It causes my network code to desynchronise, because network messages aren't being pumped.)
Yes. It involves a small amount of messing with XNA's internals. I've got a demonstration of a fix in the second half of this video.
The reason this happens is because XNA suspends its game clock when
How to fix it:
There is a long chain of events in XNA (if you use
These are private, so you'll need to use reflection to unhook the events (where
Here is the necessary incantation:
(You could disconnect the chain elsewhere, you can use ILSpy to figure it out. But there's nothing else besides the window resize that suspends the timer - so these events are as good as any.)
Then you need to provide your own tick source, for when XNA isn't ticking from
And then, in
Note that this ticking is considerably less accurate that XNA's. However it should remain more-or-less lined up with real time.
There is still one small flaw in this code. Win32, bless its stupid ugly face, stops essentially all messages for a few hundred milliseconds when you click the title-bar of a window, before the mouse actually moves (see that same link again). This prevents our
Because we now don't suspend XNA's game clock, when our timer eventually starts ticking again, you'll get a burst of updates. And, sadly, XNA caps the amount of accumulatable time to an amount slightly lower than the length of time Windows stops messages when you click the title bar. So if a user happens to click and hold your title-bar, without moving it, you'll get a burst of updates and fall a few frames short of real time.
(But this should still be good enough for most cases. XNA's timer already sacrifices accuracy to prevent stuttering, so if you need perfect timing, you should do something else.)