We had this idea in the rewrite to split the scene into (at least) 3 parts: a physics scene, a render scene, and a game logic scene. The different parts would all run on different threads and run at independent speeds (e.g. the scene is rendered as fast as it can, but the physics is only updated 30 times a second). The threads would stay in sync with each other by passing events like “move node X to …” and “set material of node Y to …”. Our plan was to treat the render system as a sink, so it only ever received events. To avoid the physics and game logic scenes getting in each other’s ways, we were going to have objects be moved either by the game logic (for scripted camera movement, etc.) or by the physics system (moving around boats, etc). That way a node would only be modified by a single thread. I think that might work (maybe not), but we have decided to abandon all that and go with a more or less straight OGRE scene instead.
As I was implementing it, it seemed like there was just going to be too much overhead for it to really be worthwhile. All of the scene nodes were identified by name, so in my unoptimized first-shot implementation there was a lot of lookups in maps of strings. I think we could have improved that to the point where it might still be workable, but the real kicker was 3rd party libraries… We decided to do this “per-subsystem” sort of threading instead of something more like a work queue with worker threads because we wanted to leverage mature, 3rd party libraries. We are excited to get all of the power of OGRE without having to implement all of that ourselves. However, most of the 3rd party libs are not thread-safe or multi-threaded. We thought if we controlled the updates to events that got passed to the thread, that would be ok. CEGUI really killed that idea, though. It is not thread-safe, and in our system it would need to be accessed by both the render thread (to display the buttons) and also the input thread (to handle input events). From what I read on the CEGUI forums and saw in their code, that just isn’t safe.
We had to decide basically whether to continue with our “it might work” idea for multi-threading and possibly implement our own GUI system, or just cut out all of that extra work and use the libs more directly. We decided to abandon our triscene idea. The sound system will probably still be threaded, but the input, physics, rendering, and game logic will all happen on the main thread. That clearly isn’t the best way to go with multi-core processors becoming with more and more common, but I think trying to use non-thread-safe 3rd party libs in a multi-threaded way is just a loosing battle. The only real alternative is to write all of our own subsystems (i.e. no CEGUI, no OGRE, no ODE), but at some point we have to just focus on getting a simple, well structured, singled-threaded (and actually running!) version of Crown and Cutlass instead of diving off into all that.
Actually, we decided to abandon the “game view” idea for now as well. We couldn’t really map that onto the rest of our design. Rather than continuing to bat ideas around that I think sound good but can’t quite get pinned down, I am going to focus more on getting what we have running. I guess that’s 2 fewer cool things I am excited about that, but at least we are getting close to working in Crown and Cutlass again for the first time in almost a year and a half!
PS We tagged the SVN repo before we deleted all this code. You can see the tag here.