none
Best method for game loops in silverlight 3+

    Question

  •  Hey,

     At the moment as my front end is still in a sloppy state, it currently has a timer going for updates that runs every 10 milliseconds (which is triggered by a dispatcher timer)... now this runs fine and all, but i just wanted to check if there was any *better* way of doing this like via the RenderComposition or whatever its called...

    This may just be a simple "The timer method is fine" answer, but wanted to make sure... after reading Bills articles in SL2 with game loops some people were saying there were issues with using the RenderComposition method outside of full screen... Although im just trying to get frequent updates at the moment, going forward im going to need to make sure that everything is done on an elapsed time basis... so rather than moving by m_MovementSpeed every update, i  move by ElapsedTime * m_MovementSpeed... or something similar...

     My brains just started dribbling out of my ear so im going to stop writing now...

    Thursday, September 03, 2009 6:13 PM

Answers

All replies

  •  Nikola recently wrote an excellent article answering this question:

    http://blogs.msdn.com/nikola/archive/2009/08/19/exposed-5-methods-to-create-game-loop-which-is-the-best.aspx

    Thursday, September 03, 2009 6:52 PM
  •  Brilliant comparison... i will be having alot of stuff happening, so i could definatly make use of other cpus later on but for the moment as the dispatch timer is a valid way of doing it, i will leave it as it is for the moment... and as im going to change over to time based movement rather than at fixed intervals it shouldn't matter too much...

    Friday, September 04, 2009 3:05 AM
  • Forgive me for bringing the subject back,but i am somehow not satisfied by the approach taken by the article you mentioned.Unless i am mistaken,DispatcherTimer events are fired up in the same thread as the UI thread,so not only does it slow up the entire page's UI but the page UI can slow the game too (most game hosting sites for example are loaded with ads,chat room and other not-so-fast UI elements).CompositionTarget.Rendering is dependant on the game framerate,which simply is not an approvable thing in a game (a slower PC would make the game speed fall down which may not be that bad,but a faster than expected PC would make the speed faster,which is indeed bad).

    As a game developers we know that if something will make our games run slower is not the techniques we use for the game loop,but the code itself.Therefore how each technique acts in variable hardware capabilities (which that article didn't take into account) is the main criteria in my opinion.

    I would grade the techniques mentioned based on that criteria like this: Thread>Storyboard (normal)>Storyboard (as a trigger)>DispatcherTimer > CompositionTarget.Rendering

    Sunday, September 27, 2009 10:59 AM
  • For a long time, I did not use CompositionTarget.Rendering, because it is dependent on FPS. And as known, FPS can not only be different per PC, but also during your game, depending whether it does, or does not show a lot of graphics.

    I cannot find the blogpost anymore where I found this idea, but this is what I did in Avios:

    I took this Stopwatch code.

    I use this function to initialize base animation:

     private void InitAnimTimer()
            {
                CompositionTarget.Rendering += HandleAnimation;
                animate = false;
            }

    The handle function:

            private const long standardFrameTime = 34;      // this determinates your standard time frame

            private long previousTime=0L;
           
            private Stopwatch stopwatch=new Stopwatch();

    private void HandleAnimation(object sender, EventArgs e)
            {
                if (animate)
                {
                    long currentTime = stopwatch.ElapsedMilliseconds;

                    double percentage = (currentTime - previousTime)/(double) standardFrameTime;

                    PercentagePF.Text = percentage.ToString("0.0000");  // this is a text control, which you make invisible for production

                    previousTime = currentTime;

                    InvokeOnAnimate(new AnimationEventArgs(percentage));
                }
            }

     And to be complete:

            public event EventHandler<AnimationEventArgs> OnAnimate;
            private void InvokeOnAnimate(AnimationEventArgs e)
            {
                EventHandler<AnimationEventArgs> onAnimateHandler = OnAnimate;
                if (onAnimateHandler != null) onAnimateHandler(this, e);
            }

    Anything which is animatable, implements an IAnimatable interface with an Animate(AnimationEventArgs a) method. During level load, all animatable objects are hooked to the OnAnimate event above.

    Now all objects receive a percentage value, relative to the standard time. If an object has speed of 10 in the X direction, then in each animation hit, you will move this object by 10,0 * percentage.

    If your FPS becomes slow, the the percentage becomes high and will compensate the timeloss. If your FPS becomes fast, then the percentage will become low and again there is compensation.

    The above gives an absolute stable movement.

    DDtMM, author of Vector Space Zero and Vector Space Armada writes about a variant of the above on his own weblog. Initially, a few frames are recorded and a statistical mean is calculated (and probably used in the same way as the percentage above). I'm not sure why DDtMM's queueing method is more stable than the above, but DDtMM will probably have good reasons.

    Sunday, September 27, 2009 7:30 PM
  •  Actually your method works better (better time resolution).Using a time measuring method is the only way to make CompositionTarget.Rendering frame rate indepedent,however i still believe that having the update of the game logic loop in a different thread than the rendering loop is the way to go.Anyway,most of these methods show their flaws under certain conditions so the knowledge alone helps making more stable games.

    Monday, September 28, 2009 11:50 AM
  • My thoughts about two threads for a game loop:

    On the Commodore Amiga (and C64), developers used (at least) two screens for their screen output. The reason was, that painting a screen took longer than one frame (and you don't want to paint on the screen you are displaying). Painting of the backgrounds were the biggest problem. They painted on large screens, such that the largeness created a scroll area, so that you could display one screen for multiple frames, while processing the other screen. The Amiga game "Turrican II" used this technique (I know because I hacked into it with my Action Replay card).

    So my first thought is: if one render cycle takes less than one frame, then you don't need two threads.

    If you do need two threads, they will have shared memory and you need to regard the fact that painting can take more than one frame (ie, use a large screen). Note that this mechanism is much more complex, so you'll need to be sure you need this. While you are painting on your future screen, you also need to make sure that everything looks natural on your current display screen.

    The argument against is: I've discovered in Silverlight 2b that new UserControl() can be very slow. I'm not sure if this is still the case in SL3. But taking this into account, beware that you do not loose more than you gain. Perhaps direct bitmap painting is faster, but I don't know that.

     

    Monday, September 28, 2009 1:08 PM