In Theory:
Let’s just say, for the sake of discussion, that your game is Tic-Tac-Toe.
If I’m understanding correctly, your game currently has Human-vs-AI working correctly. Awesome. I assume you have something like a board state that indicates whose turn it is to move. If the player tries going on not-their-turn, the move will be ignored, right?
So currently either the board makes a request to the AI to make a move, or the AI is watching the board state and checking to see if it’s its turn to go. Either approach is fine, I’m sure, but let’s go with the AI watching strategy.
The approach I’d take is to use an instance of an AIPlayer that checks in every second or so to see if it can make a move, and does so when needed. Then it goes back to watching until it’s needed again. A human opponent would work pretty much the same way. An instance of a HumanPlayer would sit in the game and watch and wait for its turn. When needed, it then grabs the board state and passes it across the network to the human player. On their end, then, everything would look like how your turn just started. Repeat as needed.
In Practice:
It depends on what platform you’re targeting (iOS, Android, Xbox, Steam, a toaster), but it also doesn’t. Abstract everything out to a MultiPlayerInput class that has any needed platforms handled inside it. As far as the Board/Gamestate is concerned, it only cares that the MultiPlayerInput is doing its job. Inside that class, conditional statements will use the right API or networking code to send notifications and data, and process its return.
In My Experience:
I’ve only done one game, and I didn’t do it well.
Meaning, I didn’t take my own advice above and just used the API in with all my other code. Which is why I only ended up releasing on iOS… I didn’t feel like going back through and decoupling it to be able to implement multiple platform APIs.
I think it’s commonly agreed that prime[31]'s plugins are the best. They aren’t cheap, though. And they do, in fact, provide a lot more functionality than you need. However, as I have no experience writing my own networking and matchmaking solution, I can’t say how much more difficult it would be to write everything yourself. I will say that you should never undervalue the inherent cost of your time, though, and saving yourself 50 hours of development time is well worth the $175 or so, in my opinion.
That said, Unity’s built-in multiplayer may still be the best option for you. Again, I’ve never used it, so I can’t speak to how easy and effective it would be (especially since it seems focused on real-time, and you’re talking turn-based here), but it’s effectively free until you start getting some heavy traffic, so it could be worth looking into a bit further if dollar bills are in short supply at the moment.
In my dreams:
Unity would provide a built-in solution that would be a simple matter of checking a few boxes and filling out a few fields, assigning some properties and then BAM: multiplayer all configured. But until that happens, we’ll have to keep on with the options we have!
Please keep us informed on your progress! This is one area I have a lot of room to improve on, and a strong need to do so!