Jump to content
reymasofashborne@gmail.com

How to get EnableSimulation repeatedly true/false on AI throughout mission

Recommended Posts

Hey all,

 

I am very new to Arma editing, but having a ton of fun.

 

Currently I am making a rather unit-intensive mission (approx. 400 units in a 900x900 area) and am trying to use "enableSimulation" on a series of sector triggers to curtail the load on the server/client.

 

The intent is as follows:

 

1. 900x900m AO divided into 9 overlapping sectors, approximately 350x350m.

 

2. enableSimulation for all AI in those sectors disabled at the start of the mission.

 

3. When player or player's group member enters one of these sectors, "enableSimulation" switches to true for all AI in that sector (or sectors if they overlap) they're in.

 

4. When player or group memeber leaves sector "enableSimulation" switches back to false, thusly reducing the amount of AI being processed by 1/9th.

 

5. AI retains all INIT params and waypoints between deactivation.

 

So I have the 9 triggers for the sectors set up. They overlap to avoid any weirdness, which is a bit more intensive when player is in an overlap zone but still better than nothing.

 

Player and their group is grouped to triggers so no other blufor activate them (ie, AI CAS flying over or the BluFor hostages that start somewhere in the AO), like so:

 

eM6jYwd.png

 

(shown is example, want to avoid spoilers for the actual mission as I intend it to be my first release)

 

Here is how each trigger param works (just east shown atm):

 

uSVnCuC.jpg

 

So this is not working at all. The hint "NW Opfor DeActive" kicks off at the beginning of the mission so the trigger does fire BUT, I can see the AI is still doing stuff within the trigger area.

 

I tried putting a big 1000x1000 trigger over the whole area to turn off Simulation at the beginning (No Dea.) but it seemed to override the smaller ones and go forever, instead of just "ONCE" - even though it was a ONCE trigger the smaller repeatedly triggers would never turn on Simulation again.

 

Also a weird bug. One of my groups in my mission is set to guard an Opfor technical. With no trigger over them they do just this but with the above trigger over them they beeline to the nearest Blufor unit and try to attack, even though all their INITs have "Target" AI disabled. That being said the dudes on the rooftops near them don't have that issue, they stay put (probably because they have "forceSpeed 0" in their inits).

 

So when you disable simulation during a mission does it get rid of any waypoints for those units or re-enable all their AI parameters despite their inits saying otherwise?

 

Any help getting this to work properly would be amazing, even if it's a script I have to run. I am no coder though, can't script myself, but I can fill in and replace stuff pretty darn well, haha!

 

Thanks in advance to anyone looking to help with this. I plan to make several versions of the mission with differing AI numbers for those with slower systems but having this optimization feature working across the board would just be amazing.

 

PS: Would there perhaps be a way to incorporate hideObject as well or is that going to give me the same problems?

Share this post


Link to post
Share on other sites

I'm pretty sure that using thisList with a trigger will store the units that activate the trigger into thisList. So if a trigger is activated by "Any group member", thisList will only contain the group member/s that activated the trigger (and return no OpFor units).

 

You might be better off saving each of the area's enemies into their own arrays and then using enableSimulation on the required array, rather than relying on thisList.

Share this post


Link to post
Share on other sites

400 units within one square km? Ouch.

 

Why not ditch all triggers and do a simple distance check to enable/disable the simulation,

then for GPU stress (400 units are certainly pushing any GPU below a 780 or similar) you could add a line of sight check for the hideobject command if you really want to use such a dense AI count.

 

This is what I came up with, and it's similar to what I use for my civilian scripts:

AIcontrol = [] spawn {

_checkDistanceSqr = (350 * 350);

while {alive player} do {

{
_dist = getposatl player distanceSqr getposatl _x;
if (_dist < _checkDistanceSqr) then {_x enablesimulation true;_x hideobject false;_x enableAI "FSM";};
if (_dist >= _checkDistanceSqr) then {_x enablesimulation false;_x hideobject true;_x disableAI "FSM";}
} foreach (allunits - allplayers);

sleep 0.1};
};

Tested this with 400 blufor units (40 * RifleSquad + 2 Riflemen) on the fields 1.4km southwest of Athira.

 

MYYkivC.jpg

 

Without the script I got 34 fps on ultra and 2500m viewdistance, 2000m object distance.

With the script I gained around 10 fps, between 43-45 fps.

The disableRemoteSensors command on the devBranch will obviously add some performance on top of that.

 

Cheers

  • Like 2

Share this post


Link to post
Share on other sites

This is precisely that what ALiVE does.

You can have proximately 2400 units on map.

Use it or look for any caching script.

Share this post


Link to post
Share on other sites

This is precisely that what ALiVE does.

Use it or look for any caching script.

 

Indeed. I would use ALiVE but it's not compatible with the map I'm working with. Also it tends to give me the access violation error after about 20 mins.

 

 

/snip

 

Thanks Grumpy this is a great approach, Will give it a shot when I get a chance and let you know how it goes.

 

Before I do, however, I gotta ask the noob question: where does all that code go? In the init.sqf? Or somewhere else? Make a new sqf, run through execvm? (NM I R TEH DUMB)

 

And yeah it's a lot of peoples, but it's dense urban environment so sightlines are very limited and something like this is probably exactly what's needed. Many of the AI have a lot of their AI turned off, ie: move, target, suppression etc, since they're on rooftops, and that seems to be helping for sure.

 

EDIT: This worked like a charm! I recommend this for ANYONE with lots of AI in their mission, it doubled my fps. Grumpy Old Man you are a life saver! Now I'm just testing to make sure all the AI's inits and waypoints are in tact. Will report.

 

EDIT2: Inits and Waypoints are working beautifully but I ran into one issue. Is there a way to stop this from happening to AI squadmates and support units? Make an exception somehow? Could I do like "allplayable" (Is that even a thing?) instead of "players" or limit it to certain sides? The supports will not react when outside the 350x350 radius.

 

EDIT3: Also there are ghost vehicles, aka vehicles and statics that are driven and gunned by invisible enemies, (the guns fire, the vehicles move, and the invisible drivers and gunners can be killed but they never show up even after getting in their gun position so as to move the body to the floor (I CANNOT loot them), even when up close. This happens whether I do moveIn or they just start in the vehicle). Any way to prevent? Update: found one vehicle with visible guys in it. Hrm...

 

NEW QUESTION: Is there a way to set up a deact. for an execvm? Like let's say I want enemy spawning around the player but only when the player is in a certain trigger or marker area. What is the opposite of "nul = execvm"?

 

NEW QUESTION #2: Any way to turn down AI accuracy but leave their acquisition rate up? So they see you easily but have a hard time hitting you?

 

Thank you again for all the help, this has been great!

  • Like 1

Share this post


Link to post
Share on other sites

You can easily exclude any amount of units/vehicles from this script.

Just add them to an array and subtract the array behind the foreach command.

Could look like this:

AIcontrol = [] spawn {

_excludedVehicles = [ChopperOne, ChopperTwo, ChopperThree, ArtilleryFromHell, SupportOne, SupportTwo];
_checkDistanceSqr = (350 * 350);
_toCheck = (allunits - allplayers - _excludedVehicles);
while {alive player} do {

{
_dist = getposatl player distanceSqr getposatl _x;
if (_dist < _checkDistanceSqr) then {_x enablesimulation true;_x hideobject false;_x enableAI "FSM";};
if (_dist >= _checkDistanceSqr) then {_x enablesimulation false;_x hideobject true;_x disableAI "FSM";}
} foreach _toCheck;

sleep 0.1};
};

You can terminate a running script or function.

Edit: Moved the final array of units to check in front of the loop for performance reasons.

terminate AIcontrol;

will terminate the script, downside is that units with simulation disabled will be stuck in that state, unless you manually enable it via another function.

 

 

