Design of network communication

Discussion of ongoing programming work.
Forum rules
Posted relevant content can be used under GPL or GFDL (http://www.gnu.org/) for the project. Thanks!
Post Reply
User avatar
Trilarion
Founder
Posts: 837
Joined: Thu Jan 12, 2012 9:27 pm
Location: Central germany

Design of network communication

Post by Trilarion » Tue Sep 15, 2020 8:30 pm

Here I will write down the current state of the network communication for a better understanding and for discussion and improvement.

lib/network.py

On the most basic level we wrap around QtNetwork.QTcpSocket, which can connect to and exchange bytes data remotely. In ExtendedTcPSocket we include such a socket and connect to its signals. We similarly wrap around QtNetwork.QTcpServer.

We read and write data through a QtCore.QDataStream that takes a QtCore.QByteArray that contains a zlib compressed data stream that is a serialized (pickled) Python object. That way Python objects can be send around.

For an example see examples/lib/network_example.py or examples/server/network_example.py

base/network.py

This is a higher level wrapper around ExtendedTcpSocket from lib/network.py. It introduces Channels (an Enum see C in constants.py) that one can subcribe to and unsubscribe from. Messages (Python objects) are a dictionary with keys: channel (Channel), action (another Enum, see M in constants.py) and the message content (any Python object).

The idea is that everything can connect to a Channels received signal and then gets notified of all messages in that channel and get decide on what to do based on the action (or message type) and the message content.

For an example see examples/server/network_process_example.py or server/network_chat_example.py.

The local network client is a member of the base/network.py modul.

server/server_manager.py

The ServerManager accepts new NetworkClients and handles messages on the server side.

General
  • There is always a single local server. It can be either configured to only accept connection from the local device or from everywhere. It's used for local single player games as well as for locally hosted multiplayer games.
  • There is always one single local networkclient, that connects to the server (either local or remote) to play a game. When it connects to a server it should either send its unique ID (in case it was connected and lost the connection) or it should get a unique ID from the server, which it then should remember.
  • The client does not know everything about the game, only what it needs to know. The flow should ideally be that the client sends a request to the server (player wants to do X), the server either rejects the request or accepts it and sends an update back to the client and to all other clients. The clients then react to the update in states.
  • Communication within the server and the client is via signals and slots from Qt, objects should be derived from QObject.
  • The server and the client live in different Python processes. At the beginning the client starts a local server in a process, when it ends, it will signal the local server to shut itself down too and will wait for it to finish too.
  • The scenario editor does not need to go through all this because one can only edit scenarios locally. It directly works on the data structure containing all informations, which is a ServerScenario.

amtyurin
Posts: 4
Joined: Mon Aug 10, 2020 10:53 pm

Re: Design of network communication

Post by amtyurin » Tue Sep 15, 2020 9:02 pm

Thanks for explanations.
How things should work for these cases?
1. Turn. I was thinking that each player does not send any action in its turn rather than collects actions in a batch and after pressing 'End turn' button sends the batch to the server. Server waits until all players finish their turn and starts calculations. Server checks for allowed actions (not to allow a player cheating) and response each players with new state of each player accordingly.
2. Save game. Is it possible to save multiplayer game? How can do that(i.e. only creator or each, if each, that player can cheat by loading it or going through save resources)
3. AI control. Is AI treated as just another client (like player) but with clever control and actions. Ideally, we should have one API for server communication, so we can use it for player or build AI on top of it.
4. In such design it is possible just run server process in some host in the Internet, so anyone can connect to it and play (or may be AI to)

In any case we need to standardize the API methods/functions and expose them for the client part. May be separate module would be good for that. It will be easier to implement AI player, so it does not need any other file references.

User avatar
Trilarion
Founder
Posts: 837
Joined: Thu Jan 12, 2012 9:27 pm
Location: Central germany

Re: Design of network communication

Post by Trilarion » Wed Sep 16, 2020 6:43 pm

1. Turn. I was thinking that each player does not send any action in its turn rather than collects actions in a batch and after pressing 'End turn' button sends the batch to the server. Server waits until all players finish their turn and starts calculations. Server checks for allowed actions (not to allow a player cheating) and response each players with new state of each player accordingly.
The question is if the actions of each player during a turn are independent and if they require interaction from the server. For example if a new resource is discovered during the turn, it would mean that the server has to return something. But I guess we could also shift the discovery of new resources to the begin of the next turn. Something else is battle. The battle phase of each turn is not independent.

One possible sequence is:
  • All players plan their moves and send them to the server.
  • Server processes all moves and creates a list of battles to be resolved, returns information to the player.
  • Players do the battle (that will require constant communication with the server).
  • Players get notified that a new turn starts with all the information that they need for it.
2. Save game. Is it possible to save multiplayer game? How can do that(i.e. only creator or each, if each, that player can cheat by loading it or going through save resources)
Single and multiplayer games are treated absolutely equal. They are just serialized scenarios on the device of the host of the game, i.e. who started it. The server just stories the current scenario.

For multiplayer games we could build in that every player can only continue its own nation (for example with a device specific password/security key that is stored in the network preferences).

However, the game is open source, you can never be 100% safe against reverse engineering. The goal would only be that non-programmers cannot cheat.
3. AI control. Is AI treated as just another client (like player) but with clever control and actions. Ideally, we should have one API for server communication, so we can use it for player or build AI on top of it.
Yes. The server should not care about whether a player is human or a machine. However, sometimes AIs need to be able to cheat a bit in order to be challenging. And the AI client would need to know when it should quit.
4. In such design it is possible just run server process in some host in the Internet, so anyone can connect to it and play (or may be AI to)
Yes. We could even run a server and host multiple games there. It would not be much more development.
In any case we need to standardize the API methods/functions and expose them for the client part. May be separate module would be good for that. It will be easier to implement AI player, so it does not need any other file references.
I fully agree that more modules, standardization and also design documentation is needed. I kind of separated the game into the lib package (very general, not game specific), client package, server package and base package (what client and server both need). One could specialize the client package into a human client and an AI client probably.

Post Reply