Game Development Community

dev|Pro Game Development Curriculum

Python Master Server

by Andy Rollins · 04/28/2008 (11:55 am) · 55 comments

Download Code File

When a game client wants to connect to a game server it can scan the network to look for servers on a particular port, this is quite an effective solution when on a small network such as a Home/Office LAN but consider trying to scan the entire Internet looking for a game server, you'd be there for quite some time!!

Instead we employ a Master Server which is hosted at a fixed known address, for example the standard Garagegames master server used in the Starter FPS can be found at master.garagegames.com on port 28002. As each game server starts up it registers itself with the master server which then maintains a list of known servers, when a game client wishes to connect it requests the list of available servers from the master server.

The basic process flow for game servers is:
1. Game server sends a heartbeat to the master server to register itself (packet type 22)
2. Master server sends an Info Request (packet type 10) to the game server requesting more information i.e. game type, mission, number of players, number of bots, etc.
3. Game server Responds with info data and is added to the list of available servers. (packet type 12)
4. Master server drops server from it's list if it hasn't had a heartbeat in about 180 seconds.
5. About every 180 seconds game server sends another heartbeat and the process starts from step 1.


The basic flow for game clients is:
1. Game client sends a list request to the master server (packet type:6)
2. Master server responds with the list of available servers (packet type:8)
3. Game client then pings the game server
4. game server responds to ping request
5. Game client sends request for information to game server
6. Game server responds to information request.
7. The list of available game servers appears in the GUI (see script joinServerGui.gui in the starter.fps)

Ideally the master server filters the results based on game type, mission, num players, etc before responding to the client in step 2 - this is currently not implemented in this version of the master server although I do store all the data so you could easily add a function to do it.

I've tested this version using Python 2.5 and both TGE 1.5.2 and TGEA 1.7 so you should have any problems with those versions, to use it you should just edit the Configuration section at the top of the Masterserver.py and set the port to whichever number you require.

Then in your game edit the server\defaults.cs file where you should see a line that looks like:
$pref::Master0 = "2:master.garagegames.com:28002";