As for the accuracy I'm using this setting to simulate untrained/poorly trained troops, working good so far:

_unit setSkill 0.3;
_unit setUnitAbility 0.3;
_unit setSkill ["aimingAccuracy", 0.1];
_unit setSkill ["aimingShake", 0.6];
_unit setSkill ["aimingSpeed", 0.1];
_unit setSkill ["spotDistance", 0.5];
_unit setSkill ["spotTime", 0.7];
_unit setSkill ["commanding", 1];
_unit setSkill ["courage", 1];
_unit setSkill ["general", 1];
_unit setSkill ["reloadSpeed", 0.1];

Cheers

  • Like 2

Share this post


Link to post
Share on other sites
/snip

 

Fantastic stuff!

 

The termination was for a random spawn script I have going, not for the optimization, but understood, just so the random spawning doesn't keep happening if players go back to base. Could the unit just be "this" in the unit init? Or could I add this to an overall trigger with the same "if side east then" param? I'll try that and see. I'm also assuming the higher the value the more skill they have, so this guys spots you pretty quick and doesn't shake too much but is inaccurate as all hell and doesn't aim very fast. I think I may switch that up so that he aims fast, but shakes a lot. So:

 

_unit setSkill ["aimingShake", 0.1];

_unit setSkill ["aimingSpeed", 0.6];

 

Thanks again for all the help man, should have something playable today or tomorrow thanks to you!

 

EDIT: So now the support is recognized as being there, I can call it in, but it is not firing. When I get back in range it starts firing.

AIcontrol = [] spawn {

_excludedVehicles = [Havoc1, Havoc2, Mayhem1, Mayhem2, Whiplash1, Whiplash2, Whiplash3, Mustang1, Mustang2, Humpback, Halbeard1, Halbeard2, Snakebite1, Snakebite2, Snakebite3];
_checkDistanceSqr = (300 * 300);
_toCheck = (allunits - allplayers - _excludedVehicles);
while {alive player} do {

{
_dist = getposatl player distanceSqr getposatl _x;
if (_dist < _checkDistanceSqr) then {_x enablesimulation true;_x hideobject false;_x enableAI "FSM";};
if (_dist >= _checkDistanceSqr) then {_x enablesimulation false;_x hideobject true;_x disableAI "FSM";}
} foreach _toCheck;

sleep 0.1};
};

Artillery are designated Halbeard1+2 and Snakebite1-3 for mortars ( the rest are various CAS and transport choppers that can't be called until you take out enemy artillery pieces)

 

Maybe it'd be easier to just do the exception for all Blufor? There's not that many of them on the map.

 

EDIT2: Actually yes this will need to be the case (side exceptions rather than specific vehicles) because your AI teammates also deactivate if you get too far away which causes a lot of issues.

 

Could I just do _excludedSide = West instead of excludedVehicles?

 

NEVERMIND! Got it working WOO

 

So I take it I can just add my squad members to that array as well and it'll exclude them?

 

It seems that if you switch unit that breaks the script completely, the script doesn't account for the player being a new unit. Any way to get it to do that?

Share this post


Link to post
Share on other sites

You could add a waituntil line just behind the beginning of the loop, you need to play a bit to get the right condition though, maybe hasInterface will do it, or something like that:

waituntil {player == player};

No idea how to prevent unit switching from breaking a script, maybe setting the scripts condition from alive player to true will do the trick.

 

Cheers

Share this post


Link to post
Share on other sites

You could add a waituntil line just behind the beginning of the loop, you need to play a bit to get the right condition though, maybe hasInterface will do it, or something like that:

waituntil {player == player};

No idea how to prevent unit switching from breaking a script, maybe setting the scripts condition from alive player to true will do the trick.

 

Cheers

 

Eh, it's not too big of a deal. Unit switching shouldn't be necessary. I'll play with it and see but I'm pretty happy with how this is all shaping up.

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

×