program design for multiplayer board game?

I’m developing a board game in Unity, similar to chess, 2 players on a tiled board. The other player can be an AI, or a human in multiplayer mode. For easier development, my plan is to write all game logic in pure C# classes, with no dependency to Unity classes. Then I can write test cases and develop the AI more easily. Would be something like this: GitHub - tomi901/Unity-Chess-MVC: A Chess game made with Unity to learn the MVC, thanks to that you could reuse the code in another engine (Using the Model folder).

The individual cells of the board will be prefabs, because they can be more complex with animations etc. But how would I implement the GUI? I guess a simple concept would be to write a class, which reads the data model objects and instantiates the prefabs each frame and attach it to a GameObject. But I guess the instantiate calls are expensive regarding runtime and memory? Would be also a problem for animations and effects, because they are only visual and not model driven. Is there a better way?

For the multiplayer support I think it would be best to run a C# server as well. In single player mode the server classes would just run locally, no changes in the rest of the program needed (at least during the game play, of course extra work is required for match making in multiplayer mode). The server would implement the game logic and provide the data to the clients, including fog-of-war restrictions, so no client has access to the full data to avoid cheating in multiplayer mode.

What network library would you recommend? It is a turn based game, I don’t think I need something big like Multiplay and can just roll my own C# server for it. Some years ago I wrote a multiplayer server in Java for hundreds of clients, also for a turn based game, was not that much work.

regarding your GUI question. you don’t instantiate your GUI in every frame. you instantiate it once during its lifetime and react to user-made GUI events from that point on. now that lifetime is up to you, whether it’s a game session, or app runtime, or maybe it lasts only during one specific screen, but you definitely don’t recreate your GUI each frame.

you should probably look up for GUI related examples and see how it’s done in general. but this has nothing to do with the multiplayer aspect of the game. GUI is by design only a client-side reaction to some deeper model.

regarding the multiplayer, your only concern is to separate client-side logic and cosmetics from the state machine and actual data of your game. if you can make your own server app, I can only recommend you to design your client from the ground up as a strictly console (async) application, and then reintegrate the core logic for the singleplayer only, as a local proxy to the usual server side.

I don’t know what you’re making but keep in mind that non-hackers can intercept naive POST and GET messages and also tinker with the application states in memory. there are many tools for this, especially for the phones. I ended up making my own anticheating measures numerous times. additional socket connection, redundancy in memory state, as well as some limited cryptography (typically shuffling/XOR rotation and secret CRC checks) are your best friends.

you’re still not immune to true hackers.

Thanks, you are right, I need only update parts of the GUI. What do you mean with console application? My idea was to program an async RPC service. I think something like this could work:

client to server:
NewGame(local/server, sideRequest)
MoveField(x0, y0, x1, y1)

server to client:
GameStarted(side, fieldSize)
FieldChanged(x, y, piece)
FieldAttack(x0, y0, x1, y1)
GameOver(winnerSide)

(very simplified, needs more functions for lobby, retransmit field after network disconnects etc.)

Then I need to update the GUI only when I get new server messages, and user actions from the client are transferred to the server. The client can be very dumb and doesn’t need to know any of the game logic, but might be a good idea to execute user actions locally immediately as well for cosmetic things like when moving a piece or attacking a field.

Good idea with hacker proof network interface. My idea was to use JSON, because then it is easier to use clients in other languages as well, or maybe something like Google Protocol Buffers. I would then implement some checks to limit the maximum size of each message, and check every parameter in the function if it is valid. And later maybe some DDOS protections with IP address blocking, if a client sends unreasonable many message etc.

Why would I need to encrypt the transfer? I plan to use SSL connections, which makes it safe against others listening on the traffic. And each client is known to the server (in my last server I used a server generated session id, which was needed in case of reconnects), so users can’t spoof things for other users. The commands to the server are all server validated, which means it is impossible to cheat by crafting special commands. The only thing that could happen would be a bot player, but I’m not worried about this.

A console application term mutated nowadays to assume text-only or to mean gaming console (which nobody knows what it really means anyway). I had the original meaning of the term in mind, your client should be a terminal point, responsible for processing user input and providing application output, but having no essential logic (except in singleplayer).

You got my point already:

This is a console basically.

Well I said limited cryptography, it doesn’t have to be true cryptography. Because of the states in memory. Sniffing and man-in-the-middle is not your enemy, it’s the state between your app output and aether that’s the problem. I had a scenario in which people would corrupt my data and send valid messages of their doing across the network. They didn’t even have to know the exact format of the message, they would corrupt the raw data in memory and circumvent packing unpacking and validation altogether. The tools are very smart today, you need to have some system of redundancy, and as I said some sort of pseudo-crypto so that your data is not transparent.