View Full Version : Multiplayer & usage of publicVariable question
JW Custom
Sep 10 2011, 16:15
I have this progressbar which needs updating depending on who and how many is in a zone, now i'm wondering how to send the data from server to clients as it needs updating like every second.
Is it fine using publicVariable or will this cause desync?
Is there other better ways to do this?
P.S. if publicVariable is okay to use is it then better if i have several zones to add the calculations to a array and public that or public the calculations one by one?
I'm thankful for any help :)
Muzzleflash
Sep 10 2011, 16:30
Can't each player just calculate it themselves?
Unless the player is really far from the zone, like many km's he will see almost the same as the server. If he is far away then he doesn't really need to see the progressbar perhaps? Even if he does it will get accurate when he get's within some km's.
Don't really think you have many other alternatives to publicVariable if you want to send it. 'RE' and other scripts use publicVariable on the low level anyway. However, I would pack the data into one array instead of multiple single datum.
neokika
Sep 10 2011, 16:31
Hi JW Custom,
In this situation is imperative to only do it locally or there is a remote chance of becoming playable.
publicVariable every second is completely crazy to say the least. :D
Do your checks locally on the player machine to update the control.
_neo_
JW Custom
Sep 10 2011, 16:36
The idea is that the more players in the zone the faster it's captured. If i calculate it locally the next player entering the zone does not have the current capture state.
I don't think publicVariable every second as long as a zone is being captured is that crazy, every other change is broadcasted constantly anyway.
neokika
Sep 10 2011, 16:40
The idea is that the more players in the zone the faster it's captured. If i calculate it locally the next player entering the zone does not have the current capture state.
I don't think publicVariable every second as long as a zone is being captured is that crazy, every other change is broadcasted constantly anyway.
Then why send it over the network at all?
Do it on every machine, they will get the same results.
_neo_
JW Custom
Sep 10 2011, 16:43
Then why send it over the network at all?
Do it on every machine, they will get the same results.
_neo_
1 player enters a zone and sit there for 10 seconds and the progressbar reaches 7%.... now a 2 player enters the zone, how does he get the 7% state so his progressbar continues from there?
Muzzleflash
Sep 10 2011, 17:07
If the rate is that slow, then I don't see the major issue with sending the data. Just send it every 10 seconds or so. Is it really that important that each player get's every percentage? If you want it to look fluid then use the same algorithm on the client to guess/extrapolate how far it is every second and when a server value is received use that to correct if needed.
neokika
Sep 10 2011, 17:17
Doesn't that depend on your scripts?
Let me tell you what I understood from your initial question.
You have a progress bar (dialog), obviously this has to run on every player machine so they see it.
You want to check how many players are near a position:
_count = { _x distance _pos } count playableUnits;
_percentage = switch (_count) do
{
case 0 : { 0 };
case 1 : { 7 };
case 2 : { 14 };
etc...
};
No need to broadcast anything over the network.
Ofc, this is just an example, I have no idea how you are doing this, maybe you can post your script so we can see.
_neo_
JW Custom
Sep 10 2011, 17:41
Doesn't that depend on your scripts?
Let me tell you what I understood from your initial question.
You have a progress bar (dialog), obviously this has to run on every player machine so they see it.
You want to check how many players are near a position:
_count = { _x distance _pos } count playableUnits;
_percentage = switch (_count) do
{
case 0 : { 0 };
case 1 : { 7 };
case 2 : { 14 };
etc...
};
No need to broadcast anything over the network.
Ofc, this is just an example, I have no idea how you are doing this, maybe you can post your script so we can see.
_neo_
What i'm doing now is simply counting how many people is in my zone using countSide. The progressbar is showing from 0-100% when at 100% the zone is captured. But as muzzleflash said if i do the same calc on client side i just need to broadcast like every 5-10 secons to sync clients/JIPs with server.
If the rate is that slow, then I don't see the major issue with sending the data. Just send it every 10 seconds or so. Is it really that important that each player get's every percentage? If you want it to look fluid then use the same algorithm on the client to guess/extrapolate how far it is every second and when a server value is received use that to correct if needed.
It was just a example, the more players in the zone the faster it's captured.
It looks pretty dumb that 3 players in the zone has captured 90% then another player enters and reaches 10% or something and then it says "captured".
I guess i'll also calculate on clients and then publicVariable from server every like 5-10 sec to sync clients/JIPs.
Thanks for your inputs.
Muzzleflash
Sep 10 2011, 18:03
I made a quick prototype to show how it can be done. I don't know the details of how you are going about it so you will probably need to change some things if you use this.
This is the serverside
/* Serverside */
private ["_current","_rate","_lastTime","_pubInterval","_trigger"];
_current = 0; //Current percentage
_rate = 0; //The rate of increase per. time unit
_lastTime = -999; //Last time it was broadcast
_pubInterval = 10; //How often will broadcast to clients
_trigger = MY_TRIGGER;
//Initial broadcast
while {isCapturing} do {
_rate = 0.8 * ({side _x == capturingSide} count (list _trigger));
_current = _current + _rate;
if (time - _pubInterval > _lastTime) then {
_lastTime = time;
PV_CaptureData = [MY_TRIGGER, _current, _rate];
publicVariable "PV_CaptureData";
};
//Server player can get realtime data
if (!isDedicated) then {
PV_CaptureData call UpdateCaptureProgress;
};
sleep 1.0;
};
This is the client side:
/* Client side */
"PV_CaptureData" addPublicVariableEventHandler {
(_this select 1) call UpdateCaptureProgress;
};
UpdateCaptureProgress = {
private ["_trigger","_current","_rate"];
_trigger = _this select 0; //You mentioned multiple trigger. Ignore if not player not in this one. You might need to make this more complicated eg. side checks. No need to show for "uncapturing" side.
if (not (player in (list _trigger))) exitWith {};
_current = _this select 1;
_rate = _this select 2;
UI_Percent = _current;
UI_Rate = _rate;
UI_LastTime = time; //Assume we received it relatively short after it was sent
};
//Manages the user interface
[] spawn {
private ["_valueToShow"];
disableSerialization; //Needed to update ui in this function
UI_LastTime = time;
UI_Percent = 0; //Last value received not "current"!!!
UI_Rate = 0.8; //rate for 1 person. Just to guess until initial server value received.
while {showCaptureProgess} do {
_valueToShow = UI_Percent + (time - UI_LastTime) * UI_Rate;
//Ensure values within bounds
_valueToShow = (_valueToShow max 0) min 100;
/*
Update UI here using _valueToShow;
*/
sleep 1.0;
};
};
If the server is also a player (not a dedicated) then it should run both.
JW Custom
Sep 10 2011, 18:28
I already have the calculation done and the progressbar works fine, my post was about have all clients in sync and how often i could use publicVariable without causing desync.
But thanks anyway.
galzohar
Sep 10 2011, 20:48
There probably isn't a single answer for this, since a server with extra bandwidth should be able to deal with a lot more publicVariable spam than one that is already pushing its limits without any publicVariable spam. Overall I don't know though what actually is "reasonable" and what isn't.
Powered by vBulletin® Version 4.2.0 Copyright © 2013 vBulletin Solutions, Inc. All rights reserved.