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.
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 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.
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).
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.