1
\$\begingroup\$

I'm building a game using SFML, with disconnected logic & screen systems that run on different threads and communicate through synchronised buffers. Now, this system worked perfectly well when I only ran independent AI units, but now comes the time to handle player input, and I'm not sure what's the best way to handle it.

Currently, when a player clicks the screen, the input manager creates a MouseClick event, which goes to the logic buffer. The logic manager checks if that spot contains a controllable entity, and if it does, creates a SelectUnit event with the relevant information in the display buffer. When the display manager reads that event it updates the screen with the relevant piece of GUI, and any click on the GUI again sends an update to the logic component. The two problems I see are that the SelectUnit event will need to contain a lot of logic info which might harm the info decoupling, or just make it useless, and that I fear (still not tested) that since the communication will bounce several times between the two threads, some might be lost.

Now, I wonder if this system could be handled better, with less transferred information.

Note about the tech: SFML creates a RenderWindow object which handles input and display. I'm still not sure what library to use for GUI (probably GWEN.net), so I can't currently name tech limitations on it.

EDIT: this is supposed to be a RTS multiplayer game. So far, it seems to me there'll have to be a central logic unit (on the host computer?) that'll receive all the inputs from all players, and send the responses accordingly. This, obviously, makes this system even more complex. Again, suggestions are welcome.

\$\endgroup\$
7
  • \$\begingroup\$ Could you tell us what kind of game is this? An RTS? A turn-based strategy game? Also, did you split your processing in two threads for a specific reason? -if that's causing you trouble, you could just get rid of it. If you're trying a Model-View-Controller thingie, well, you should know it's not that appropriate for games, as exposed here and there. \$\endgroup\$ Apr 23, 2012 at 23:05
  • \$\begingroup\$ Here too. \$\endgroup\$ Apr 24, 2012 at 0:08
  • \$\begingroup\$ It'll be a Real-time 2D RTS. I split the processes to two threads because I wanted to maximise utility of multicore systems - I tried running it in a single thread (and I can return to it easily) and in two threads, and two threads was considerably faster. But I think the threads are less the issue, but the design pattern. Yes, it's very similar to MVC. It's decidedly simpler for me to write and control when different aspects are handled in different namespaces and by their own managers (and yes, it's easier to handle multithreading). \$\endgroup\$
    – nihohit
    Apr 24, 2012 at 6:56
  • \$\begingroup\$ Basically, I'm following something similar to the basic suggestion here. If you could point me to a more efficient design pattern, I'd be thankful. \$\endgroup\$
    – nihohit
    Apr 24, 2012 at 6:56
  • \$\begingroup\$ Also, it seems that here they do recommend a similar system for the non-hosted players. Wouldn't it be simpler to account for everyone in the same way? \$\endgroup\$
    – nihohit
    Apr 24, 2012 at 7:07

1 Answer 1

2
\$\begingroup\$

You have separated your runtime in two threads, one for the game updates ("logic"), and another one for the rendering ("screen"). Your concern is how to exchange information between them.

A usual way of doing this is to keep two separate buffers describing your scene, one per thread. The rendering just needs the info relevant for rendering in its own buffer: matrices, meshes, textures... Whenever the scene changes, the update thread fills a command queue with delta changes (e.g. object A was moved, object B was deleted, etc.). When the rendering thread is ready to process a frame, it consumes those commands and adapts its own scene.

Easier to write but less memory-efficient: have three buffers, one that the update thread modifies, another one that waits for the rendering thread to pick up (a glorified command queue), and a last one that the rendering thread works on.

A few related links:

Now to your specific problems:

The two problems I see are that the SelectUnit event will need to contain a lot of logic info which might harm the info decoupling, or just make it useless...

Exactly, this is way too high level for you rendering thread. You should process it in your update thread, and send something more generic to your rendering thread:

  • Add Mesh_Selection to the scene, attached to Unit_X
  • Add GUI_Object_Foo with Texture_Bar at screen location x,y

That's the general idea, but what to send exactly is up to you. The more high level you go, the more you off-load your update thread, but the more complicated your commands will be.

...and that I fear (still not tested) that since the communication will bounce several times between the two threads, some might be lost.

There's no reason why you rendering thread should send anything back. All the updates are processed by the update thread, the rendering thread just renders what it's fed with, top-down.

NB: That's one way to do multithreading in game engines, but it's definitely not the only way. You'll need to do a bit of research to find if that's really what you need: it's common on current-gen consoles, but it's a bit outdated on modern PC hardware. And it's definitely overkill on single-core systems. Here are a few links to start with:

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .