• Welcome to SC4 Devotion Forum Archives.

[Programming] Networking (multiplayer)

Started by tomkeus, September 01, 2009, 11:46:49 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

tomkeus

Well, before croxis, i'll have a thing or two to say on basic networking architecture. As I said, simulation engine will be in form of Python modules written in C++. In this, way, simulation will be Python application, so all networking can be done with Python sockets or SSL module. I think that will be right up croxis' alley. Let me give some pseudocode

Basically, within Python application we could have loop


while(not exit)
{
data = connection.receive()
if(data)
{
instructions = interpret(data)
execute(instructions)

%queue commands from graphics engine
%receive Advance() command
...
...
if(exit_command_received())
exit()
}

%do everything else simulation needs
connection.send()
%inform graphics engine of calculated changes
}


If graphics engine is to be written in C#, appropriate sockets interfaces will be written using C##'s API
#define TRUE FALSE /*Happy debugging suckers*/

croxis

Right.  I would personally separate the simulation and connection system, and connect them with an event manager.  Otherwise a timed out client would grind the simulation to a halt.

There is a critical decision to be made however with the client/server design in regards to what the clients do.  At one extreme the client is a dumb terminal, the server directly tells it what to draw and the client directly tells the server what was clicked.  Easy to do but can be very bandwidth intensive.  The middle option which most games use is that the client runs part of the game along with the sever, but only the information the client needs to know.  It works well to keep cheating and bandwidth down.  This wont work that well for a city sim though.  The final option is that the server and clients are essentially identical.  The only difference is that the server is the authoritative game state.  The idea behind this is that, with no player interaction, the simulator will always play out the same way.  The only data sent is the player interactions.  This is what openttd uses and what will probably work best.

In ascii art for tom's idea:


Python Server ---- GUI
|
|
Master Python Server
|
|
Python Server ---- GUI


The problem with this is that each client will have two communication connections, one to the remote master server, and one to the gui, and this will require two different sets of communication protocols.  If it was just dumb clients to a master server


GUI
|
|
Python Server --- GUI
|
|
GUI


then only one protocol will need to be developed and maintained.

tomkeus

#2
I opt for dumb clients and a one server. Here's why:

I don't see why client-server communication should be bandwidth intensive:

When players make changes within the graphics engine, they are sent to the simulation engine in the form:

SetIncomeTax(30...)
BuildRoad(RT_SINGLE_LANE, Tile1, Tile2,...)
DemolishObject(ObjectID...)
CreateZone(ZoneShape, ZT_RESIDENTIAL_LOW...)
...
...


Graphics engine doesn't send every click player made. It only sends actions to be performed over the city encoded in precise command list which typically would be no longer than couple of hundreds of bytes. When graphics engine internal clock counts down one month, and it has no more changes to make to city's appearance, it sends AdvanceOneMonth(...) to the simulation engine, making it execute queued instructions in background. When the simulation engine finishes, it will calculate new city state and inform graphics client of changes to implement to reflect new state:

Population = ...
CityIncome = ...
...
ConstructionUpdates = {{BuildingID1, 0.25}, {BuildingID2, 0.1}}
...
UpdatePollutionMap = {{Tile1, 1.7}, {Tile2, 1.3}, {Tile3, 1.4}}


It is entirely upon graphics engine to decide what to do with this stuff and how to implement it. For example, when it gets construction state update for various buildings in the form {BuildingID, PercentageCompleted}, it will find corresponding loop animation and change it to reflect construction advance. Again, it is completely in graphics' engine jurisdiction. Simulation engine doesn't know how things look like, it doesn't even care too much where things are in relation to each other (I will elaborate on that later - it is very useful idea). Simulation only knows about things which are relevant to computational model it uses. For example, it doesn't care too much about geometry of transportation network. It is rather concerned with it's topology. Again, this might seem little confusing, but I'll elaborate on that in separate topic.

So communication between GUI and sim end should be pretty compact.
#define TRUE FALSE /*Happy debugging suckers*/

croxis

After driving home I think we could just use mostly dumb gui clients.  I'll throw together a basic prototype tomorrow morning.

As far as actual protocol, On the panda3d forums I found this: http://code.google.com/apis/protocolbuffers/docs/overview.html

From the post: "Yeah the PB's are cool because thy provide uniform message format and ability to grow the format and having old code still work. You still need to figure out what kind of messages you would use."

I think this would work out well for a project like this allowing some asynchronous development between the clients and server.  There are also ports in all sorts of languages which also helps with flexibility.

I figure I will start prototyping some code tomorrow.

croxis

To those with netcode experience, which do you think would be better for the game server, multithreaded or asynchronous i/o?

croxis

I branched the existing repository on github and I am working on the basic server engine (event manager, sockets, etc)

http://github.com/croxis/CityMania/tree

Nique

Good,

Since we have to create a c++ base i think i'll remove all the c# files from the root.
Proudly developer of