Multithreading and GameState

Hey Guys, I'm new to jME and I've got some questions about general game architecture's that jME supports. Right now I'm using darkfrog's StandardGame class and I would like to use GameStates for my functionality like he recommends. However, I am also looking for a good way to incorporate multithreading as well. I've got a lot of internal game logic I intend to be constantly running (things like background loaders for sound and terrain, and various other things) and I'd like to use separate threads for these things. I saw jjmontes use of GameStates (where he had a ClientState, RenderState, ServerState, etc) and I thought that it was a very clean method of breaking up code. Unfortunately, due to the nature of GameState update method, GameStates seem to require linear processing.



What my question boils down to is this… Does anyone have any idea how to incorporate the excellent code separation that GameStates provide along with multithreading capabilities?

I think you're trying to multithread something that can't/shouldn't really be multithreaded.  GameStates are intended to process scene-graph information via the update method.  All of the scene-graph updates should be done in a single thread…there's really no reason for them not to be and it would be incredibly complicated to try to split that work out.



Where multithreading gives you benefit is in the non-scene-graph aspects of the game.  All you need to make that happen is a separate thread.  For example:


MyGameState state = new MyGameState();
...attach and enable...
MyNetworking networking = new MyNetworking();
networking.setMyGameState(state);   // Might be useful for the networking to have a reference the game state - though there are many ways to handle this
networking.start();
MyAI ai = new MyAI();
ai.setMyGameState(state);    // AI will need to access the scene-graph
ai.start();



This is not necessarily the best way to incorporate multithreading with a game, but it's one of the easiest examples I can show of how to do it.  You have three threads there (OpenGL thread that StandardGame manages, Networking thread, and AI thread) that can all communicate to the scene-graph.  There are some aspects of the scene-graph that take a lot of time that would be beneficial to be managed outside of the OpenGL thread as well (such as terrain loading, texture loading, etc) but there are some threading issues obviously dealing with certain aspects of OpenGL (since it forces you to a single-thread for all of its work) so you can do everything you can outside that OpenGL thread and then either use StandardGame's lock/unlock, or the GameTaskQueue to insert those things into the processing of the OpenGL thread.

Successful multithreaded game development is knowing how to split work up, but also knowing where they have to be put together.  A lot of times you'll just try to do everything outside the OpenGL thread and wait until you get an exception and start throwing things into GameTaskQueue until it stops. Sadly, I spend a lot of time doing that.

As development of jME progresses the necessity of GameTaskQueue will hopefully be minimized.

Hope that helps.

Wow, ok thanks. I guess I kind of misunderstood the use of GameStates. Thanks for your help! I'll try to figure out how to add multithreading while still keeping the overall design simple (if that's possible).



By the way, is there no better way than trial and error to determine if something belongs on the opengl thread or not? Also, would you get a guarantee of an error showing up if you messed with stuff outside of the OGL thread that belonged in there? (if not it seems like an iffy thing to try, doesn't it?)

Well, sometimes it's trial and error because sometimes jME abstracts those things away from you by letting you make changes to an object and then the next time the spatial is updated the OpenGL "stuff" is invoked so it can be done from any thread.  However, there are still a lot of places where that is not done and potentially places where that cannot be done.  That obviously creates some problems.  But in addition there are things that are scene-graph specific and others that are OpenGL specific.  It would be great if we could just bug LWJGL to make their API have better (some) multithreading support.



Generally I get a big fat exception when I try to do anything but there are a few cases where that's not been so.  I don't really have a good answer here.  You have a higher likelihood of having fewer problems if you go single-threaded, but you have many more potential performance gains as well as better abstraction if you take on the risk of multithreading. :wink: