Jump to content
Sign in to follow this  
commanderx

Lags in Multiplayer cause of hint?

Recommended Posts

Hi,

I have following code after resolving a mission. With this code I have big lags every 10 seconds always when the script runs.

What ist the best way to make this lag free and what is causin the problem so that I can avoid it in the future?

[color="#FF8040"][color="#191970"][b]waitUntil[/b][/color] [color="#8B3E2F"][b]{[/b][/color]
[color="#191970"][b]sleep[/b][/color] [color="#FF0000"]10[/color][color="#8B3E2F"][b];[/b][/color]
 [color="#8B3E2F"][b][[/b][/color][color="#7A7A7A"]"Aufgabe geschafft, begeben Sie sich in die Basis zurueck, damit eine neue Aufgabe erstellt wird.\nVorsicht, es können sich noch feindliche Einheiten in der Umgebung befinden."[/color][color="#8B3E2F"][b],[/b][/color][color="#7A7A7A"]"hint"[/color][color="#8B3E2F"][b],[/b][/color][color="#000000"]nil[/color][color="#8B3E2F"][b],[/b][/color][color="#000000"]true[/color][color="#8B3E2F"][b]][/b][/color] [color="#191970"][b]call[/b][/color] BIS_fnc_MP[color="#8B3E2F"][b];[/b][/color]
[color="#8B3E2F"][b]{[/b][/color]
	[color="#191970"][b]if[/b][/color] [color="#8B3E2F"][b]([/b][/color][color="#8B3E2F"][b]([/b][/color][color="#191970"][b]side[/b][/color] [color="#000000"]_x[/color] [color="#8B3E2F"][b])[/b][/color] [color="#8B3E2F"][b]=[/b][/color][color="#8B3E2F"][b]=[/b][/color] [color="#000000"]west[/color] [color="#8B3E2F"][b]&[/b][/color][color="#8B3E2F"][b]&[/b][/color] [color="#191970"][b]isPlayer[/b][/color] [color="#000000"]_x[/color][color="#8B3E2F"][b])[/b][/color] [color="#191970"][b]then[/b][/color]
	[color="#8B3E2F"][b]{[/b][/color]
		[color="#1874CD"]_distance[/color] [color="#8B3E2F"][b]=[/b][/color] [color="#000000"]_x[/color] [color="#191970"][b]distance[/b][/color] [color="#1874CD"]_base_marker[/color][color="#8B3E2F"][b];[/b][/color]
		[color="#191970"][b]if[/b][/color][color="#8B3E2F"][b]([/b][/color][color="#1874CD"]_distance[/color] [color="#8B3E2F"][b]<[/b][/color] [color="#FF0000"]50[/color][color="#8B3E2F"][b])[/b][/color] [color="#191970"][b]then[/b][/color] [color="#8B3E2F"][b]{[/b][/color][color="#1874CD"]_exit1[/color] [color="#8B3E2F"][b]=[/b][/color] [color="#FF0000"]1[/color][color="#8B3E2F"][b];[/b][/color][color="#8B3E2F"][b]}[/b][/color][color="#8B3E2F"][b];[/b][/color]
	[color="#8B3E2F"][b]}[/b][/color][color="#8B3E2F"][b];[/b][/color]
[color="#8B3E2F"][b]}[/b][/color] [color="#191970"][b]forEach[/b][/color] [color="#191970"][b]allUnits[/b][/color][color="#8B3E2F"][b];[/b][/color]
[color="#1874CD"]_exit1[/color] [color="#8B3E2F"][b]=[/b][/color][color="#8B3E2F"][b]=[/b][/color] [color="#FF0000"]1[/color][color="#8B3E2F"][b];[/b][/color]
[color="#8B3E2F"][b]}[/b][/color][color="#8B3E2F"][b];[/b][/color]
[/color]

Share this post


Link to post
Share on other sites

