Skip to main content
GameDev.net gamedev.net
🔒 Locked

Single server, MANY games

Started by TheGecko Sep 2, 2006 at 12:59 AM 11 replies 3.5k views
Original Post
TheGecko
TheGecko
Hey people. First off, I just want to say I'm not new to coding. I'm mainly a game / engine programmer and I have never done any type of network programming before. I know the basic concepts of networking in games, but have never really implemented networking into any of my games before. I need some help as to where to start looking for code or samples, etc. on the following scenario: I wish to implement a multiplayer network sports game where there are 2 football teams battling it out against each other. However, the SERVER is the one doing all the AI and movements, etc. and the clients are just dumb terminals that receive the results from the server and render everything on the screen. There is NO input from the client at all. All he does is watch the match play out. The catch here is, however, I wish to only have one server doing all the work even if there are 200 games going on at the same time. This is so that the server maintains the game even if any one or both of the clients quit their games (either by closing the game or if a crash occurs) Did any of that make sense? The server is simply 1 exe program that I assume will be running a thread for each game that is created. I know I should do a search in the forums, but I'm not sure what I should be searching for. Can this sort of thing be done? Don't worry about the power of the server, I just need to know how to go about doing all this with just one exe running that accepts conections, starts a new game, feed the results to the clients in real time and then kill the game once it is finished. Any help would be great. Thanks!
hplus0603
hplus0603
The biggest question is likely the simulation cost of each game. If you have 200 simultaneous games, then each game can't take more than 0.5% of the CPU.

However, if you can simulate faster than real time, you're likely better off to simulate the entire game, and then send the results as sequences of player movements, and the clients can view the game as an "offline" experience. You could even have the client support Tivo-like controls with pausing, rewind, and slow motion. Then, when there's heavy load, the clients have to wait a little longer for their match results, which leads to self-balancing load.

400 TCP connections is not a big problem for hardware these days, although you probably ought to host this somewhere central to the net, rather than in your closet :-)

An additional resource is the Forum FAQ, btw.
enum Bool { True, False, FileNotFound };
Bob Janova
Bob Janova
I don't know if it's directly relevant to your problem, but this CodeProject article (by me) about a game lobby for multiple small online games mayt be of interest.
TheGecko
TheGecko
Thanks for the response guys! I knew I'd find some answers here :)

I think what I'm looking for is more of how to design this system programatically. I'm not sure how to write server code to "spawn" a new game everytime 2 people on the net start a game vs. each other.

Basically, this is how the game works:

(1) Player A logs onto the game client and starts a game and waits for an opponent to connect. His game client sends info to the central server and the server "spawns" a new thread of the new game and waits for a challenger.

(2) Player B sees Player A's game on the server and decides to challenge him.

(3) Player B connects to Player A (via the main server)

(4) Now that both players are connected and ready, the server starts the "game" and does ALL the AI, etc. of both Player A & B's team.

(5) Player A & Player B simply sit back and watch the game unfold until it's over. Once the game is over, the server program writes the results to a database and closes this game thread.

Scenario:
---------
(6) Player B's computer crashes for some reason in the middle of the game and he has to reboot.

(7) After reboot, Player B logs back into the game with his game client and continues watching the game from where he left off until the game is over.

This scenario is the reason why I want a central server to do all the AI and database logging. Imagine if Player B is losing the game to Player A and does not want his record to show that he lost this game, he can simply quit the game client and leave. I'm trying to avoid situations like this.


So, with the general layout of what I'm trying to do above, I need some guidance as to where to start coding the server bit. I've already made a basic client and all is well, but there is no server to control them.

I'm not worried about server load. More servers can be added without any problems and clustered together for load balancing :) I just need to be pointed in the right direction as to WHAT I should be reading up on.

Anonymous: Thanks for the info! And I'm definately using C++. Not just that, but the server will also be coded in MFC (I LOVE MFC).

hplus0603: That's EXACTLY what I'm trying to do. I just don't know where to start looking :(

Bob Janova: Hey! That's maybe what I'm looking for as a sample to start off. I'll take a look at it after work today and mess around with your code :)

Added: Wholly crap! Bob, that's almost what I'm trying to do! Good job man! Mind if I email you sometime down the line if I run into problems?

If anyone else has any more input, please feel free to post :)
hplus0603
hplus0603
The MFC socket wrapper is known to have bugs. I would seriously stay away from that, and use plain WinSock instead.

For your server architecture, I would perhaps do it a little more asynchronously. The server sits and processes requests for games in a queue. Games are then processed (simulated, whatever), and the resulting game record is stored in a database.

Meanwhile, connected clients can request that games be run (the match-up in your case). Once a game is requested, the clients pretty much forget about the request (although they might show some UI saying "game pending").

There is then a mechanism on the server that is responsible for telling connected clients about game results they have not yet seen. This mechanism likely works in two phases:
1) When a client connects, all un-seen games in the database are sent to the client, and once the client acknowledges, marked as seen.
2) When a client is already connected, and a new game is added to the database involving this client, the game is sent to the client, and when the client acknowledges, marked as seen.

So the process is likely less synchronous than you make it out to be, but at the same time, simpler. Client processing looks something like:

1) receive message or user input when available
2) process message if received
3) process user input if received
4) send any response necessary

The messages to a client have the types:
- server notifies about a game result
- server notifies about an accepted game challenge
- chat or other data from a matched-up player

The server loop looks like:

1) receive message if available
2) process message if received
3) check for asynchronous event completion
4) send any response necessary

The messages to a server have the types:
- new client connecting
- make game challenge
- send chat or other data to a matched-up player

