Author Topic: Networking? Networking!  (Read 1453 times)

Offline Morgul

  • GNE Founder
  • Moderator
  • Grand Admiral
  • *****
  • Posts: 2086
  • Karma: +21/-4
  • Godlike Fuzzy Dice
    • View Profile
    • G33X Nexus Entertainment
Networking? Networking!
« on: February 21, 2006, 05:13:18 pm »
Well, since my last thread's a *ahem* adult only one, I figured I'd post something to make sugar plums dance in little children's heads... or something like that. Basically, we've been designing some sweet, sweet networking stuff. Now, this isn't the official design doc... that's going to be finished soon (It's on the wiki, but I'm too lazy to link. It's pretty simple to find.) however, I will outline some highlights of the current system.

Seamless Updates (For game content):

Basically, we started by designing a nice block diagram for the flow when a client load a 'region' (a region is the chunk of the universe that CS loads at one time. If you can see one single part of a region, that region is loaded. We can make regions as small, or as large as we want. More discussion on this it outside the scope and point of my little blog here.) After we had everythign as simple as possible, we looked at it, and realized it could be generalized to any time the client creates an entity.

Here's the meat of how this works. The client decides it needs to load something. It tells the server, "Hey man, I want to create this entity." Then the client starts creating it locally. The server will respond with a message to all clients, saying, "Hey guys, make this for me. Thanks." OR it will respond with a message to that client that says, "I don't know what your smoking. Knock that crap off." (Aka, "No.") If the client gets the no message, it deletes the entity. If it gets the update, it links that local entity to the ID of the entity on the network, then updates it's position and everything, if the server thinks it changed.

No, here's the seamless part. Before the entity is created locally, the client and server do a little dance to make sure the client has the files it needs. (Keep in mind what I'm outlining here can be for loading any sized chunk of the universe, from a region, to an entity, or even to the entire universe. It's as flexible as we need it to be.) The client tells the server, "Hey, here's a list of the checksums of all the files I need to make this entity." The Server then goes through the list. If it finds a file that doesn't match it's list of checksums, it then goes intoa  decision mode. If that checksum is from a version of the file that we've said is ok to run for now, or it's to an entity that currently isn't loaded in the chunk of the universe you're loading (like a missle that could eb shot by a ship, but hasn't been yet) the server will tell the client to start loading, and then it will send the client the updated data files. This way, it's updating while you play! Seemless!

Now, it's not really seamless. Let's say the version is 'blacklisted' and would really screw things up for you as a player if you loaded it. Then, we have two choices. If it's a small file, the server will send you the file, and the client will hold off loading till it gets it (hopefully not long enought for you to notice) or, it will put up a nice 'warning' on your screen, telling you it's updating your client files currently, so please wait. As soon as it's feasinle to load things in the background it will switch over to background loading, and you'll be in the game once more.

Now, a loading screen in the middle of a battle would be very annoying, huh? Well, the solution to that would be to have botha  server, and client side option. The server could be setup to FORCE all clients to update their files to the versions on the server. The client could also be set to FORCE an update before joining the server. This way, you have the choice to make sure you're up to date, unless the server is a very unstable one (meaning data files change a LOT on a frequent basis) and forces you to update. If you don't like it, play a different server.

No need to install mods!
This is an idea that branched out of the former idea. Basically, the only data files on the client are going to be prechached stuff anyway. Yes, I know that  the client is going to have modesl and all this other stuff with it. However, none of that is authoritative. The server tells you what an MX29000Ultra looks like, not your client. So, all game data the client has is merely a cache of gamedata. That's why we have this update mechanism built into our servers. So, why not take it one step further, and save different caches for different servers. If you're playing on a modded server, it will store that gamedata in a seperate spot from the gamedata for the official servers, or any other servers you play on. This way, you can use youe one client, without installing, or uninstalling any mods inorder to play. Very simple, no hassle.

Event Based System
We're working on an envet based update system that will allow us to minimize the amount of communication needed. Basically,the server and the client will each do their own calculations on how things should work. In theory, if they have the same files everything should be the exact same, always. However, a small amount of error can cause a very large amout of error latter on. So, we do need to update, but hopefully there won't be too much to change between one and the other.

Now this is assuming the client is running something that works the way we expect. If they're not, we don't care, since we don't support that. Keep in mind, the ONLY think a client is allowed to do in this event system is tell the server, "I got this input from my user". Then it decides what to do, and the server decides what to do. If the client decides that the X button kills everyone, sure enough they see everyone die... on thier own copy. Then the server updates, and everyone's alive again.

Psuedo P2P networking
An interesting problem we decided to tackle was p2p networking. Basically, in a p2p system, the clients would all have to be trusted. We can't do that, because cheating would be easy. Keep in mind, we're giving away the source to the client. We can't trust anything it tells us. So, we decided not to remove the server from the system. The server still is the only source who's gamestate we trust implicitly. However, if the client it lagging out, but still has a decent ping to some other clients, it should be able to get gamestate from whichever ones the server decides are 'good' clients, who've not sent any bad data in a while.

So the way it works is pretty simple. Included in the updates (or seperately and not as often) we will transmit a list of clients who are in good standing with the server. Any client who losses connection with the server for a bit will contact these clients, and request them to pass along the client updates. The 'trusted' client would then pass along updates for as long as the other client wants them. However, The server will be wathcing, and if the client is out of communication too long, it will drop the client. Also, the client CANNOT send messages to the server through the trusted client.

A little note. We don't really trust trusted clients. If the client is getting bad data from the trusted client (it get the updates form the server later, and they're pretty far off from the trusted client, and it has to make a bunch of corrections) it will tell the server who will log in as a client, request data, and see just how bad it is. Then it will decide to blacklist that client from being a trusted client.

That's it for now... those are just osme of the prieviews to come!
« Last Edit: February 28, 2006, 01:53:46 am by whitelynx »
"Just because my math may tell lies doesn't mean that I don't understand the quantum mechanics of it all." --Caenus

The popular videogame "Doom" is based loosely around the time Satan borrowed two bucks from Vin Diesel and forgot to pay him back.

"In the beginning there was nothing. And it exploded." --Terry Pratchett