Jump to content
Sign in to follow this  
dreadedentity

Something I think is important to note when dealing with AI groups

Recommended Posts

While testing a script I'm writing, it has recently come to my attention that groups lead by AI and consisting only of AI will not be deleted when all units in it have been killed.

It seems that the return value of (count units CUSTOMGROUP) is dependent on the current group leader's knowledge of the alive status of his squad members, making it extremely tricky to test whether or not a group has been completely wiped out. Groups are supposed to be deleted when they become null (technically, all variables in the arma 3 engine), but it seems that if you kill all of them before the leader (or new leader) can determine whether his squad members are alive or not, it will never become null because there is no leader to decide if the last unit(s) has(have) died and kick him(them) out of the group. Therefore, no matter how you do it, if you kill the last member in a group, the "group" variabletype will not get deleted unless you script in your own "alive" check and remove the remaining unit yourself (or set the array to null)

To test this, create a new group (enemy or friendly, doesn't matter). In the leader's init line type

0 = [group this] execVM "test.sqf";

save this test mission.

create test.sqf and place it in the mission's folder. Put this code inside of it.

_group = _this select 0;

while {true} do
{
player sideChat format["Number of units in group alive: %1", count units _group];
sleep 1;
};

Now preview the mission and start killing the units one by one. Make sure you don't place too many because friendly units turn hostile if you kill like 5 of them. You'll notice that it doesn't do anything for a while, but then the counter slowly starts going down, but it will never get to 0 it will stay at 1. I assume the ai process for determining whether it's squadmates are alive is similar to the process players go through,

5, Report position!

like 10-15 seconds later

5, is down!

(unit 5 deleted from group)

Something to keep in mind if working on scripts that repeatably spawn a large number of ai groups.

Edited by DreadedEntity
forgot a semicolon in my code :(

Share this post


Link to post
Share on other sites

Your code doesn't check if they're alive, it only checks if they are part of the group. They can still be dead and part of the group.

Dead units will be deleted from the group slowly, so that is why you see your counter go down slowly.

Use something like this in the debug window to see how many are actually alive (I called the _group groupPoop in this code):

onEachFrame{player sideChat format["TIME: %1  Number of units in group alive: %2", time, {alive _x} count units groupPoop]};

Think of the group as knowledge of the leader. Only when the leader realises someone is dead, then they will be deleted from the group. "Oh no. 5 is down" etc.

EDIT:

As far as automatically deleting the group when all are dead, add a "killed" EH to each member as they spawn testing for alive members, like example above. If no-one is alive, then deleteGroup the group.

Something like this should work (untested):

_deadPerson = _this select 0;
_deadPersonGroup = group _deadPerson;

if ({alive _x} count units group _deadPersonGroup == 0) then {
deleteGroup _deadPersonGroup;
};

Edited by Das Attorney

Share this post


Link to post
Share on other sites
Only when the leader realises someone is dead, then they will be deleted from the group.

Exactly. I ran another few tests and it seems I was wrong about my initial assumption that the last units will never be deleted from the group. They are deleted but it is extremely slow, something like 20-30 seconds. That's much too slow, especially since they were removed one at a time, everyone might consider writing their own "alive" checks and removing dead units from groups.

Your code doesn't check if they're alive, it only checks if they are part of the group.

Purposefully done, I did this to highlight the fact that groups can be filled with dead units and still exist.

Share this post


Link to post
Share on other sites

Cool. I see why they haven't deleted empty groups automatically (nice to have use of the same group for all sorts of reasons), but yes, it's good to be aware they don't delete the empty groups for missions with lots of respawning.

Share this post


Link to post
Share on other sites

Yes, it's good to know: great I have read this topic.

It's been this way since forever, and you get accustomed to it, start to use it in your scripts, then boom, it gets changed. And this is not some minor feature.

One less loop for some, an own group recycler for another. (I have persistent groups in my misison: patrols which if wiped out will get reinforcements. It was easier to do this in the same FSM, using the same group id...)

Share this post


Link to post
Share on other sites
Yes, it's good to know: great I have read this topic.

It's been this way since forever, and you get accustomed to it, start to use it in your scripts, then boom, it gets changed. And this is not some minor feature.

One less loop for some, an own group recycler for another. (I have persistent groups in my misison: patrols which if wiped out will get reinforcements. It was easier to do this in the same FSM, using the same group id...)

Hm, copying or "storing" waypoints in a placeholder group won't be too easy now, if you're using waypoints that is.

Have you tried dynamically creating pseudo waypoints with the move command instead of using those cumbersome createwaypoint commands?

I think it's a bit easier to handle a "group move xyz" + "waituntil unitready leader group" loop instead of waypoints.

Haven't been using any regular waypoints since a long time, seems to be easier to break out of such a loop.

Share this post


Link to post
Share on other sites

onEachFrame{player sideChat format["TIME: %1  Number of units in group alive: %2", time, {alive _x} count units groupPoop]};

"In order to keep compatability between official and community content the functions BIS_fnc_addStackedEventHandler and BIS_fnc_removeStackedEventHandler should be used instead." (Source)

So, you better use those two functions rather than using "onEachFrame" (and others) directly.

Share this post


Link to post
Share on other sites

Yes I'm aware of them but don't really see the need when doing a one-liner in the debug console.

Share this post


Link to post
Share on other sites

What's gonna happen with this:

In my killed EH I am using the group of the unit for a side check, since the corpse itself is CIV. Now, for the last unit dead group will return null, so there is no way to check the last unit's side. Right?

Share this post


Link to post
Share on other sites
What's gonna happen with this:

In my killed EH I am using the group of the unit for a side check, since the corpse itself is CIV. Now, for the last unit dead group will return null, so there is no way to check the last unit's side. Right?

Not entirely true, like I said in the original post, the units get taken out of the group slowly, and then it turns null when there's no more units in it. However, this is extremely slow so you should add an event handler "killed" for each unit and use the code {[_this select 0] joinSilent grpNull;}

So what you can do with this is after that first code you can add more stuff to do when the unit gets killed, like increment score or something. Example:

_unit addEventHandler ["killed",
{
[_this select 0] joinSilent grpNull;
_this select 1 addScore 1; //adds 1 point to the unit that killed him
}];

Not sure it that helps you at all, but if you tell me more about what exactly you're trying to do, I might be able to come up with something.

Share this post


Link to post
Share on other sites

He's trying to check the side of the unit which was killed. Since dead units belong to side civ.

Not really sure how I feel about this change to be honest. It's one less loop for me, but also removes some scripting possibilities.

Share this post


Link to post
Share on other sites

So what about the copywaypoints command ?

Lets say i have a single unit (so basically a group) that i delete via deleteVehicle in his init line and use copywaypoints to copy his waypoints for a spawned group.

This works currently, but BIS changed it in the dev build so this would no longer work ?

Share this post


Link to post
Share on other sites
Actually it seems that they do delete empty groups in the latest dev branch. See here: http://feedback.arma3.com/view.php?id=20523

Yikes , not sure how i feel about this change. As others have mention is good that we no longer need to take care of managing empty groups BUT for those of us that use say for example Killed EH's to respawn units back into empty groups when they are dead we are going to lose all references once the last unit dies. TBO honest at first glance i would prefer it if BIS left it the way it was.

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  

×