A Server Question

Community Forums/General Help/A Server Question

feeble1(Posted 2013) [#1]
I have a little server/client setup that I have been playing with for some time. The server sends out all player and server controlled NPC information to each client.
Right now, I have a finite state machine on the server that is moving my NPCs around and deciding whether or not to attack the human players. I was wondering if it would be more efficient to run my NPC calculations in a separate little server. Then send the NPC positions to the main server and out to the clients.
Any thoughts or nudges in the right direction would be greatly appreciated.


UUICEO(Posted 2013) [#2]
If your going to be dealing with a large game with many clients then yes it would be better to have all the main aspects of the server broken in to their own server unit (login, account, NPC, Items, Quest) servers. Having a single main server keeping track of the world and taking input from the other servers as to what is going on in the world. This is the way I would go for a larger game, If your doing a small game with minimal clients then it really wouldn't be worth the extra effort to break everything apart and create the additional servers needed.


Brucey(Posted 2013) [#3]
Or you make your server multi-threaded so it can do many things at the same time.


Derron(Posted 2013) [#4]
Your server should not need to move npc using your server. Every action can be done on clientside. Your server just verifies data it receives from the clients. ("was it possible for enemy Y to get hit by player X with damage Z"). For "non-problematic things" (non-environment-changing/-involving) you can even skip those checks and just accept it. If the data is not valid, send a invalidate-flag back and the client just undos that action.

This will reduce the load of your server to just "data holding and data processing".


bye
Ron


feeble1(Posted 2013) [#5]
Thank you all for you interest and responses.

@UUICEO I really don't think it would be an issue to snap a bit of the server apart. I would still have to run each on the same machine though.

@Brucey Multi-threading sounds a bit like black magic to me. I have read about it, but haven't quite gotten my head around it. I'm just attempting to learn right now. But I am sure that I will eventually switch over to RakNet for this very reason.

@Derron So far I have 50 NPCs running off of the server. All the server does is add increments to an NPCs position. The clients are deciding whether an NPC gets hit or attacks. I'm not sure I could let the clients move NPCs effectively.


Derron(Posted 2013) [#6]
If the "AI" is coded into the client, each client can compute the AI movement by itself (with all having the same results).

If you want to update "small portions" you can store that small portions on the server - so some "magic" is done remotely and only a result is returned to the clients.

This all sounds a bit more than needed - but the more advanced you go, the more CPU cycles your calculations will need - which leads to higher loads on the server which lead to higher response times aka "latency" - in the worst case (clients have to wait for servers data to get next movement) they start to get "lags".


bye
Ron


feeble1(Posted 2013) [#7]
I would think that having each client manipulate the NPCs would cause a bit of confusion. I now have a bit of a dummy client/server sending npc location to the server. The results are better than I thought they would be and very consistent.

@Derron What do you think about assigning NPC calculations to the first client that enters a "zone"? Then, if another client enters with a better ping rate, migrate to the best client.


Derron(Posted 2013) [#8]
Why should one do this?

NO client should have to rely on something else (exception is validation of some things during logging in, getting detailed information about newly spawned creatures ...).

AGAIN: each client simulates its own "world". They only manipulate their own incarnation. Server is there to check if everything is "valid" and "possible".

Instead of server->client: "unit A moves to 10,10 then 10,11 then ..." it just says: unitA has movementType1, spawned at 10,10 at 1234354 gametime.


What has to get synchronized is: multiplayer. The server is the central base of knowledge about your neighborhood.
In this case "zoning" is useful. Players in a certain zone are getting synchronized.

In no case it should be needed that playerA directly communicates with playerB (IP1->IP2, all communication should be: IP1->SERVER->IP2).

Exception is if you have also LAN-ability, then there is no server but maybe a "lobby system".


bye
Ron


Brucey(Posted 2013) [#9]
You can see client generated NPCs running in GTA V online. Sometimes when someone is lagging, some of the NPC vehicles will appear to jump or pop - those that belong to the laggy client.
So you can spread the NPC load around your current clients.


feeble1(Posted 2013) [#10]
This is terribly interesting, but maybe a little complex for me. I am reading everything that I can find on the subject.
Thank you all for your patience!


Derron(Posted 2013) [#11]
The most easiest way is to do:

"client games" (like a "sologame"). But that clients should react to "external" data. So the server can send data like "spawn a car of type FastRedBully at x,y,z". Clients know how that car moves and is able to compute everything needed.
Another external data is player synchronisation. So (for the beginning: without zoning) the server sends you all necessary interactiondata (movement, kills, quest acceptance) from connected players.
As your client knows that a "kill" changes a unit from "living to dead" it is able to do everything needed (change animation, play sound ...). The server is also the one rolling the dices for loot/bonuses - this information is also spread around.

The clients are sending their interaction data to the server: I am moving forward, accepted the given quest, tried to "attack"/"cast spellX".


To have all clients compute the same things you cannot do things like:
Damage = Rand(1,100)+50
But will have to use mersenne-twister (take care to have the same amount of "calls" to the random function on each client) and use this for things like a "random number"-table calculation which you can refer to _multiple_ times.

If there is no "random" value at all - eg. Your bullets just kill an enemy, you need no "randomizer". This is just needful for things like DungeonsAndDragons with dices as base of all.


In short: nearly everything should be playable "alone". Next step is to interact with the server. The server is then extended to spread around the needed data received (and transformed) from other connected players.

Sounds way harder that it is :D.
Imagine your units have a Method "Control" which takes input like "forward". So now you call this method for YOUR unit as soon as "forward" is pressed. Later on you also call this in the moment you receive "unitControl"-network packets. But this time you run "theOtherUnit.control(...)".
That way you can also have Scripts controlling units. Just deconnect "action" from "input".



bye
Ron


UUICEO(Posted 2013) [#12]
Using the client to control any aspect of the game other than the users character itself is a design for allowing players to cheat. It's far better if you plan on having a commercial quality game to have the server handle everything and send the results back to the clients. It is the only way to prevent people from cheating and even this is not 100% but it is the best way to go about it.


Derron(Posted 2013) [#13]
@UUICEO
Please describe how cheating would be possible.

As I said: validation has to be done by the server there is no real ability to cheat.

Exception is "wall hacks" or other things. These can be circumvented with "position checks" by the server.

Each action: collecting loot, entering rooms, joining teams, ... is validated/checked by the server.

Any other exploitation of the game is just "local" and therefor a non-global-modification.

Eg you set the mobs-hp to "0", mob dies, ... mob is alive again as server could not validate the kill (eg. just 20dmg done of 100dmg). You may "cheat"/"hack" your local client to keep the unit dead. For all other players this mob is still alive ... your client is then just forcefully out of sync.
Local cheating ... uhmm ya.


bye
Ron


UUICEO(Posted 2013) [#14]
Simple packet manipulation prior to sending the update to the server. this would allow for super speed or anything else that the client would be able to control.

And as I said before, if the client is allowed to control these aspects, @Derron your version is not allowing the client to control anything since the server does checks which is the same as having the server control it.


Derron(Posted 2013) [#15]
Like said in the first postings: clients should calculate the movement ("did I stuck in a tree?").

Manipulation not useful - control packets are send server->clients not vice-versa.

@your version is not allowing the client to control anything:
I never intended to say that. The data given by the server controls the game. The Server says: Mob XY has 100 hitpoints, the car has a speed of 100mph... etc.
That is why it is possible to update "game data" without updating client side things.
Exception is "new formulas" - they require patching. If the server sends "interpreted formulas" (lua scripts) they could be modified locally etc. ... So they add another uncertainty which isn't useful. But sure ... there are many things realizeable in scripted things and they could get live-patched by simple servercommands.

The initial response to everything just was: the server does not need to update enemies or control ingame logic. Logic follows certain restrictions - and that restrictions are the things the server spreads around.

After spreading around each client could get "modified" to double values (movement speed) but this can be checked with "status updates" checking old and new position values (these values are needed for position synchronisation between players). Sure they can be manipulated somehow.
Therefor people have GameMasters to report to - they observe the players and take "hands on them" if they behave odd.

To aggressively fight cheaters is way more useless than lowering the hardware requirements and therefor running costs. There is no 100% sure way to get rid of cheaters except playing with your (trustable) friends on a real table.


bye
Ron


PS: @original topic:
My first answer to your question is still the one you should go for. You wont have a 10.000-players-setup and you should keep your work lightwheight. The "clients do all - server checks and gives rules" approach should be easier to implement than a "server does everything and informs others what to do". As soon as you run into performance-hungry loops things wont get better and you will have to split your code, work with interprocess-communication (or how you then process things on multiple computers to get things computed smoothly).


feeble1(Posted 2014) [#16]
How about a bit of a hybrid:
While in a wandering state, server controls npcs.
If a player comes within an npcs 'range' it switches to attack
A packet is sent to the clients to tell which npc is going to chase/attack which player.
If the player dies or leaves the npcs range, a packet is sent to the server and the server regains control. That npc starts to wander.

As for the sever controlled npc coordinates, they would only have to be updated every 250 millisecs or so.

I am rather enjoying this topic. Thanks again.


Derron(Posted 2014) [#17]
"mature" MMORPGS use the type of "waypoints". So NPCs walk along a certain path - if they leave it (because they aggro another unit - and attack them) they return to their path as soon as they return to a "idle" state.

In addition units can have AI states - "i got attacked, I run back to my house now" or other scripts.


All in all this is an information a client can request from the server (if the cached data is invalid or missing). All calculations are then done on the client side. Server just has to know "unit is moving home" - the rules define whether such an unit is invulnerable for that moment and other things.

In no way the server needs to calculate WHAT the unit is doing now or next update tick. It just knows that from deterministic behaviour.

So the server just behaves like a database with rules and information. So to keep things dynamic you eg. have a server database with items and their values. These values can be fetched and cached from clients. Same for spells/weapons (database holds information about damage, cooldown, area of effect / type of effect, immunities ...).

If your game defines different AI types the database just holds the information what AI a unit uses - and this can ... you guess it - be fetched by the clients.


Sure -- you could do everything on the server - but then the processing power increases for each connected player and load balancing and cluster building will be needed as soon as you reach a certain amount of concurrent users. If everything is done by the clients you will be able to have some thousand concurrent users on an average server (gigs of ram, a database and some scripts for communication with the clients).

There must be a reason that most things on websites are now offloaded to the clients instead of being precalculated by a server. Exception are "secret formulas". So you are using "back boxes" (give input and get output without knowing what happens inside) for things the players should not get that easy by looking at some assembler code.


So I just say it again: try to code it in a way, that your clients accept "external" input. This could come from keyboard, joystick, mouse, data files or even remote connections (sounds now more complex than it is) ... just split "action" from "reaction". At the end it does not matter if "Unit.Attack(otherUnit)" is called from the networkHandler or an localInputHandler or or ...


bye
Ron


feeble1(Posted 2014) [#18]
Thank you for the input. I will keep searching, reading and trying.