Multiplayer Game Programming for Teens with Python: Part 2

I’m sure once in a while, your friends and you go online to play a multiplayer game. In this tutorial, you will learn about multiplayer game programming by creating a simple game. By .

Leave a rating/review
Save for later
Share

This is a post by Tutorial Team Member Julian Meyer, a 13-year-old python developer. You can find him on and Twitter.

Welcome back to our 2-part tutorial series on Multiplayer Game Programming for Teens with Python!

In the first part of the tutorial, you created most of the client for the game. You created the code that draws the lines to the screen, and allows you to put down new lines.

In this second and final part of the tutorial, you will finally get to the multiplayer part of the code by creating a server for the game that the clients connect to. Let’s get started!

Getting Started

The basic idea behind making a multiplayer game is that you have a game client, and your friend has a game client. To communicate between each other, both clients connect to a central server that coordinates the gameplay.

To create the server for the Boxes game, you’re going to use PodSixNet, a simple, lightweight Python networking library created by Chris McCormick. In layman’s terms, PodSixNet lets the player talk to the server. You’ll find that it’s easy to use and does exactly what you want it to do. You can learn more about PodSixNet here.

It works like this: First you run a PodSixNet custom server on a specific port (you can think of this like a mailbox with a particular address). You then run the client to communicate with the server through that port.

I’ve already included the PodSixNet code in the resources for the project which you downloaded earlier. But if you’d like to download a fresh version, you can download it here: PodSixNet-78

Go into the folder where you unzipped the file and you should see a file called setup.py. Follow the directions below to install PodSixNet on your computer.

For Mac Users:
Open a new Terminal window and type cd . Notice the space at the end of the command. Drag in the folder containing the unzipped PodSixNet file and press enter. Then type sudo python setup.py install and press enter. This will install PodSixNet so that you can use it anywhere on your computer.

For Windows Users:
Press shift while right-clicking the directory containing the unzipped PodSixNet file. Then click Open Command Prompt Here. Then, if you have Python in your path, type python setup.py install. If this command gives you a “Command Not Found” error, then you do not have Python in your path and you need to add it.

To add Python in your path, right-click My Computer and click Properties. Then click the Advanced Tab and then Environment Variables. Add one and put it in the directory to your Python folder, which should be something like C:\python2.7. Now proceed with the python setup.py install command.

To test out your installation, start up the Python interpreter by typing python in Terminal or the Command Prompt and pressing enter. Then type import PodSixNet and hit enter. If nothing happens, then you’re good. If there is some type of error, then post the error in the comments to this tutorial to get help fixing the problem.

The PodSixNet Skeleton

Let’s begin by creating a PodSixNet skeleton. This is something you can use whenever you want to use PodSixNet in your project just to make sure everything that is working.

Create a new file called server.py and put it in the same folder as boxes.py. Begin the file with this:

import PodSixNet.Channel
import PodSixNet.Server
from time import sleep
class ClientChannel(PodSixNet.Channel.Channel):
    def Network(self, data):
        print data
 
class BoxesServer(PodSixNet.Server.Server):
 
    channelClass = ClientChannel
 
    def Connected(self, channel, addr):
        print 'new connection:', channel
 
print "STARTING SERVER ON LOCALHOST"
boxesServe=BoxesServer()
while True:
    boxesServe.Pump()
    sleep(0.01)

This creates a simple bare bones connection that listens for connections on a default port. When someone connects, it prints out a message.

This code should work out-of-the-box (no pun intended), but it won’t do anything yet because you haven’t programmed the client-side. The changes you need to make to the client-side code are simple. All you have to do is initialize the client’s PodSixNet class and connect it to the server, and then you can send a variety of messages to the server.

Add this code to the top of boxes.py to import some needed PodSixNet libraries and timing:

from PodSixNet.Connection import ConnectionListener, connection
from time import sleep

Make BoxesGame extend ConnectionListener by changing class BoxesGame(): to:

class BoxesGame(ConnectionListener):

Add this to the bottom of the BoxesGame class’s init to initialize the PodSixNet client:

self.Connect()

Add this to the beginning of the update function to “pump” the client and the server so it looks for new events/messages:

connection.Pump()
self.Pump()

Now open up two Terminal windows. Use Python to run boxes.py in one window, and server.py in the other. When you start up the client, the server will tell you that a new client has connected successfully.

localhost:boxes rwenderlich$ python server.py 
STARTING SERVER ON LOCALHOST
new connection: <socket._socketobject object at 0x37ff48>

Adding Multiplayer Functionality

Your client and server are talking to each other! That’s great, but you still need to get your game on. Let’s add some functionality to do just that.

First you want your client to tell the server when it places a line. Find the code where you set a line as drawn on the board inside update. Make that part look like this:

if pygame.mouse.get_pressed()[0] and not alreadyplaced and not isoutofbounds:
    if is_horizontal:
        self.boardh[ypos][xpos]=True
        self.Send({"action": "place", "x":xpos, "y":ypos, "is_horizontal": is_horizontal, "gameid": self.gameid, "num": self.num})
    else:
        self.boardv[ypos][xpos]=True
        self.Send({"action": "place", "x":xpos, "y":ypos, "is_horizontal": is_horizontal, "gameid": self.gameid, "num": self.num})

Notice that this code refers to the new properties self.gameid and self.num. Add statements to initialize them to None in BoxesGame‘s __init__:

self.gameid = None
self.num = None

Now run the server and client and try placing a line. The server will log some messages showing the lines that you clicked on the client:

STARTING SERVER ON LOCALHOST
new connection: <socket._socketobject object at 0x3adb90>
new connection: <socket._socketobject object at 0x54db58>
{'gameid': None, 'is_horizontal': True, 'action': 'place', 'num': None, 'y': 5, 'x': 3}
{'gameid': None, 'is_horizontal': False, 'action': 'place', 'num': None, 'y': 5, 'x': 3}