I would structure it with an event queue for asynchronous tasks, one object per connected player, a queue of data to send for each connected player, and a database object that can record game state. Each step of the system just moves data from one to the other -- no large, synchronous tasks. When a match start event is received from both players, a match event is put into the queue. When that event runs, the match is simulated, and the result posted back into the queue. When the result is processed, the database stores the result, and if the players are online, post the notification to their output queues. Etc.
enum Bool { True, False, FileNotFound };
TheGecko
TheGecko
I think I get what you're saying, but what I need to do is show the game being played out in real time 3D. The game clients are not just UI or anything like that. There are 3D actors with skeletal deformations running around on a field doing actions sent by the server and seen by the client. (Maybe I didn't make that clear :p)

But this is a real time 3d game where the AI and logic is being done on the server and then rendered on the clients. There is NO input from the client whatsoever. All the client does is sit on his ass and watch the match play out till its over.

Also, I don't want info being passed back and forth from the database all the time. Only when the match is over does the server write the final results to the database.

Hope that clears up things a bit :)
Bob Janova
Bob Janova
Yeah, it sounds like your game could be implemented as a serverside game in my system. Feel free to email me if you have problems understanding my program! (I think you can do that through CodeProject; if not you can PM me for my address.) If you make a big success, please acknowledge me :P. I don't actually have the code with me at the minute, though, so my help might be limited.

I'm a little curious as to why anyone would want to 'play' a game where the players get no interaction!
hplus0603
hplus0603
Quote:
this is a real time 3d game where the AI and logic is being done on the server and then rendered on the clients. There is NO input from the client whatsoever


I'm assuming this is a "fantasy football" kind of game, where the composition of the teams is the main challenge of the game.

I think you mis-understood my proposal. If you do the math: 200 games at a time, means each game only needs 0.5% of the CPU (you can fake AI and physics a WHOLE LOT -- see below).

Thus, a 15-minute game would actually only take 4.5 seconds to calculate on the server CPU. Thus, you could calculate the entire game (faster than real time) when the game is "started", and then send the entire game results to the clients as a stream. The clients then view this at their own leisure (and can start viewing when you start streaming the game result, probably don't need to wait until end of receipt). The 5 seconds to process a game can easily be hidden by showing the players huddling, walking up to the starting line, doing poses for the crowd, etc, before the game starts going.

Now, the data you send (assuming football) just needs to be "player X moves using stance Y to position Z" and other such actions (tackles, pile-ups, passes, etc). The clients can then, in real time, run character controllers and physics at high resolution, figuring out the specifics of what to display, how to animate the players, etc. That puts the processing where it's cheap for you -- on the client machines! The outcome and play of the game is already decided, you just use the client as a really, really smart "decompressor" of the game stream, which knows how to "dress up" the data stream to make it look good.

Anyway, even if you end up wanting to run the games real-time on the server, you can still use the same architecture, there's just a whole lot more events to service for any one individual game. It still solves the problem of clients disconnecting (including both clients disconnecting!) etc.
enum Bool { True, False, FileNotFound };
Bob Janova
Bob Janova
If there is genuinely no way for the clients to affect the course of the game, Hplus is right. However that would be a pretty dull way to spend 15 minutes – even management games would typically let you intervene and change your tactics if it's all going wrong.
TheGecko
TheGecko
hplus0603: That's the word I'm looking for.."fantasy football". I didn't know what you would call it :)

Anyway, what you said is absolutely correct. This is a "fantasy football" type game where the player manages a team, trains his players and then sends them off against another team and watches them battle it out. For now, I haven't really spent much time thinking about input because I don't think that it would really matter in a 10 minute game :p You could speed up the game if you like however if you start getting bored.

But, on the subject, I'm actually interested in how do you do all the AI calculations in 4.5 seconds :p I guess nothing is being rendered on screen, so the AI should just execute as any normal program. But it's hard to picture this as a programmer without something to see on screen :p

hplus0603: Referring to your idea of streaming the "game result", I'm curious as to what it is I would be streaming exactly. From a programming point of view, would I store all the "game result" in memory and then push the entire buffer from memory into a packet and send that off to a client? That could be a pretty big buffer if I did it that way. Or do I write everything to a script file for example and then the clients would execute that script after they've downloaded it?

Maybe, what I'm trying to ask is, what is the execution exactly? :p (Not sure that makes sense)

Oh and thanx to both of you. All that you guys are saying has been really helpful in my project :)
hplus0603
hplus0603
Quote:
what is the execution exactly


That's what you need to solve!

Note that, from a networking point of view, whether you're sending a single memory buffer, or "downloading" a "script file," it's all the same thing; it's just bytes over a pipe. How the server produces it is a server-side problem, and how the client interprets it, is a client-side problem.

The number 4.5 seconds came from your stated goal of doing 200 simultaneous games on a single server. If you have a less ambitious goal, then you can spend more time on each game, of course. And, while developing, you absolutely want to have a visualizer, which probably supports stopping time and slow-motioning the simulation. That doesn't mean your deployed solution needs to run that slow, though.

I already described the data I would send as "the match" -- player movements and outcomes in fairly coarse terms, and then let the clients fancy up the presentation by playing running animations, doing ball physics (with cheating to get the right result) etc.
enum Bool { True, False, FileNotFound };
TheGecko
TheGecko
Thanks for all the help hplus! I'll take a look and try out a simple prototype tonight. Hopefully, I should get something up and running soon. Maybe with some simple boxes and spheres :p

Thanks again for all your help guys!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.