Jump to content
Sign in to follow this  
fencr0c

waitUntil performance

Recommended Posts

Read on a couple of posts that the waitUntil command should not be used as it can degrade performance if there are lots of them.

I think I understand the reason, as waitUntil is outside of the scheduling environment (hope that's correct).

But what should I use instead, for example on a trigger?

_trgBld=createTrigger["EmptyDetector",_loc];
_trgBld setTriggerArea[1500,1500,0,false];
_trgBld setTriggerActivation["WEST","PRESENT",false];
waitUntil {triggerActivated _trgBld};

Should the waitUntil be replaced by a while with a sleep?

_trgBld=createTrigger["EmptyDetector",_loc];
_trgBld setTriggerArea[1500,1500,0,false];
_trgBld setTriggerActivation["WEST","PRESENT",false];
//waitUntil {triggerActivated _trgBld};
while {not triggerActivated _trgBld} do {sleep .3};

Share this post


Link to post
Share on other sites

If i remember correctly, this would be valid aswell:

waitUntil {
   triggerActivated _trgBld;
   sleep 0.3;
};

Share this post


Link to post
Share on other sites

waitUntil should not be outside the scheduling environment. Nothing is, except calling code from eventhandlers (config, scripted or init fields in editor) and triggers.

On a side note; FSMs are not part of the same scheduling environment, instead they are part of the AI scheduler and thus high AI load can schedule FSM execution.

waitUntil simply waits at least 1 frame each iteration. Depending on scripting load, it can skip a frame or more.

Depending on the complexity of the waitUntil statement/condition, it is generally recommended to add a sleep to it,

unless it would sit the design in the way.

---------- Post added at 11:32 ---------- Previous post was at 11:28 ----------

Myke;2032801']If i remember correctly' date=' this would be valid aswell:

waitUntil {
   triggerActivated _trgBld;
   sleep 0.3;
};

[/quote']

This is the correct form (the last statement is used as condition for the waitUntil):

waitUntil {
   sleep 0.3;
   triggerActivated _trgBld;
};

In some cases 'while' is more useful, as the above waitUntil will ALWAYS sleep 0.3 seconds, even if the condition is true before the first iteration.

You could workaround that by:

if !(triggerActivated _trgBld) then {
  waitUntil {
      sleep 0.3;
      triggerActivated _trgBld;
  };
};

But the while construct works around it by design:

while {!(triggerActivated _trgBld)} do {
   sleep 0.3;
};

Edited by Sickboy

Share this post


Link to post
Share on other sites

With simple conditions, I've never noticed any performance issues when using waitUntil sans sleep.

Share this post


Link to post
Share on other sites

I have a script with a few waituntils in it. I wrote the whole script from scratch, bare in mind im new at this.

The script basically "is" my whole mission. It does everything from spawning new objectives to deleting old ones.. to onscreen messages etc etc.

Iam calling the script like this in the init.sqf:

objectives = compile preprocessFileLineNumbers "objectives\objectives.sqf";

_objectives = [] call objectives;

Will a simple execvm "objectives\objectives.sqf"; work just aswell? Iam confused on when to use compile preprocessfilelinenumbers and when to use just execVM.Could someone besides the wiki explain how this is working?

Also, is there any need to use isserver commands ie, waituntil {!isserver bla bla bla} in my script and/or init? And could someone besides the wiki please explain isserver?

This map is made for multiplayer (12 people). However iam unsure if it will be MP JIP compatible as iam fairly new at scripting. I want to know what improvements i could make to ensure Mp compatability. i realize that JIP clients wont always be updated on objectives and markers without some extra MP scripting.

This is my init.sqf

execVM "briefing.sqf";
waituntil {!isnil "bis_fnc_init"};
objectives_3Dtext = compile preprocessFile "objectives\3dText.sqf";
begintext = ["Takistan", "2016", "Pestilence Rain"] spawn BIS_fnc_infoText;

private ["_objectives"];
objectives = compile preprocessFileLineNumbers "objectives\objectives.sqf";
_objectives = [] call objectives;

This is the script that "is" my mission:

private ["_marker1","_marker2","_obj1","_obj2","_objs","_marker3","_marker4","_obj3","_obj4"];

// creates 3d text on screen at initial objective location
firstobjtext = ["<t color = '#66FF00't/><t size='0.450'>Objective</t>",position obj1,40,0] spawn Objectives_3DText;

//initial objective - radarstation

waituntil {
sleep 0.3;
!alive obj1;};
deletemarker "r1";
"1" objStatus "done";
tskobj_1 settaskstate "succeeded";
obj_1 = true;
publicvariable "obj_1";
hint "radarstation eliminated";
[] execvm "objectives\briefing2.sqf";
objcompleted = ["Objective", "Completed"] spawn BIS_fnc_infoText;

//2nd group of objective(s).2 ammo caches that need to be destroyed

_marker1 = createMarker ["cache1",getmarkerpos "c1" ];
_marker1 setMarkerShape "ICON";
"cache1" setMarkerType "DESTROY";
"cache1" setmarkersize [1,1];
_obj1 = createVehicle ["TKVehicleBox_EP1",getMarkerPos "c1",[], 0, "NONE"];
_marker2 = createMarker ["cache2",getmarkerpos "c2" ];
_marker2 setMarkerShape "ICON";
"cache2" setMarkerType "DESTROY";
"cache2" setmarkersize [1,1];
_obj2 = createVehicle ["TKVehicleBox_EP1",getMarkerPos "c2",[], 0, "NONE"]; 
obj13DText = ["<t color = '#66FF00't/><t size='0.450'>Objective</t>",position _obj1,40,0] spawn Objectives_3DText; 
obj23DText = ["<t color = '#66FF00't/><t size='0.450'>Objective</t>",position _obj2,40,0] spawn Objectives_3DText; 

_objs = [_obj1, _obj2];

waituntil {
sleep 0.3;
{alive _x} count _objs == 1;};
hint"1/2 caches destroyed";
if (!alive _obj1) then {deletemarker "cache1"} else {deletemarker "cache2"};
waituntil {
sleep 0.3;
{alive _x} count _objs == 0;};
if (!alive _obj1) then {deletemarker "cache1"} else {deletemarker "cache2"};
if (!alive _obj2) then {deletemarker "cache2"} else {deletemarker "cache1"};
objcompleted1 = ["Objective", "Completed"] spawn BIS_fnc_infoText;
"2" objStatus "done";
tskobj_2 settaskstate "succeeded";
obj_2 = true;
publicvariable "obj_2";
hint"2/2 caches destroyed";
[] execvm "objectives\briefing3.sqf";


//3rd group of objective(s). 2 igla pods that need to die

_marker3 = createMarker ["aa1",getmarkerpos "a1" ];
_marker3 setMarkerShape "ICON";
"aa1" setMarkerType "DESTROY";
"aa1" setmarkersize [1,1];
_obj3 = createVehicle ["Igla_AA_pod_TK_EP1",getMarkerPos "a1",[], 0, "NONE"];
_marker4 = createMarker ["aa2",getmarkerpos "a2" ];
_marker4 setMarkerShape "ICON";
"aa2" setMarkerType "DESTROY";
"aa2" setmarkersize [1,1];
_obj4 = createVehicle ["Igla_AA_pod_TK_EP1",getMarkerPos "a2",[], 0, "NONE"]; 
obj33DText = ["<t color = '#66FF00't/><t size='0.450'>Objective</t>",position _obj3,40,0] spawn Objectives_3DText; 
obj43DText = ["<t color = '#66FF00't/><t size='0.450'>Objective</t>",position _obj4,40,0] spawn Objectives_3DText;

_objs1 = [_obj3, _obj4];

waituntil {
sleep 0.3;
{alive _x} count _objs1 == 1;};
hint "1/2 AA pods neutralized";
if (!alive _obj3) then {deletemarker "aa1"} else {deletemarker "aa2"};
waituntil {
sleep 0.3;
{alive _x} count _objs1 == 0;};
if (!alive _obj3) then {deletemarker "aa1"} else {deletemarker "aa2"};
if (!alive _obj4) then {deletemarker "aa2"} else {deletemarker "aa1"};
objcompleted3 = ["Mission", "Complete"] spawn BIS_fnc_infoText;
"3" objStatus "done";
tskobj_3 settaskstate "succeeded";
obj_3 = true;
publicvariable "obj_3";
hint"2/2 AA pods neutralized";
sleep 2;

exit

Is it ok to have that many waituntils in one script?

And in what ways could this script be simplified?

Edited by Iceman77

Share this post


Link to post
Share on other sites

I don't think that script works at all mate. Does it? Maybe it does. Maybe you need to try Squint to help you sort out your code. You also need to format it here in the thread properly so it's easier to read.

For example...I just looked at that last waituntil... even when I try to format it properly there's just too much wrong. It does not make sense. There's half of a foreach... the waituntils aren't closed off... too much!

I looked at it again and it probably does work... but get rid of the "exit" at the end that's not needed.... and I still think you need to read the guides.

I think you probably don't have -showscripterrors in your shortcut...do you? If you don't you must have it to debug your scripts properly.

Also you can look in your .rpt file for errors.

Familiarize yourself with these:-

Armed Assault Editing Guide

Arma 2 Scripting Commands

Sorry mate...but if this works I'd be very surprised!

waituntil {
sleep 0.3;
{alive _x} count _objs1 == 1;};  //??? where's the rest of this foreach?
hint "1/2 AA pods neutralized";
if (!alive _obj3) then {deletemarker "aa1"} else {deletemarker "aa2"};
waituntil {sleep 0.3;{alive _x} count _objs1 == 0;};
	if (!alive _obj3) then {deletemarker "aa1"} else {deletemarker "aa2"};
	if (!alive _obj4) then {deletemarker "aa2"} else {deletemarker "aa1"};
	objcompleted3 = ["Mission", "Complete"] spawn BIS_fnc_infoText;
	"3" objStatus "done";
	tskobj_3 settaskstate "succeeded";
	obj_3 = true;
	publicvariable "obj_3";
	hint"2/2 AA pods neutralized";
	sleep 2;
exit   // you don't need this

Edited by twirly
Clarity

Share this post


Link to post
Share on other sites
I don't think that script works at all mate. Does it? Maybe it does. Maybe you need to try Squint to help you sort out your code. You also need to format it here in the thread properly so it's easier to read.

For example...I just looked at that last waituntil... even when I try to format it properly there's just too much wrong. It does not make sense. There's half of a foreach... the waituntils aren't closed off... too much!

I looked at it again and it probably does work... but get rid of the "exit" at the end that's not needed.... and I still think you need to read the guides.

I think you probably don't have -showscripterrors in your shortcut...do you? If you don't you must have it to debug your scripts properly.

Also you can look in your .rpt file for errors.

Familiarize yourself with these:-

Armed Assault Editing Guide

Arma 2 Scripting Commands

Sorry mate...but if this works I'd be very surprised!

waituntil {
sleep 0.3;
{alive _x} count _objs1 == 1;};  //??? where's the rest of this foreach?
hint "1/2 AA pods neutralized";
if (!alive _obj3) then {deletemarker "aa1"} else {deletemarker "aa2"};
waituntil {sleep 0.3;{alive _x} count _objs1 == 0;};
	if (!alive _obj3) then {deletemarker "aa1"} else {deletemarker "aa2"};
	if (!alive _obj4) then {deletemarker "aa2"} else {deletemarker "aa1"};
	objcompleted3 = ["Mission", "Complete"] spawn BIS_fnc_infoText;
	"3" objStatus "done";
	tskobj_3 settaskstate "succeeded";
	obj_3 = true;
	publicvariable "obj_3";
	hint"2/2 AA pods neutralized";
	sleep 2;
exit   // you don't need this

so far everything is functional and is working as intended when i play the mission through the editor (preview). Iam new at scripting but ive made alot of missions over the years using triggers combined with simple commands. So iam pretty compotent with the editor itself.

iam mainly worried about mp compatability and was wondering how multiple waituntils effect performance or mp compatability.

my code looks drastically sloppy haha, but it is working as intended so far.

i did undo my terrible attempt at nesting the waituntils, like it was originally before i posted the code.also i only recently added the sleep commands with the waituntils. i ran through the mission after i put the sleep commands like they are now and it works fine so far. mabey i put the sleep commands in wrongly?

private ["_marker1","_marker2","_obj1","_obj2","_objs","_marker3","_marker4","_obj3","_obj4"];

// creates 3d text on screen at initial objective location
firstobjtext = ["<t color = '#66FF00't/><t size='0.450'>Objective</t>",position obj1,40,0] spawn Objectives_3DText;

//initial objective - radarstation

waituntil {sleep 0.3;!alive obj1;};
deletemarker "r1";
"1" objStatus "done";
tskobj_1 settaskstate "succeeded";
obj_1 = true;
publicvariable "obj_1";
hint "radarstation eliminated";
[] execvm "objectives\briefing2.sqf";
objcompleted = ["Objective", "Completed"] spawn BIS_fnc_infoText;

//2nd group of objective(s).2 ammo caches that need to be destroyed

_marker1 = createMarker ["cache1",getmarkerpos "c1" ];
_marker1 setMarkerShape "ICON";
"cache1" setMarkerType "DESTROY";
"cache1" setmarkersize [1,1];
_obj1 = createVehicle ["TKVehicleBox_EP1",getMarkerPos "c1",[], 0, "NONE"];
_marker2 = createMarker ["cache2",getmarkerpos "c2" ];
_marker2 setMarkerShape "ICON";
"cache2" setMarkerType "DESTROY";
"cache2" setmarkersize [1,1];
_obj2 = createVehicle ["TKVehicleBox_EP1",getMarkerPos "c2",[], 0, "NONE"]; 
obj13DText = ["<t color = '#66FF00't/><t size='0.450'>Objective</t>",position _obj1,40,0] spawn Objectives_3DText; 
obj23DText = ["<t color = '#66FF00't/><t size='0.450'>Objective</t>",position _obj2,40,0] spawn Objectives_3DText; 

_objs = [_obj1, _obj2];

waituntil {sleep 0.3;{alive _x} count _objs == 1;};
hint"1/2 caches destroyed";
if (!alive _obj1) then {deletemarker "cache1"} else {deletemarker "cache2"};
waituntil {sleep 0.3;{alive _x} count _objs == 0;};
if (!alive _obj1) then {deletemarker "cache1"} else {deletemarker "cache2"};
if (!alive _obj2) then {deletemarker "cache2"} else {deletemarker "cache1"};
objcompleted1 = ["Objective", "Completed"] spawn BIS_fnc_infoText;
"2" objStatus "done";
tskobj_2 settaskstate "succeeded";
obj_2 = true;
publicvariable "obj_2";
hint"2/2 caches destroyed";
[] execvm "objectives\briefing3.sqf";


//3rd group of objective(s). 2 igla pods that need to die

_marker3 = createMarker ["aa1",getmarkerpos "a1" ];
_marker3 setMarkerShape "ICON";
"aa1" setMarkerType "DESTROY";
"aa1" setmarkersize [1,1];
_obj3 = createVehicle ["Igla_AA_pod_TK_EP1",getMarkerPos "a1",[], 0, "NONE"];
_marker4 = createMarker ["aa2",getmarkerpos "a2" ];
_marker4 setMarkerShape "ICON";
"aa2" setMarkerType "DESTROY";
"aa2" setmarkersize [1,1];
_obj4 = createVehicle ["Igla_AA_pod_TK_EP1",getMarkerPos "a2",[], 0, "NONE"]; 
obj33DText = ["<t color = '#66FF00't/><t size='0.450'>Objective</t>",position _obj3,40,0] spawn Objectives_3DText; 
obj43DText = ["<t color = '#66FF00't/><t size='0.450'>Objective</t>",position _obj4,40,0] spawn Objectives_3DText;

_objs1 = [_obj3, _obj4];

waituntil {sleep 0.3;{alive _x} count _objs1 == 1;};
hint "1/2 AA pods neutralized";
if (!alive _obj3) then {deletemarker "aa1"} else {deletemarker "aa2"};
waituntil {sleep 0.3;{alive _x} count _objs1 == 0;};
if (!alive _obj3) then {deletemarker "aa1"} else {deletemarker "aa2"};
if (!alive _obj4) then {deletemarker "aa2"} else {deletemarker "aa1"};
objcompleted3 = ["Mission", "Complete"] spawn BIS_fnc_infoText;
"3" objStatus "done";
tskobj_3 settaskstate "succeeded";
obj_3 = true;
publicvariable "obj_3";
hint"2/2 AA pods neutralized";
sleep 2;

exit

(in my mind) this script is waiting until certain units or in some cases a # of units are dead and then it is telling me about it. ie, hints and texts displayed about the current objective status, updating the journal,spawning in new objectives etc.. Im sure its ugly and inefficient.And iam sure the performance of the script is low. Any tips on how to optimize this would be appreciated.

ps, i do use the -showscripterrors command

here's my barebones mission, ie singlemouseclick + no enemys.. only the objectives / briefing exist

http://www.gamefront.com/files/20866311/co_12_Pestilence_rain.Takistan.rar

Edited by Iceman77

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  

×