Jump to content
  • 0

How does the dead/destroyed despawn script work?


Flatlined

Question

I've been thinking. Yes that actually happens sometimes, nothing good have ever come out of it but I'm trying. :/

 

The despawn script for dead soldiers and destroyed vehicles - how does it work?

Is it on a timer that when triggered collects entities to be removed and does it immediately or is it something smarter?

 

The reason I ask is that it is annoying when I am running low on for example RPGs - kill an RPG-gunner 20 in front of me, and when trying to pick up their launcher just to have it despawn just as I try to.

Link to comment
Share on other sites

13 answers to this question

Recommended Posts

  • 0

I actually don't know if AW runs custom garbage collection on its servers, but except for removing markers and objects such as radio towers you usually don't need to make such a script as the engine does that for you.

When building a scenario in the editor you can go to Attributes > Performance and edit Dynamic Simulation and Garbage Collection settings for your mission. Have a look at that feature of the editor and you'll know how it works immediately.

Link to comment
Share on other sites

  • 0

So a more in-depth explanation:

We use our own cleanup script.  For the scripters out there it is located at: \scripts\misc\cleanup.sqf

The script is basically one giant while loop with as condition just true.  Meaning that the code in that script will keep executing till infinity and beyond.

First thing in the script is sleep 360 + (random 240);  This command will basically make the script do nothing for 360 seconds + a random number between 0 and 240. Translated this means that the script will run only every 6 to 10 minutes.
Then the scripts moves on to delete all dead bodies, all things you dropped on the ground, all craters, all empty groups, all ejection seats and canopies, ...
And lastly it checks if the fog is above a certain level and if it is reduce it by a certain amount.
After this it just goes back to those sleeps and in 6-10 minutes will do this all over again.
 

Link to comment
Share on other sites

  • 0

Great. Thanks for the explanation Stan.

 

That is how I expected it was working. I have different idea...

 

Why not have a script that runs every minute or so, its job is to go through a buffer/queue of commands. The commands may be a deletion, spawn entity, spawn a paradrop 12 minutes after an AO has started, etc. Anything really.

 

Adding commands to the buffer can be done as a reaction (event handler) when (for example) an enemy soldier dies or it can be a separate script/loop whose only job is to add commands to the buffer. There may be multiple sources (producers) of commands to the buffer; each with their own responsibility, etc.

  1. Each of those commands have a time-to-execute value.
  2. The script/loop checks each element if their time has been passed:
    • If time passed: Execute.
    • If time has not passed: It puts it back at the front of the buffer so that it remains till the next loop.
  3. Commands that should run on an interval could put themselves back into the buffer with a new value every time they have executed.
  4. Alternatively the buffer could be sorted on the time-value so the loop knows that it's no point in chugging through the rest of the buffer. This may or not be more performant depending on the size of the buffer and the insert-time of the buffer implementation.

This is usually how the main loop in games are (kinda/sometimes/theoretically) implemented although they tend to kick off commands to worker threads so that the main loop don't get clogged up.

Link to comment
Share on other sites

  • 0
10 minutes ago, Flatlined said:

Why not have a script that runs every minute or so

Problem with this is that the script is resource intensive. This means that the server performance dips ever so slightly every 6-10 minutes when it is ran as it is checking the ENTIRE map for things to delete etc. You put this on a one minute timer and the performance of the server will drop probably significantly since it is having to make multiple decisions at once, and the script doesnt always run instantly, it normally takes some time for the script to be fully executed therefore the downtime between each time it is run will maybe be less than one minute, leading to a decrease in average performance, which is something that is valued. Would also mean that if you drop something you have one minute to pick it up, and anything else it cleans up.

Link to comment
Share on other sites

  • 0

McKillen, yes. But the point was that the legwork of "finding things" already has been done by some other means; possibly as they happen with the use of event handler or what may be available in the arma engine.

 

Now, if the buffer becomes very big, or the commands takes very long time to run, this probably will result in reduced performance. Which is why I added one example of an optimisation: sorted buffer.

 

The point here is kind of trying to spread out the spike in resource-utilisation you mentioned over a longer period of time, in smaller batches that each takes less time to execute. This is something you want to do with applications that are run on a few/single thread since it blocks everything else while it's running. It also let's you execute things in more fine grained intervals (instead of 6-10 minutes).

 

Link to comment
Share on other sites

  • 0
1 hour ago, Flatlined said:

That is how I expected it was working. I have different idea...

If you can write the script and it's reasonable and doesn't impact server performance to an unreasonable amount we will happily implement it.  I don't currently have the time to write it myself.

Link to comment
Share on other sites

  • 0
8 hours ago, Flatlined said:

a buffer/queue of commands

 

