Game logic on separate thread?

I am working on a little turn based strategy game and I thought it would be a good idea to build it with some kind of Model-View-Controller mindset.

I’ve got all the fun monogame stuff, animations, input and GUI etc running in the main game loop, and then I have started implementing the actual rules of the game in a console app project on the side. Mainly so I can focus on the abstract game logic stuff and not worry about material things like Update() etc… Essentially like this:

static void Main()
{
    Match game = new Match();

    while (! game.GameOver)
    {
        var input = GetConsoleInput();
        
        game.Advance(input);

        Console.WriteLine(game.Status);
    }
}
...

Clearly I can’t just jam that into the main Monogame loop and call it a day cus I need to draw things…

So how do I combine these paradigms in the best way? I believe I could run the “rules loop” on a different thread and then have the monogame loop check in on it and update itself and the graphical representation of the game accordingly. Sounds fairly straight forward (though I have a poor grasp of multi-threading).

So I thought I should ask here first, before I start messing about with threads, in case someone has some advice or wisdom to share.

Thanks

Just a quick brain-fart reply:

My mind went to Events, Delegates and Multithreading’s [EDM hehehehe} straight away…

1 Like

You can go digging through the source of my code for inspiration if you want, it’s very abstract so it might be difficult to get into, it’s also a WIP. Engine logic and game logic are completely separated. Although there’s no separate threads in my code, at least not yet, everything is controlled from the XNA Update and Draw deep down in the code. https://github.com/LateStartStudio/Hero6/tree/3c4a3b2e4f1a6ae461c78af6953cc12852f44ae3

I have called my game logic components “Modules”, here is example of the starting room, you’ll notice there’s no mention of the XNA game loop in there. It has event methods that defines what’s going to happen on player interaction, the actual methods gets invoked from the engine. https://github.com/LateStartStudio/Hero6/blob/3c4a3b2e4f1a6ae461c78af6953cc12852f44ae3/src/Hero6.Campaigns.RitesOfPassage/Rooms/Albion/HillOverAlbion.cs

I have called my game engine components “Controllers”, here is the game engine code for the room entity of my game. The controllers works around the XNA game loop, but they are fairly abstract so I could easily support a new game engine written in for example Unity by writing a new set of controllers which was my design goal from the beginning. https://github.com/LateStartStudio/Hero6/blob/3c4a3b2e4f1a6ae461c78af6953cc12852f44ae3/src/Hero6.Engine/ModuleController/Campaigns/Rooms/RoomController.cs

1 Like

Wow @persn what a beast of a project… I’ll see if I can wrap my brain around it tomorrow, thanks!

I decided to experiment with a threaded version (wanting to avoid redesigning what I’ve already built).

This is what I came up with. Seems to work well so far.

class GameLogic
{
    public event EventHandler GameChanged;

    public static void Run(EventWaitHandle waitHandle, ref MyInput input)
    {
        Match game = new Match();

        while (! game.GameOver)
        {
            //Block this thread until player takes action in monogame
            waitHandle.WaitOne();

            //Input should be set in monogame now.. use it! 
            game.Advance(input);

            //Tell monogame that things have progressed
            GameChanged?.Invoke(game, EventArgs.Empty);
        }
    }
}

This is probably a flawed design in some way… but so far so good.

EDIT:

High quality brain-fart! :+1:t2:

1 Like

Just my 2 cents. I’ve don’t think the rules logic requires a separate thread. I’ve been making some turn based games and using the built in update/draw (as persn’s program ultimately does also) works fine. Even with some hefty rules processing (all relative I know) I have not seen any performance issues (thanks monogame).

1 Like

I was thinking the same thing, at first, but I realized that there was a certain beauty to multi-threading in a game environment. I had a design that would have required a VERY long running genetic algorithm to be processing data. That process could literally take days, so it HAD to be on other threads (other computers, even). In this case, we don’t really know what else is happening, and separating the game from the logic behind it begins to resemble the separation of responsibility that is the basis to multi-tier designs in line of business applications.

1 Like