Jump to content
  • 0

[Suggestion] New way to delete Zeds


Guest

Question

Hi,

 

apparently loops, that constantly get nearEntities (mostly used in Zed Shields) are FPS Killers.

I am planning on having Zed Shields around Plots, but i didn't want massive FPS drops, so i came up with this Idea:
Getting the Marker Positions via getMarkerPos and saving them in an array. In the Zombie Behavior then check the Positions array and delete the Agent, if the distance to the Marker Position is smaller then 100.

deleteInPositions = [];

deleteInPositions set [count deleteInPositions, (getMarkerPos "Tradercitystary")];
deleteInPositions set [count deleteInPositions, (getMarkerPos "AirVehicles")];
deleteInPositions set [count deleteInPositions, (getMarkerPos "BanditDen")];
deleteInPositions set [count deleteInPositions, (getMarkerPos "Klen")];
deleteInPositions set [count deleteInPositions, (getMarkerPos "BoatDealerEast")];
deleteInPositions set [count deleteInPositions, (getMarkerPos "TradercityBash")];
deleteInPositions set [count deleteInPositions, (getMarkerPos "HeroTrader")];

Now this is my suggestion (inside wild_spawnZombies.sqf) :

_meters = 0;
while {!isNull _agent} do {
    if (alive _agent) then {
        {
            _meters = _agent distance _x;
            if (_meters < 100) exitWith {
                deleteVehicle _agent;
            };
        } count deleteInPositions;
    };
};

I am wondering, if this is actually better or worse then nearEntities, as it kind of constantly loops.. ?

 

Note, that _x in this case is an array that contains PosX, PosY, PosZ, which it got from the getMarkerPos, but also this is not terrain relative, so i don't really know, if this works or not?

 

 

Link to comment
Share on other sites

11 answers to this question

Recommended Posts

  • 0

In my opinion server should always keep a track of existing zombies and cleanup appropriately. If it was me, I'd create an array of existing zombies and come back to check how they doing every 5 minutes or so... using the while loop and sleep command.

 

Your second snippet loops every frame, which is a bigger killer probably, and I can't do any judgement until I see what or who defines and finds _agent (rest of the code). Add sleep command right before loop ends and it should be safe enough to use at its current state.

 

Also, here's a little trick to avoid copy/pasta, kinda easier on performance - less lines:

{
	deleteInPositions set [count deleteInPositions, (getMarkerPos _x)];
}count ["Tradercitystary","AirVehicles","BanditDen","Klen","BoatDealerEast","TradercityBash","HeroTrader"];

Link to comment
Share on other sites

  • 0

Thank a lot.

This is inside "wild_spawnZombies.sqf", which has to be overwritten first.

_agent is:

_agent = createAgent [_type, _position, [], _radius, _method];

I believe, that this loop is "attached" to each Zombie individually.

Link to comment
Share on other sites

  • 0

ok so instead of attaching loop to every zed out there, we could just fill the array of existing alive shits and let server kill them when they exit the range of the marker.

 

i've cooked up simple function for the job, use it when both zed is spawned or when dies by natural causes... or just wanders off too far from marker, but that's detected by server every 5 mins or so, ofc.

/*
Function to manage Zed array
Usage:
["add",_agent] call fn_newZedThing;
["remove",_agent] call fn_newZedThing;
*/
fn_newZedThing = {
	_case = _this select 0;
	switch (_case) do {
		case "add":
		{
			myZeds set [count myZeds, (_this select 1);
		};
		case "remove":
		{
			myZeds - (_this select 1);
		};
	};
};
Link to comment
Share on other sites

  • 0

Why not set a variable zombieshield on plot poles and do this?

if (isNil "zombieshield") then {
    zombieshield = true;
};

while {!zombieshield} do {
            _entity_array = (getPos Plastic_Pole_EP1_DZ) nearEntities ["CAManBase",50];
            {
                if (_x isKindof "zZombie_Base") then {
                    deletevehicle _x;
                };
            } forEach _entity_array;
            uiSleep 4;
        };
Link to comment
Share on other sites

  • 0

 

ok so instead of attaching loop to every zed out there, we could just fill the array of existing alive shits and let server kill them when they exit the range of the marker.

 

i've cooked up simple function for the job, use it when both zed is spawned or when dies by natural causes... or just wanders off too far from marker, but that's detected by server every 5 mins or so, ofc.

 

 

Thanks for that. But then again, i want to delete the Zombie, if he is within the safe zone, so a loop is definitely necessary, as the Zombies can walk around.

 

 

 

 

Why not set a variable zombieshield on plot poles and do this?

 

Because "nearEntities" is what i am trying to prevent, as it's considered to be an FPS Killer. :)

Link to comment
Share on other sites

  • 0

When working on something like this I tend to step back and put down some design goals, needs, nice to haves and don't cares.

 

For this, off the top of my head, I would put down...

 

Goal: Increase FPS via better wild zombie safe zone protection method.

Needs: Remove zombies in / at the trader marker.

Nice to haves: Fairly quick removal.

Don't cares: Instant removal, any zombies not near the trader zones, anything at trader zones when players are not around.

 

So from that and our knowledge of Epoch / DayZ we know we do not need to check that often and we only need to check zombies in the vicinity of the trader cities as other zombies are unlikely to be able to move so fast. To this end I would setup a tracking zone (lets call it the amberZone) where we want to track the zombies. There would also be a redZone for zombie removal and a greenZone for "Don't care" level zombies. Large arrays can be slow so multiple arrays (one for each zone) would be prefered.

 

We can then build some rules / actions (not a fully comprehensive list);

  • We need to track amberZone zombies more often than greenZone zombies.
  • We need an amberZone marker (invisible) for each trader city.
  • We need to record wild zombie agents and their positions.

 

I would put all wild zombies spawned in to one of the 'Zone' arrays based on their location when spawned. Have a process running every 15 minutes checking position of zombies in greenZone and 2-5 minutes (fine tune based on zombie speed) checking position of zombies in amberZone.

 

The theory is that you are checking a smaller number of targetted objects (wild zombies) much more infrequently thus reducing server load.

 

Raymix has suggested the code to sort the zombies in to the zone arrays on completion.

 

Possible enhancements

 

As the checks are not so time sensitive, you could slow the scripts down and put a uisleep to put a pause of 0.001 or something between each zombie check. The script will take longer to complete but will not be fighting so hard for resources. Just need to make sure the script completed before another cycle is due to complete or build in a system to check to see if it is already running before kicking of another instance.

 

'On demand' checks based on clients positions. If the client is xx mtrs from the trader safezone then send a PVS to start the anit-zombie safezone check. Server receives the PVS and kicks off the safe zone anti zombie script and adds the client to a list of clients in the area of the safe zone. The server runs the script until the list of clients is empty and then stops. Clients are removed via the client sending a PVS when they leave the safezone. This means the scripts only run when there are clients in the arear near the safe zone (again fine tune the range). There is a little more PVS traffic but... with some throttling check to make sure no-one looks to abuse it and swamp the server buy finding the threshold and jumping in and out, it should be fine.

 

We will likely be implementing something like these 'On demand'' checks in Dominion as the 'always on' checks are really quite wasteful on CPU cycles.

Link to comment
Share on other sites

  • 0

Why not simply prevent zed spawn in the first place?

 

by using something like:

 

in building_spawnZombies.sqf and wild_spawnZombies.sqf

 

right under 

private [...];

add something like:

if ( /* Check Players Position to an Pole/Marker/etc */ ) exitWith {};

Maybe add some safe distance to it, to prevent any kind of false spawn in the safe area

Link to comment
Share on other sites

  • 0

Did anything come from this? Would be nice to make my current zed cleanup more efficient

 

Yes, but only very low difference for non HC clients.

 

I have added this line to both, wild_spawnZombies.sqf and zombie_generate.sqf:

 

                _meters = 0;
		while {!isNull _agent} do {
			if (alive _agent) then {
				{
					_meters = _agent distance _x;
					if (_meters < 150) exitWith {
						deleteVehicle _agent;
					};
				} count deleteInPositions;
			};
			sleep 10;
		};
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
  • Advertisement
  • Discord

×
×
  • Create New...