Make sure you only call that BIS_fnc_MP script from the server only (wrap it in a "if (isServer) then {};) statement, otherwise you will have every client send the same hint to every other client every 10 seconds. Depending on the player count I can imagine that this could cause lags.

Overall, consider if you have to run that whole loop on every client and server, or if it would be okay to just run on the server.

Use "count" instead of "forEach" (a little bit faster) if you don't need to access "_forEachIndex". You might also be able to improve performance of that loop by iterating through "playableUnits" instead of "allUnits". This should generally result in less units to check (in your case you only want players on your side).

Edit: You might be able to achieve the same functionality by setting a trigger.

if (isServer) then {
 _trg = createTrigger ["EmptyDetector", getPos _base_marker];
 _trg setTriggerArea [50,50,0,false];
 _trg setTriggerActivation ["WEST","PRESENT",false];
 _trg setTriggerStatements["this", "
   ['Aufgabe geschafft, begeben Sie sich in die Basis zurueck, damit eine neue Aufgabe erstellt wird.\nVorsicht, es können sich noch feindliche Einheiten in der Umgebung befinden.','hint',nil,true] call BIS_fnc_MP;
 ", ""];
};

Note: I am just interpreting the Biki here, no knowledge of triggers.

Edited by Gundy

Share this post


Link to post
Share on other sites

distanceSqr is also slightly faster than just distance

EDIT: And to support the point made above, the reason it's "lagging" is because every 10 seconds your filtering through every unit currently alive in the mission, so if you have say 150 units at a few miliseconds per loop iteration, those short times add up to a suspension, or "lag", that pretty much freezes the game until the loop has completed.

So, in short, the fewer units you have to loop through, the better.

EDIT2: And with some recommended optimizations, and a few other changes, try the following:

waitUntil
{
sleep 10;
 ["Aufgabe geschafft, begeben Sie sich in die Basis zurueck, damit eine neue Aufgabe erstellt wird.\nVorsicht, es können sich noch feindliche Einheiten in der Umgebung befinden.","hint",nil,true] call BIS_fnc_MP;

{((side _x) isEqualTo WEST) && {_x distanceSqr _base_marker < 50} } count playableUnits > 0;
};

Edited by JShock

Share this post


Link to post
Share on other sites

Hi John,

thanks for your advice. I will test that and come back with the results :-)

The script snippet runs inside a script that is run from the server with the if(!isServer) exit with {}; at the beginning. We were only 6 players on the server while experiencing those really bad lags.

Edited by CommanderX

Share this post


Link to post
Share on other sites

How about a client / server solution ?.

Have the server find the initial playable units for the side you want and send a PublicVariableClient to each of them then exit (server side finished). The Event Handler on the client side then spawns a script local to the client which checks the distance from the base and hints.

Should be much less network traffic and the checking is pushed to the clients, allowing the server to get on with its server stuff.

You could also make it so the hint says something along the lines of "Mission ended, new task available, check in with the commander.". Put an addaction on the commander AI that when activated sets a global va(scope: client) which the hint script checks every cycle and exits if found. That way you get one server based playableunits search, a few PVClient sends and no triggers or distance checks on the client end either. You could also build in a safeguard timeout if the player does not return to the commander for next instructions which will kill the hinting script after XX cycles.

Share this post


Link to post
Share on other sites

I solved this problem in another way. I created an sqf file back_home.sqf with the following in it.

if(!hasInterface) exitWith {};
private "_distance";

//Darauf warten, dass 
waitUntil {
hint "Aufgabe geschafft, begeben Sie sich in die Basis zurueck, damit eine neue Aufgabe erstellt wird.\n\nVorsicht, es koennen sich noch feindliche Einheiten in der Umgebung befinden";
sleep 10;
_distance = player distance base_marker;
if(_distance < 50) then {back_home = 1; publicVariable "back_home";};
back_home == 1;
};

and it in the original sqf ist this

back_home = 0;
publicVariable "back_home";
[[[],"tasks\back_home.sqf"],"BIS_fnc_execVM"] call BIS_fnc_MP;
waitUntil {
sleep 10;
back_home ==1;
};

So every client is running this script on it´s own and there were no lags.

Thanks to everyone helping me out and for getting ideas how to solve this problem.

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×