Take the 2-minute tour ×

I'm new to Reactive Extensions for .NET and while playing with it I thought that it would be awesome if it could be used for games instead of the traditional update-render paradigm. Rather than trying to call Update() on all game objects, the objects themselves would just subscribe to the properties and events they are interested in and handle any changes, resulting in fewer updates, better testability and more concise queries.

But as soon as, for example, a property's value changes, all subscribed queries will also want to update their values immediately. The dependencies may be very complex, and once everything is going to be rendered I don't know whether all objects have finished updating themselves for the next frame. The dependencies may even be such that some objects are continuously updating based on each other's changes. Therefore the game might be in an inconsistent state on rendering. For example a complex mesh that moves, where some parts have updated their positions and other have not yet once rendering starts. This would not have been a problem with the traditional update-render loop, as the update phase will finish completely before rendering starts.

So then my question is: is it possible to ensure that the game is in a consistent state (all objects finished their updates) just before rendering everything?

share|improve this question

3 Answers 3

up vote 2 down vote accepted

The short answer is yes, it is possible to accomplish what you're looking for regarding game update loop decoupling. I created a proof-of-concept using Rx and XNA which used a single rendering object which was not tied in any way to the game loop. Instead, entities would fire an event off to inform subscribers they were ready for render; the payload of the event data contained all the info needed to render a frame at that time for that object.

The render request event stream is merged with a timer event stream (just an Observable.Interval timer) to synchronize renders with the frame rate. It seems to work pretty well, and I'm considering testing it out on slightly larger scales. I've gotten it to work seemingly well both for batched rendering (many sprites at once) and with individual renders. Note that the version of Rx the code below uses is the one that ships with the WP7 ROM (Mirosoft.Phone.Reactive).

Assume you have an object similar to this:

public abstract class SomeEntity
    /* members omitted for brevity */

    IList _eventHandlers = new List<object>();
    public void AddHandlerWithSubscription<T, TType>(IObservable<T> observable, 
                                                Func<TType, Action<T>> handlerSelector)
                                                    where TType: SomeEntity
      var handler = handlerSelector((TType)this);
      observable.Subscribe(observable, eventHandler);

    public void AddHandler<T>(Action<T> eventHandler) where T : class
        var subj = Observer.Create(eventHandler);            

    protected void AddHandler<T>(IObserver<T> handler) where T : class
        if (handler == null)


    /// <summary>
    /// Changes internal rendering state for the object, then raises the Render event 
    ///  informing subscribers that this object needs rendering)
    /// </summary>
    /// <param name="rendering">Rendering parameters</param>
    protected virtual void OnRender(PreRendering rendering)
        var renderArgs = new Rendering
                                 SpriteEffects = this.SpriteEffects = rendering.SpriteEffects,
                                 Rotation = this.Rotation = rendering.Rotation.GetValueOrDefault(this.Rotation),
                                 RenderTransform = this.Transform = rendering.RenderTransform.GetValueOrDefault(this.Transform),
                                 Depth = this.DrawOrder = rendering.Depth,
                                 RenderColor = this.Color = rendering.RenderColor,
                                 Position = this.Position,
                                 Texture = this.Texture,
                                 Scale = this.Scale, 
                                 Size = this.DrawSize,
                                 Origin = this.TextureCenter, 
                                 When = rendering.When

        RaiseEvent(Event.Create(this, renderArgs));

    /// <summary>
    /// Extracts a render data object from the internal state of the object
    /// </summary>
    /// <returns>Parameter object representing current internal state pertaining to rendering</returns>
    private PreRendering GetRenderData()
        var args = new PreRendering
                           Origin = this.TextureCenter,
                           Rotation = this.Rotation,
                           RenderTransform = this.Transform,
                           SpriteEffects = this.SpriteEffects,
                           RenderColor = Color.White,
                           Depth = this.DrawOrder,
                           Size = this.DrawSize,
                           Scale = this.Scale
        return args;

Notice that this object doesn't describe anything how to render itself, but only acts as a publisher of data that will be used in rendering. It exposes this by subscribing Actions to observables.

Given that, we could also have an independent RenderHandler:

public class RenderHandler : IObserver<IEvent<Rendering>>
    private readonly SpriteBatch _spriteBatch;
    private readonly IList<IEvent<Rendering>> _renderBuffer = new List<IEvent<Rendering>>();
    private Game _game;

    public RenderHandler(Game game)
        _game = game;
        this._spriteBatch = new SpriteBatch(game.GraphicsDevice);

    public void OnNext(IEvent<Rendering> value)
        if ((value.EventArgs.When.ElapsedGameTime >= _game.TargetElapsedTime))

    private void OnRender(IEnumerable<IEvent<Rendering>> obj)
        var renderBatches = obj.GroupBy(x => x.EventArgs.Depth)
            .OrderBy(x => x.Key).ToList(); // TODO: profile if.ToList() is needed
        foreach (var renderBatch in renderBatches)
            _spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend);

            foreach (var @event in renderBatch)

    private void OnRender(Rendering draw)
            draw.Rotation ?? 0f,
            draw.Origin ?? Vector2.Zero,

Note the overloaded OnRender methods which do the batching and drawing of the Rendering event data (it's more of a message, but no need to get too semantic!)

Hooking up the render behavior in the game class is simply two lines of code:

entity.AddHandlerWithSubscription<FrameTicked, TexturedEntity>(
                                      _drawTimer.Select(y => new FrameTicked(y)), 
                                      x => x.RaiseEvent);

One last thing to do before the entity will actually render is to hook up a timer that will serve as a synchronization beacon for the game's various entities. This is what I think of as the Rx equivalent of a lighthouse pulsing every 1/30s (for default 30Hz WP7 refresh rate).

In your game class:

private readonly ISubject<GameTime> _drawTimer = 
                                         new BehaviorSubject<GameTime>(new GameTime());

// ... //

public override Draw(GameTime gameTime)

Now, using the Game's Draw method may seemingly defeat the purpose, so if you would rather avoid doing that, you could instead Publish a ConnectedObservable (Hot observable) like this:

IConnectableObservable<FrameTick> _drawTimer = Observable


Where this technique can be incredibly useful is in Silverlight-hosted XNA games. In SL, the Game object is unavailable, and a developer needs to do some finagling in order to get the traditional game loop working correctly. With Rx and this approach, there is no need to do that, promising a much less disruptive experience in porting games from pure XNA to XNA+SL

share|improve this answer

This is potentially quite a general question about decoupling rendering from update in a game loop. This is something that networked games have to cope with already; "how do you render something that doesn't break the player's immersion when you don't actually know what's happened yet?"

One approach to this is to 'multi buffer' the scene graph, or elements of it, and actually render an interpolated version at a higher render frame rate. You still have to identify a point in your update when everything is finished for a particular time step, but it is no longer tied to the render. Instead you copy your update results to a new scene graph instance with a time stamp and get started on the next update.

It does mean that you are rendering with a lag, so may not be suitable for all types of game.

share|improve this answer
My problem is much simpler. I do know what's happened, but only after one or more whole update phases have finished. And the question is: how do I know an update phase has finished when using Rx? Or maybe there is a concept that does not need an update phase and still allows the game to be consistent when rendered. Rendering a lagged game just to be able to use Rx means that Rx is not suitable for my needs, but I don't think this is true. –  Virtlink Feb 22 '12 at 12:16
Assuming we're talking about a fairly traditional simulation type game then you kind of have to know the state of everything you want to render at a given point in time, I think. Otherwise for instance you might see jittering between objects that are supposed to be aligned, joined together or moving in synch (e.g. a car and it's driver). I guess that this is what you mean by consistency? –  OlduwanSteve Feb 22 '12 at 16:41
That's correct. Some game objects, like car parts, need to be aligned with each other. Traditional game loops finish their update phase so there it is never a problem. –  Virtlink Feb 23 '12 at 7:53

Why don't you use some kind of IScheduler to schedule your change subscriptions. Then you could have your main game loop step your scheduler implementation 16.6 ms every frame (assuming 60fps). The idea would be that it would execute any scheduled actions due in that time, so you could still use things like delay or throttle.

share|improve this answer
I should probably add, I don't think Rx is a good fit for updating your main game state. I do think it might be a good match for ai behaviours though. –  Caleb Vear Feb 23 '12 at 8:03

Your Answer