What you're talking about is a whole mission daemon, which isn't how I&A works.  If your initial problem is that objects are being deleted just as you're trying to access them because the cleanup script activates, then propose a method which solves that problem.  For example, some exception handling in the cleanup script that skips the cleanup of units that are within X meters of a player, just in case that player wants to scavenge off the dead body.

 

Trying to make a megascript to handle all scheduling of events becomes problematic the larger the script becomes.  If the script can't be completed within 3ms it gets postponed to the next cycle, where it is pushed to the back to allow other scripts an opportunity to complete.  So if you have other things waiting for that script to complete, your mission will start to fall apart.  Simplicity is key.

 

Quote

Sadly adding event handlers also hits performance

 

Actually, I'm not sure if this is true, as the code in an event handler isn't called until the event occurs. I would go so far as to say it's probably a bit more efficient than running a loop to detect the same event because it's an internalized function: I have no data to present in either case.  Certainly an eventHandler is more efficient to work with because you can target the units specifically.

 

In Gauntlet, rather than use a cleanup code that runs on a loop, every spawned unit has a Killed event handler which will despawn the unit after around 180 seconds; also, on the completion of a mission, all dead units that haven't despawned are automatically cleaned up.

Link to comment
Share on other sites

  • 0
8 hours ago, Ryko said:

For example, some exception handling in the cleanup script that skips the cleanup of units that are within X meters of a player, just in case that player wants to scavenge off the dead body.

That's not what exception handling is, I assume you meant a regular if that checks for nearby players.

 

8 hours ago, Ryko said:

Trying to make a megascript to handle all scheduling of events becomes problematic the larger the script becomes.  If the script can't be completed within 3ms it gets postponed to the next cycle, where it is pushed to the back to allow other scripts an opportunity to complete.  So if you have other things waiting for that script to complete, your mission will start to fall apart.  Simplicity is key.

If you use scheduled execution yes, but not if you use unsheduled execution. Unscheduled execution executes code roughly 7x faster and doesn't care about the 3ms limit. The catch is you can't use infinite loops (since the code runs until it is done), sleep, uiSleep and waitUntil. You still shouldn't run a lot of expensive commands, but for what you'd need to do here, it wouldn't give any problems.

 

16 hours ago, McKillen said:

Sadly adding event handlers also hits performance

Event handlers are AFAIK very performant, but I've got no data to back it up. I tried testing it but I ran into this problem: since a few eventhandlers on units didn't change performance you'd need to place a large amount of AI, but at that point it's the AI ruining the performance, not the eventhandlers.

 

How I see it there's a few ways to optimize the script:

  • Remove the loop from the script, compile preprocessFileLineNumbers the script, put it in a CBA_fnc_addPerFrameHandler (CBA would need to run on the server, but not the client).
  • Go the eventhandler way and either do a []spawn{} or even better, use CBA_fnc_waitAndExecute.
  • Keep the code, compile preprocessFileLineNumbers the script and spawn it instead of execVM. preprocessFileLineNumbers buffers the script in memory and compile prepares it for execution beforehand instead of having it redone every iteration of the loop.
Link to comment
Share on other sites

  • 0
15 minutes ago, Jochem said:

Go the eventhandler way and either do a []spawn{} or even better, use CBA_fnc_waitAndExecute.

Problem is the cleanup script will clean anything that is dropped by players etc. This will mean that the eventhandlers will need to be added to every item that is dropped. Also used for the ejection seats which will then have the same issue. For units, yes i could see it working however there will need to be another script to add eventhandlers to each newly dropped items such as when an AI dies, and drops his weapon, or when a player drops his equipment on the ground then a way is needed to add the eventhandler to said item etc. 

Link to comment
Share on other sites

  • 0
1 hour ago, McKillen said:

Problem is the cleanup script will clean anything that is dropped by players etc. This will mean that the eventhandlers will need to be added to every item that is dropped. Also used for the ejection seats which will then have the same issue. For units, yes i could see it working however there will need to be another script to add eventhandlers to each newly dropped items such as when an AI dies, and drops his weapon, or when a player drops his equipment on the ground then a way is needed to add the eventhandler to said item etc.

Items dropped by dead units are still connected to said unit, so if you delete the unit it's weapon get's deleted. It even works when a player swapped it's own weapon with that of the unit.

 

For players dropping items you could use this EH: https://community.bistudio.com/wiki/Arma_3:_Event_Handlers#InventoryClosed

 

It's true you'll always need to combine it with a script that runs periodically, thing is that script doesn't impact performance as much as it otherwise would.

I personally use the first solution I suggested in my missions, runs every minute, never had any performance problems with it (and it even checks for nearby players).

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Forum Statistics

    11.1k
    Total Topics
    66.4k
    Total Posts
×
×
  • Create New...