RPC calls vs State sync

Hi all!

We have some issues here with our networking parts for our upcoming game.
It has around 100 moving objects so we need to be really careful on how we do networking

We have a working solution using a customized "GraduallyUpdateState" script...
One problem remains though, we use about 100+ kb/s of bandwidth!!

So in order to lower this number i was thinking of trying to use RPC calls instead, only syncing at specific moments
Since the object move along either the z or x axle, I was thinking of just updating the position when the object turns in the corners.
Both the clients and the host move the objects at the same speed, so on the "straight path" there will be no packets sent...

And its here RPC calls come in :)
How expensive do you guys think this will be?
Is it cheaper to just use state sync on all objects or could it be cheaper to sync them all via i.e

// On host only
if(Network.isServer  direction != lastDirection)
    networkView.RPC("UpdateSync", RPCMode.Others, direction, position)

@RPC
function UpdateSync (dir : int, pos : Vector3) {
    // Update direction and stuff here
}

And yes, we use a int as direction ;)

Perhaps anyone has experience with something similiar?
Additional thoughts?
We desperately need help with this, the game more or less depends on it :(

Thanks
André

I don't assume they are all straight in front of the cam, right?
In that case, do not update all every time.
Update the other basing on their distance to the object you want to sync (update radius). the further away, the lower the frequency and outside of a given distance you don't sync them anymore. Sync highly important information on every of those syncs and lower important information not everytime and / or basing on distance as well (rotation for example makes no sense to be synced when the object is further away, you won't see the difference most likely)

especially make sure you don't try to sync in realtime ... 20 times a second is more than enough normally.

thats how MMOs do it and you will be targetting a similar structure most likely + optimations from online shooters with data compression for example.

Well, actually they are in front of the camera at all times...
You can have a look here:
www.frikkinsoft.eu/SpookBustas/SpookBustasWeb.html

Since they move in a predictable manner and the arrows that the players set out are synced, we might get around by syncing positions fairly seldom since they should at least be close to the "real" (server) position

Is perhaps a very low Network.sendRate a solution? Say something like 1-2 times per second?

If it is not action oriented, a low sync rate definitely will help.

the other thing is that it seems to have only 4 or 8 directions.
So at best you just sent directions. with 4 directions thats 2 bit, with 8 directions its 3 bits to send per object.

compared to 12+ bytes (-> 8*12 = 96Bit) if you send 3 positions for example.

the more restrictions have have on the states, the more you can reduce the amount of data that needs to be send to syncronize those unique states for example.

It's very much action oriented, although the behaviour of all the objects is pretty much predictable...

There is only 4 directions that has to be synced yes, so that should not pose a problem :)

Should NetworkStateSynchronization still be set to ReliableDeltaCompressed??
Or is it safer to use the "Brute Force" option?

I have some serious networktesting to do tonight :P

Hmmm, the only way of getting a reasonable bandwidth usage out of this is to just sync the direction variable...
And just that uses 17-20 kbit/sec !!

This can't be a good solution, as soon as a packet is a little too late the object continues to move away in the wrong direction...
So some sort of position sync is necessary :(

I tried to solve this by using OnSerializeNetworkView() to sync position with a sendRate of 1 (and 2 and 3...) and just set the direction via an RPC call..
But it seems that "normal" RPC calls is only called at "sendRate speed" too

Is it possible to use 2 different sendRates??
Or am I forced to sync "manually" via timers and RPC calls?

Do you mean kbytes/s or kbits / s

the later would be no problem at 20 kbit/s, this would be 2.5kb/s, even a 56k would be able to keep up to 3.5-4kb/s

It is kilobits so no, its not much (had to pick out my calculator here :P)

But when syncing positions its around 37 kilobytes / player...
Thats not good :(

Well well, I will have to try this "manual RPC networksyncing" approach...
Ill keep ya posted ;)

Any thoughts still appreciated!! :)

37kb/s is insane ...
Do you have "free positions" or is it more grid like?
Because if it is gridlike you could actually update the grid position instead of a 3D world position.
This would need 2 byte instead of 12 bytes (x,y if the index is smaller than 256)

Whohoo!!

After a quick n' dirty codechange this morning with "grid syncing" I got it down to 55-60 kbits/sec - around 7 kb/sec...
So with 4 players (including host) it should be playable on around 20 kb/sec :smile:
Muuuuch better than 120 kb/s ;)

Thanx for all the help dreamora!!

Now I just got to figure out a good approach to sync the positions of the objects to the grid...
Need a really quick searchalgorithm here :P

Thanks again!

hey out of curiosity --

How are you determining how much bandwidth you're using? I'm working on this right now, and since everything happens under the hood I haven't found a way to measure whether or not I'm generating too much traffic.

I've seen windows-based packet-forwarding tools in the past that will both simulate limited conditions and provide data on exactly what's being sent -- but I haven't found an equivalent for osx.

Does anyone have a good tool for this?

I've been using the Network page of Apple's Activity Monitor. It gives me a rough idea, anyway. There is also something similar in the Task Manager in windows.