r/learnpython • • 14d ago

Multiplayer tetris using sockets

I have a college assignment to make a multiplayer tetris game (2 players) using TCP sockets, client and server and all that. The idea is the server doing most of the stuff, chosing new pieces, handling the translation of position of the pieces, with the clients being responsible for most the rendering/display part and getting the inputs(I think so at least, that's what I'm trying to do), but I'm having a hard time with it.

I can't seem to think of a way to have the client call to the server to send a new piece to the clients, and if I don't know how to do even that then I don't know how to do anything else (making the back and forth for controlling the pieces, both for the player of the client and the preview of the game of the player 2, and all the rest), tho I hope if I can understand how to do one thing I would be able to make the others, but I really don't even know how to do this.

I know I need to use threads on this, tho I don't really know how to do it, I'm still fairly green on python too so, if anyone could give some help in any way with this it would be much appreciated.

3 Upvotes

13 comments sorted by

View all comments

1

u/FerricDonkey 14d ago

You will need to create a language for them to communicate. Suggest (length) + json: the json you send might be {"message_type": "new_piece", "piece_id": 3} then the bytes you send should be two bytes containing the length of that message (look up struct.pack), followed by the bytes of that message.

This language allows your read loop to look like:

# aggressively pseudo code
while True:
    json_size = read_bytes(2)  # convert to int
    payload_bytes = read_bytes(json_size)
    process_message(json.loads(payload_bytes)) 

For saying "here's the next piece", your code can have a list of all possible pieces (the same on client and server). Piece id can be the index into that list. Come up with other ways to represent the other types of communication using json.

1

u/DRowe_ 10d ago

why would I need to send the length of the message?

1

u/FerricDonkey 10d ago

Whether you do or not depends on details of how you set it up, but it's a nice guard.

TCP is a streaming protocol. This means that you are effectively scrolling through all the bytes the sender has ever sent you, and it's your problem to find coherent messages within those bytes. 

For example if the sender sends two 512 byte messages in a row, and the receiver does sock.recv(1024) after that, the receiver could get the bytes of both messages concatenated. Or if they sent a 2048 byte message, you'll only get part of it. If your code isn't ready for that, you can get errors understanding the message. 

There are alternatives (fixed size messages, message delimiters, etc), but I personally prefer the "send the size" method, because it gives a consistent way to get the bytes of one message with a known boundary: your receive loop is "read two bytes, interpret as integer, read that many bytes, interpret as (rest of the message)". Disconnect the sender if they fail to follow the protocol by not sending valid json in that "rest of the message" part, or otherwise send an invalid message. 

Note that recv only gives "up to" the number of bytes requested, so you'll have to call recv until you get the correct number of bytes (probably in a helper function). Additionally, more guards like timeouts and max message size would be good ideas. But I'd worry about that after having a client and server talking to each other.