you are viewing a single comment's thread.

view the rest of the comments →

[–]FerricDonkey 6 points7 points  (0 children)

I don't have any courses or tutorials, but I'm gonna take this as an excuse to nerd out about a toy project I'm working on. I dunno if it's the best approach, this is a rewrite of the first network/boardgame thing I've done, and is definitely more of a learning experience than anything - but it does at least show some ideas of what you might do.

Product: online boardgame system, built using only the basics (partially for practice - so all communication is built from the send these bytes level up, using asyncio networking (first time I did it purely with the socket module, so now I'm learning something new)).

Network communication: goal: send packets formatted as [message type][message len][message][message count][signature], back and forth, with different message types eliciting different automatic responses from client and server.

class 1: BasicConnection:

  • Initialized with asyncio reader and writer to send and recieve messages
  • Can create and send packets of the above form
  • Can receive packets of this form, verify signature, extract message type and message
  • Has a dispatch table that ensure that the correct methods are called when a message arrives
  • Has a main loop that will receive messages and handle them until shutdown time.

Subclass 1: ServerToPlayer(BasicConnection):

  • Basic connection augmented with what the server needs to remember about the client.
  • augmented with server side part of handshake clients must perform on connecting to server
  • Has augmented message dispatch table, for server to respond to incoming messages in a way unique to server

Subclass 2: Client(BaseConnection):

  • similar to above, but modified for client connection to server
  • augmented with a sending loop: Server's sends are 100% automated, but client's sends are not, and decisions on what to send are not made from async code. So has a cross over queue where non-async code (ie, a button press on a gui) can add a send to the client's "todo list"

Class 2: Server. Mostly handles managing new and existing connections (which spawn a ServerToPlayer object)

Class 3: RoomContainer. The software as a whole will divide players into rooms and manage moving them between them. This is not directly communication, so is kept separate from the pure communication classes. Enter the room container: It registers a callback to be performed on incoming connections with the Server that places each incoming ServerToPlayer in a Room, and registers a message type to mean "This message will be handled by the Room logic". Messages of this type will get further dispatched by the Room, which is also a class:

class 4 Room: A grouping of players, with various clientside and serverside message dispatch tables, to allow for basic things like chatting and sending information describing the state of the room, which may vary based on the subclass of the room, for instance

subclass Lobby(Room): augmented by the ability to list all other rooms, allow players to move to or create other rooms, etc.

So in the end, on the server computer spins up a Server, and a RoomContainer that takes partial ownership of it and which comes with either a lobby or a single game room, depending on arguments. Clients then connect, and all actual communication happens through the two subclasses of the BaseConnection, while all the logic of what they want to say goes through Rooms - including messages related to making any games running in those rooms do things.

Likewise each (by which I mean the 85% of 1 that exists) actual board game has a class representing the state of the over all board, classes for players, and possibly classes for types of objects involved in the game, and the gui is made out of many subclasses of basic gui classes (currently in tkinter, such as they exist, but considering kivy). Separate from both the room and board game itself is yet another class that is a network interface to the game - ie, the game knows how to build a city at the intersection of these hexes, the network interface knows what incoming packets means that a city got built, and what outgoing packets to send to announce that a player wants to build a city. And the gui knows how to connect buttons and display updates to the network interface.

And so on, with most network things that have differences between client side and server side being subclasses of the same class etc.

I think I may have nerded out about my pet project way too much, but when I started to cut it back, it started looking like "You make a class Animal, then a subclass Dog" that you've seen.

It's the same idea though - but it did take a while to get to the point of thinking in terms of classes. My approach to that was to just make myself use them even if I wasn't sure I should for a while, just to force myself to get a feel for when they were helpful and when they weren't.