to point at your master server (remember to alter the port number to also match the one you set in the masterserver.py file. Examples:

using the local machine i.e. your own pc/laptop:
$pref::Master0 = "2:localhost:28002";

or via IP address:

$pref::Master0 = "2:192.168.0.200:28666";

or even an external site:

$pref::Master0 = "2:my_cool_domain.com:27531";

Note the "2:" before the hostname/ip address needs to be there it's an old thing from tribes and the engine expects it to be there.

I've been coding Python for the sum total of 4 days now so there are no doubt bugs within the code, let me know if/as you find them and I'll endeavour to update the resource with any fixes or improvements that people come up with.

Please feel free to use the code however you wish without restriction, although it would be nice to receive some credit if you do use it.
Page «Previous 1 2 3 Last »
#1
05/06/2008 (11:01 pm)
Hey Andy,
Just want to say THANK YOU, you answered quite a few questions that I had. However I do have one for you. I'm currently using godaddy for my web/database hosting and it does support python. How do python scripts actually get called and used? If I place the scripts on the site, and I start up toque and query the master server (with a static IP) will the scripts somehow just automatically be called.....? This is the part that I'm lost on, any help would be greatly appreciated.
Thx.
#2
05/07/2008 (5:26 am)
I'm also quite interested in the answer to that question. I'm looking to change my hosting, and after a first cursory look around, I would go with the shortlist of GoDaddy and Dreamhost. If GoDaddy would support the running of scripts, it would be a cool plus.
#3
05/08/2008 (6:11 am)
@ Dalo - Unfortunately no the scripts don't just somehow get automatically called, you have to manually start the master server yourself, on windows you can simply execute a command from a dos prompt with "pythoon masterserver.py".

On linux/unix machines you have two options, you can either do the /usr/bin/python/python masterserver.py or you can edit the python script and put the line "#!/usr/bin/python" at the very top which tells the OS where the python executable is and then simply run "./masterserver.py" as your command. (obviously I've assumed your hosting company installed python in the /usr/bin folder which could be different.

@ David - Unfortunately most companies don't allow you to run servers like this on shared web hosting and would point you at their VPS (Virtual Private Server) or Dedicated hosting options which are significantly more expensive. I've got a site hosted with Dreamhost myself and they've a very friendly support staff who I've bugged about various things in the past, they for sure don't allow you to run a master server if you look at their Terms or service it clearly states:

Any application that listens for inbound network connections (even if the application would otherwise be allowed) are not permitted.

The best bet if you aren't sure is to email the sales/support team prior to ordering, it'll give you a good idea how responsive/helpful they are... be prepared though I've yet to find a company that will allow things like this to run on shared hosting plans.
#4
07/07/2008 (2:54 pm)
Hey Andy,
I cannot for the love get anything to work on GoDaddy, I phoned them and was quite disappointed with there piss pore service/help. Do you have any suggestions for hosting sites or even dedicated server companies?
Thx.
#5
07/08/2008 (5:34 pm)
DALO - sorry to hear of your troubles, I am lucky enough to have friends that work for 2 different hosting companies so for most of my personal development and needs I use the free services I get there.

However, I am trialling right now a VPS server at serverchoice.com for a project I'm working on, primarily to see how a Virtual server would handle running TGE, so far I've been very pleased with the results we've been testing with the 3 devs and between 50-70 AI characters in game without any lag and the TGE engine and python master server, character server, patching server and mysql database all run 24/7. We have a bigger test this weekend 12th July as our game Zday hits an alpha v0.2 release and we have around 25 people lined up to test.

I have had to contact their support team as their firewall blocks all ports by default, a quick call to the support team and within 15 minutes they'd emailed me back to let me know they'd opened the ports on my server. They're offering a 3 month free trial at the moment, unfortunately I think it's only open to UK residents.

When looking at hosting options there are a few things to think about:
- Firstly you need to look at how much it'll be used, if its just a low usage for a small number of people then the cheapest VPS service you can find would be suitable, if you're planning on opening it up and using them a deal then you can't beat a phone call to discuss things.

- I'd always ask some questions before buying like firewall config, network connections - they might give you a dedicated server but it's useless if the network connection is slow, scaling up - can you swap packages and upgrade if you find you need more, etc. You'll soon find the companies with helpful staff. I always write an email explaining what we're doing, what we need to use, what our expectations are (cpu, memory usage,etc) and send it out to 10-15 companies and ask for their recommendations and costs - it's our general practice at work to use an RFI process.

- Phone them, emails are fine but a phone call tells you 2 things - how quickly they answer the phone and how knowledgeable/helpful that person is. See if you can have a discussion about potential discounts/sponsorship once you have a completed game that you want hosted, it's good advertising for a hosting company to have a hosted by banner on your website or in game, some are helpful and will listen and others will be a flat no.

- When looking at dedicated servers keep in mind some companies offer them as unmanaged meaning apart from offering support to ensure the server is up and running, it's down to you if things go wrong/break and they don't backup your site for you.

Keep in mind Cheapest is not always best, I'd rather pay a little more and get some good service
#6
08/15/2008 (8:14 pm)
Hey Andy,
So I picked myself an older G5 and thought I'd give it whirl to host my master server. I tried to run your python script and it keeps kicking back this error message:
File "", line 1
/Users/dalo/Desktop/MasterServer.py
^
SyntaxError: invalid syntax

I threw the code into text wrangler, which checks python scripts, and it said there are no syntax errors.....?
Any ideas?
Thx
#7
08/16/2008 (4:23 am)
How are you executing the script?

It's strange that it would say Line 1 which is a comment field - have you made any modifications?
#8
08/16/2008 (9:07 am)
Got it to work. All I did was re-save the file and it worked. I'm wondering if it had something to do with line endings. I know mac doesn't like window line endings.......anyways, thx for the script ;-)
#9
08/17/2008 (12:25 pm)
I am having trouble with this script. Here is my setup. Master Server is running on its own box. I start up a dedicated server and a client on my dev box. The dedicated server pings the master and it replies back. When I go into the client though and query the master server it says nothing is found. However if I query the LAN servers it picks it up everytime.

Tried with both TGEA 1.7.1 and TGE 1.5.2.
#10
08/18/2008 (6:05 am)
DALO - Great news

TheClaus - It sounds like you may have issues with port forwarding, when you say you're running the Master server on it's own box is that box outside of your LAN? If so when your game server connects to the master server it will be logged with your WAN IP address rather than the ip address of your machine in your local network.

Typically your network would look like this:
LAN IP
192.168.0.1    - PC 1 in your LAN
192.168.0.2    - PC 2 in your LAN

Router
192.169.0.100 - Local IP address for Router
82.56.23.84 - WAN IP address used for traffic on the internet.
When you connect to any website, server, etc on the internet that site sees the WAN IP address of the router (82.56.23.84) in this instance. Routers are smart an know if PC 1 connects to something then any returning information is meant to go back to PC1 on the network.

That's why your game server can connect to the master server and you see the master server responding, because your router knows the game server started the conversation.

On the game client side however if you look at my process flow in the resource you'll see that in step 3 the game client tries and pings the game server... this will effectively ping your WAN ip address and that's where your problem will most likely be... how does your router know that this request coming into WAN IP is for PC 1 or 2? It doesn't.

If you look at your console.log file for the client you will see something like:
Querying Master server..
Retrieveing server list packet 1 of 1..
Pinging server 82.56.23.84...
Pinging server 82.56.23.84 (retry 2)...
No servers found.

Sorry it's written from memory so the actual text will be different but if that's the kind of thing you see then it's port forwarding issue, you can see it gets the reply from the master server but then can't connect to your game server.

Port Forwarding is just basically a rule you setup on your modem to say if I get a request coming to my WAN IP on Port 28000 (the default port for TGE) then forward that request to this LAN IP. You can find instructions at www.portforward.com/ for configuring port forwarding on a lot of routers.
#11
08/18/2008 (8:09 am)
Here is my setup it is all LAN.

PC1 - 192.168.1.6 - Running just the Master Server on port 28002
PC2 - 192.168.1.11 - Running both dedicated server and client, server is on 28000

Here is what I get on the dedicated server.

Sending heartbeat to master server [IP:192.168.1.6:28002]
Received info request from a master server [IP:192.168.1.6:28002].
Sending heartbeat to master server [IP:192.168.1.6:28002]
Received info request from a master server [IP:192.168.1.6:28002].
Sending heartbeat to master server [IP:192.168.1.6:28002]
Received info request from a master server [IP:192.168.1.6:28002].
Sending heartbeat to master server [IP:192.168.1.6:28002]
Received info request from a master server [IP:192.168.1.6:28002].
Sending heartbeat to master server [IP:192.168.1.6:28002]

This is what the client is seeing.

ServerQuery:  start Querying LAN servers 0
LAN server ping: IP:Broadcast:28000...
ServerQuery:  ping Waiting for lan servers... 0.5
ServerQuery:  query Querying servers: 1 left... 0.5
Querying Server IP:192.168.1.11:28000 (3)...
ServerQuery:  query Querying servers: 0 left... 1
ServerQuery:  done One server found. 1
ServerQuery:  start Querying master server 0
No master servers found in this region, trying IP:192.168.1.6:28002.
Requesting the server list from master server IP:192.168.1.6:28002 (2 tries left)...
Received server list packet 1 of 1 from the master server (1 servers).
Pinging Server IP:192.168.1.11:28000 (3)...
ServerQuery:  query Querying servers: 1 left... 0.5
Querying Server IP:192.168.1.11:28000 (3)...
ServerQuery:  query Querying servers: 0 left... 1
Server IP:192.168.1.11:28000 filtered out by rules set. (snl:afxDemo)
ServerQuery:  done No servers found. 1
ServerQuery:  start Querying master server 0
No master servers found in this region, trying IP:192.168.1.6:28002.
Requesting the server list from master server IP:192.168.1.6:28002 (2 tries left)...
Received server list packet 1 of 1 from the master server (1 servers).
Pinging Server IP:192.168.1.11:28000 (3)...
ServerQuery:  query Querying servers: 1 left... 0.5
Querying Server IP:192.168.1.11:28000 (3)...
ServerQuery:  query Querying servers: 0 left... 1
Server IP:192.168.1.11:28000 filtered out by rules set. (snl:afxDemo)
ServerQuery:  done No servers found. 1
ServerQuery:  start Querying master server 0
No master servers found in this region, trying IP:192.168.1.6:28002.
Requesting the server list from master server IP:192.168.1.6:28002 (2 tries left)...
Received server list packet 1 of 1 from the master server (1 servers).
Pinging Server IP:192.168.1.11:28000 (3)...
ServerQuery:  query Querying servers: 1 left... 0.5
Querying Server IP:192.168.1.11:28000 (3)...
ServerQuery:  query Querying servers: 0 left... 1
Server IP:192.168.1.11:28000 filtered out by rules set. (snl:afxDemo)
ServerQuery:  done No servers found. 1
Server query canceled.
Exporting Gui preferences.
Exporting server prefs...
Exporting client prefs
Exporting server prefs
Cur. D3DDevice ref count=1

Here is what the Master Server output is.

Heartbeat from IP: 192.168.1.11  Port: 28000
Sending Game Info Request IP: 192.168.1.11  Port: 28000
Game Info response from IP:  192.168.1.11  port:  28000
    Game type    :  afxDemo
    Mission type :  MageVSMage
    Number Bots  :  0
    Num players  :  0
Heartbeat from IP: 192.168.1.11  Port: 28000
Sending Game Info Request IP: 192.168.1.11  Port: 28000
Game Info response from IP:  192.168.1.11  port:  28000
    Game type    :  afxDemo
    Mission type :  MageVSMage
    Number Bots  :  0
    Num players  :  0
Heartbeat from IP: 192.168.1.11  Port: 28000
Sending Game Info Request IP: 192.168.1.11  Port: 28000
Game Info response from IP:  192.168.1.11  port:  28000
    Game type    :  afxDemo
    Mission type :  MageVSMage
    Number Bots  :  0
    Num players  :  0

If you need anything else let me know.
#12
08/18/2008 (5:48 pm)
You are getting results returned if you look at the logs for the client, and it pings the server ok - what's then happening is that server is being filtered out because it doesn't match the game server you're looking for:
Server IP:192.168.1.11:28000 filtered out by rules set. (snl:afxDemo)

The bit in brackets at the end (snl:afxDemo) are the game types, the first being the game type the client is looking for (snl) and the second being the server game type (afxDemo) - as these don't match you're getting the results thrown away.

You need to set both $Client::GameTypeQuery on the client
and the $Server::GameType on the server (be warned this variable is set in 2 places so you may have it being overwritten).
#13
08/18/2008 (6:46 pm)
Is there anyway to not have it filter?
#14
08/19/2008 (3:45 pm)
I believe if you set the game client variable $Client::GameTypeQuery to be "any" that should select all game servers.
#15
08/19/2008 (4:00 pm)
That worked perfectly. Great script. I have been using it for a couple of days and it is very stable. You might want to mention something in the resource article that explains were to change the Querytype. That was my problem and once I modified it the whole thing just started working.
#16
09/05/2008 (12:16 pm)
Hello,
So I've been messing around with all of my server variables to try and distinguish the different types of games being hosted and in doing so I have not been able to get my Multiplayer working for several weeks now. My Gametype server variable is the name of my game and the missiontype variable changes for the different mission types. I think I've managed to solve that issue, which was the same as Eric's above. But now I have a MaxPlayer filter stopping clients from joining, all $pref::Server::MaxPlayer variables are set to 10?. Where is it that when you create your server that these variables are being called? Are the variables being extracted from scripts in engine? If so which variables are being extracted? Is it the $Server:: variables or the $pref::Server:: variables? or both?

When I start my multiplayer game the Master Server only shows 4 lines:

Game type : Koth
Misison type : T1
Number Bots: 0
Num players : 0

That's it. When a client tries to connect it'll show the whole list of server variables on the Master Server. But the client cannot connect because of the MaxPlayer filter.

All in all there are so many variables everywhere it's very confusing in which ones do what? Why are there 2 sets of pref.cs files, in common and in your game? Can I delete one so there's no inconsistencies?

Another thing is that when I call getServerCount(); from the client, I get 0 back. It doesn't even obtain a server........?

I've just plastered a pile of questions. If anyone can shed light on these questions then that would be wonderful.
Thx.
#17
09/05/2008 (11:31 pm)
Ok, that was a nightmare, I totally blame GG for this. According to this TDN page TDN Docs It sais that if you put 0 (zero) for maxPlayers, or bots or whatever then there is limit. Well, that's bogus. If you put zero you cannot connect. So setting the max whatever to a high number will connect you to a master server, not zero.

Hope this helps someone down the road.........
#18
09/09/2008 (2:24 pm)
Andy I am going to create a resource on a login system and I would like to advertise your resource in a step I am doing. Would this be okay?
#19
09/09/2008 (2:56 pm)
Eric, I am most definitely interested in your upcoming resource. Will this be using a mysql database to fetch users?......just curious.
Thx.
#20
09/09/2008 (3:01 pm)
Actually it is using the HTTPObject connected to a PHP backend. So if the PHP page is connected to a mysql then it works. Right now I am using serialize for PHP.
Page «Previous 1 2 3 Last »