Classic game loop Vs. Separate threads for update and render

For the last couple of days I’ve been doing some pen and paper sketching on a small Java game. Right now I’m
trying to make up my mind about if I should use just one loop with both rendering and updating or splitting them up in separate loops. The idea is to have a SceneGraph class that holds all game objects (GraphObjects) and a SceneGraphCanvas that renders the content of the SceneGraph to the screne.

I’m leaning towards having separate threads, but I’ve heard some rumours that this could lead to very choppy frame rates. But if I could, some how, get around this I think it I would have some really useful classes and thing like a split-screen would be a matter of minutes to implement. I know threading can lead to code complexity problems, but since both threads will more or less be minding there own business I don’t think this will be much of a problem in practice.

SceneGraph.run() [in pseudo code]



while(running)
{
    if(!paused)
    {
       while( there still are canvases rendering this graph)
         Sleep(2)

      - calculate delta time and FPS
      - Update all graph objects

      - Collision detection on all GraphObjects
      - Collision reaction
      
            
      m_cycle_count++
      
      Sleep(5);
    }
   else
    {
       Sleep(100)
    }
}


SceneGraphCanvas.run() [in pseudo code]


while(running)
{
   if(m_screen_graph.m_cycle_count > m_last_rendered_cycle)
   {
      renderScreenGraph()
      m_last_rendered_cycle = m_screen_graph.m_cycle_count
   }
   else
   {
      Sleep(10)
   }
}

(SceneGraphCanvas extends javax.awt.Canvas)

Does this sound like a reasonable way to do things?

Have any one here tried something like this? If you have I’d really like to hear if and how you got it to work (or why you didn’t and why it’s a really stupid idea to use the separate threads approach)

You should probably search around the forums, we’ve had quite a few lengthy threads about the “best” way of scheduling logic and rendering.

IMHO, a thread each is asking for some serious trouble. You don’t really gain anything (and I fail to see how split screen would be any easier either way) but you introduce a whole extra class of tricky bugs and put yourself at the whim of the OS scheduler, which frankly isn’t much good for this kind of use (because it was never intended to be). You’ll be adding a whole bunch of overhead - not just the runtime overhead of context switches and locking behaviour, but the programming effort to write and maintain that structure.

I disagree that both threads will be “minding their own buissiness” too. Every scene graph object will have to be syncronised or otherwise locked as they could be being written to by and read by both threads. You could get around this to a certain extent by double buffering it, but then you double your memory use and it’s still not perfect.

However without knowing why you want to use two threads (other than some hand-wavy “really useful” answer) then it’s pretty much impossible to give a definate answer.

Edit: Incidentally, “scene graph” usually refers to a structure used only for rendering purposes. Trying to crowbar game logic and collision detection into it as well is probably not a good idea. You make the two systems annoyingly dependant on each other, and you usually want a different data structure for each anyway. Unless you’re doing something simple, in which case it’s not a scene graph, it’s just a list of stuff to update and draw.

JustAListOfStuffToUpdateAndDraw doesn’t sound like the best of class-names, but if you have a better suggestion then SceneGraph then I’ll be happy to use it (i keep spelling it like “ScereenGraph” any way). ;D

Most swing-components are rendered by the event-dispatch-thread and this means they are only rendered when something “happens”. For a game this is not very practical (but now I’m probably telling you things you already know). The point of having separate threads would be to liberate the engine user from having to call update on them. He/She would just have to create the ListOfStuffToUpdateAndDraw and add a ListOfStuffToUpdateAndDrawCanvas, attach the ListOfStuffToUpdateAndDrawCanvas to the ListOfStuffToUpdateAndDraw and not have to write his/her own game loop (the rendering engine will take care of that). A split-screen would just be two ListOfStuffToUpdateAndDrawCanvas in a JPanel with a GrindLayout. In other words the ListOfStuffToUpdateAndDrawCanvas would act like any other UI-component requiring (almost) no extra considerations.

But now that I think of it I could have the ListOfStuffToUpdateAndDrawCanvas keep a list of attached ListOfStuffToUpdateAndDrawCanvases to. This way I could have booth the single thread and my Canvases would act like any other UI-component. :smiley: