Jump to content
Sign in to follow this  
Kydoimos

Low FPS and Mission Editing

Recommended Posts

Hi all - don't suppose anyone can tell me what the big no-no's are for mission editing, in relation to FPS. I've got a low FPS rate - could it be because of too many static objects? Too many units? Or too many User Textures? Thanks in advance!

Share this post


Link to post
Share on other sites

Too many objects/units can be an issue, I personally don't know the exact tipping point, but it is possible (especially a lot of units with waypoints), a while back (I'm talking 7 months ago) I made a mission with almost 200 enemy AI and probably half had waypoints, FPS was more like frames per hour, but with all the updates that have come out I have seen quite a bit of improvement performance side when I push the issue of number of AI on the map from the editor. For textures and anything similar to that, it is possible that you don't have proper syntax on setting those textures so they would be loading clientside instead of serverside (unless your mission is singleplayer, then it's all "clientside" persay) and if it's multiplayer those textures would multiply with each connected client (I learned this the hard way....). Another check is to make sure all your scripts (if your running any) are all working in full capacity, none are getting stuck in a loop or something of the sort.

Also try putting a client check in your init.sqf, helps diminish the object/texture multiplication problem (make sure it's put above everything else in your init.sqf):

if (!isServer && isNull player) then {isJIP=true;} else {isJIP=false;};

if (!isDedicated) then
{
waitUntil {!isNull player && isPlayer player};
sidePlayer = side player;
};

That's all I can think of at the moment, hope some of it helps.

Edited by JShock

Share this post


Link to post
Share on other sites

Use caching scripts if possible to hide units until your in the zones. EOS is great but its a random unit script. For placing units there are some out there but Murks script seems to the best although out dated.

Share this post


Link to post
Share on other sites

Thanks guys! Helpful suggestions! Cheers!

Share this post


Link to post
Share on other sites

I believe there is Simulation Manger Module as well, that will pause things outside your range that you can set in the module options.

Share this post


Link to post
Share on other sites

Interesting, Goblin - thanks! Only trouble is, the area I'm creating is quite small and choc-a-bloc with objects - I can see why BIS didn't fill the houses with furniture! :-) All the same, dead handy module that!

Share this post


Link to post
Share on other sites
Hi all - don't suppose anyone can tell me what the big no-no's are for mission editing, in relation to FPS. I've got a low FPS rate - could it be because of too many static objects? Too many units? Or too many User Textures? Thanks in advance!

AI is the elephant in the room, and server CPU is the resultant bottleneck. Lower server FPS will throttle player FPS, and AI drag down server FPS.

Less AI = higher FPS.

I've seen some missions with objects spammed everywhere, inefficient and numerous loops in the code, but the player FPS is fine because no/very few AI units/vehicles.

If your goal is FPS and all other considerations secondary, then I have two suggestions:

1. Few(er) to no AI.

2. Use Stratis.

Another small note:

Speaking of Altis, there are 450+ simulated mission objects that cannot be removed/altered. These are the airbase lights. Set the time to evening/night and the airbase will be colorful. All those little lights are simulated objects, I wish I could remove them when not necessary/wanted.

Stratis has about 260 of them.

Type:

_c = count allMissionObjects ""; hint format ["Count: %1 mission objects",_c];

into empty Altis editor debug console, and you will have quite a high count due to all those airbase lights. In my opinion there should be zero mission objects in empty editor.

Edited by MDCCLXXVI

Share this post


Link to post
Share on other sites

AI is the bottleneck in this game, in every sense. I'm deeply frustrated with these bots, despite all efforts from the community to improve them. It's the only aspect in which I saw no significant evolution for the past 18 months.

But you can alleviate some of the problems. If your mission is at least a little bit complex, you can't spawn all units from the start. You may also need a unit caching script. And it's preferable, for example, to have one group with 10 units rather than 10 groups with one unit each.

Share this post


Link to post
Share on other sites

@MDCCLXXVI - hmm, interesting - I wonder if the simulation module that Goblin mentioned would resolve the issue? I'll certainly try to cut back on AI - and hide / enableSimulation false what I don't need!

Share this post


Link to post
Share on other sites

I found in one of my missions that putting down loads of AI had very little effect on FPS, but giving them all waypoints dropped FPS very quickly by about 10 FPS.

EDIT: Like your mission, the whole battle takes place within 700m so caching isn't an option. I have tried removing same AI and deleting waypoints to get the FPS back up. I wondered if it was to do with the current AI pathfinding issues.

Edited by alky_lee

Share this post


Link to post
Share on other sites
if (!isServer && isNull player) then {isJIP=true;} else {isJIP=false;};

if (!isDedicated) then
{
waitUntil {!isNull player && isPlayer player};
sidePlayer = side player;
};

is sidePlayer an ArmA3 command?

Share this post


Link to post
Share on other sites
is sidePlayer an ArmA3 command?

sidePlayer as you see it is not a command, that is the "side player" being assigned to the global variable "sidePlayer", making sure that the server understands that the player is now "loaded" and assigned a side (being BLUFOR, OPFOR, etc.), or at least that's my version of the breakdown of this code.

---------- Post added at 01:35 ---------- Previous post was at 01:30 ----------

I found in one of my missions that putting down loads of AI had very little effect on FPS, but giving them all waypoints dropped FPS very quickly by about 10 FPS.

EDIT: Like your mission, the whole battle takes place within 700m so caching isn't an option. I have tried removing same AI and deleting waypoints to get the FPS back up. I wondered if it was to do with the current AI pathfinding issues.

I completely agree alky, it only seems to have huge issues when there are a number of AI with waypoints, I think it may be due to BI trying to have the AI do "too much" to add to the "realism" factor as they see it, in terms of always checking for position in relation to the next, what happens if their shot near, what happens if one of my fellow AI gets shot, so on and so on. And just as MDCCLXXVI said as well:

AI is the elephant in the room, and server CPU is the resultant bottleneck. Lower server FPS will throttle player FPS, and AI drag down server FPS.

But anyhow, to get back on topic in helping our thread author out....before we get this shutdown.....and before we get into bashing Arma optimization too much....

Edited by JShock

Share this post


Link to post
Share on other sites

I've noticed, in ArmA 2 at least, that there are errors that don't pop up even when you have the ShowErrors param on. (probably due to locality). For months I had been running with a mod that would literally spam my arma.rpt logfile and I did not know that that had impact on my FPS either.

After a quick check, I noticed the errors, edited the mod to resolve them and my FPS instantly became stable and a lot higher (5-10+ FPS)

Now ofcourse I am talking about an addon (it was Loki's Lost Key fyi), but errors inside mission created loops ( while, for, foreach) can effect FPS somewhat too.

Just a small addition :P

Kind regards,

Sanchez

Share this post


Link to post
Share on other sites

If you're using a lot of "addAction" commands with long and complex condition statements, this may also be a reason for low fps as they are checked on each frame. If you use addAction to interact with static objects, add the action to the object instead of the player.

Also, instead of making complicated while loops checking the distance to other objects or location in order to trigger some code, use triggers as they do the same job a lot more efficient.

Share this post


Link to post
Share on other sites

Also, instead of making complicated while loops checking the distance to other objects or location in order to trigger some code, use triggers as they do the same job a lot more efficient.

Well...that last one it depends on what you're checking. I remember that triggers are checked like every 0.5313310 (whatever) seconds, and in case you have something that doesn't require that quick of checking a while loop with a sleep of > 1 second would be more efficient.

Kind regards,

Sanchez

Share this post


Link to post
Share on other sites

Another small note:

Speaking of Altis, there are 450+ simulated mission objects that cannot be removed/altered. These are the airbase lights. Set the time to evening/night and the airbase will be colorful. All those little lights are simulated objects, I wish I could remove them when not necessary/wanted.

.

It's not just the lights. If you stand in an empty part of Stratis and count the number of objects within a given range, you'll find that it's roughly a tenth of what you get if you do the same on Altis. Conclusion? Altis is overpopulated with crap like feathers, footsteps, insects, pollen etc etc.

Share this post


Link to post
Share on other sites

@alky_lee - thanks for the response, yes, could be to do with that - at the moment it looks like I've just got too much of everything! :)

---------- Post added at 17:30 ---------- Previous post was at 17:27 ----------

@All - thanks everyone for your suggestions, there's a lot to consider! I'm sure I'll get there! Even if it requires a process of elimination, where I delete things and check for higher FPS,

---------- Post added at 17:54 ---------- Previous post was at 17:30 ----------

Ha ha! Right - here's my problem - I have a trigger with this as a condition:

{["mine_", str(_x)] call BIS_fnc_inString} count (thisTrigger nearObjects 60) > 1  

It's causing a massive FPS drop! Where am I going wrong? I basically need the trigger to fire if a player places a mine in the given area...

Share this post


Link to post
Share on other sites

I'd try a fired eventhandler in combination with a distance check. Something like this (untested):

player addEventhandler ["Fired", {
if (((_this select 5) in [MineType1, MineType2,...]) && {[MyTrigger, (_this select 6)] call BIS_fnc_inTrigger}) then {
	// Code
};
}];

Share this post


Link to post
Share on other sites
I'd try a fired eventhandler in combination with a distance check. Something like this (untested):

player addEventhandler ["Fired", {
if (((_this select 5) in [MineType1, MineType2,...]) && {[MyTrigger, (_this select 6)] call BIS_fnc_inTrigger}) then {
// Code
};
}];

That would be my suggestion. Triggers can be handy but smart use of EH instead can save you a load of fps if you're consistent. Triggers will eat fps when you get many of them combined with a lot of objects.

Heck, as odd as it is, it's preferable (like mentioned earlier) to have a while loop with a longer sleep than a trigger, and while loops are to be avoided for optimal performance. Unless I absolutely need to know something asap I don't even use triggers any more. EHs cover about 95% of things I typically need to know (dead/shot/hurt/healed/assembled/destroyed/in vehicle/out of vehicle/whatever).

Hardly anyone notices a few seconds pause anyway. Having instant confirmation (*beep* you manshot hvt! *boop*) on my actions from a notification a millisecond after the fact always felt gamey to me anyway.

Share this post


Link to post
Share on other sites

Wouldn't a "Fired" eventhandler only get triggered once mine is detonated?

If that's the case, it will not detect when it is planted and execute your code at that point.

Kydoimos not sure what you are trying to do with the trigger exactly but maybe this could give you a low impact alternative idea.

Detects planted mines in 5 second interval within 65 meter radius of objective_pos_logic.

objective_pos_logic could be an invisible object like small grass cutter "Land_ClutterCutter_small_F"

_checkmines = true;
_minefielrad = 65;

while {_checkmines} do
{
_nearestMines = (getPosATL objective_pos_logic) nearObjects ["TimeBombCore",_minefielrad];//"minebase"

{
	if (!mineActive _x) then
	{
		_nearestMines = _nearestMines - [_x];
	};
} foreach _nearestMines;

if (count _nearestMines > 0) then
{
	// do some code
	// if repeat not needed then _checkmines = false;
};
sleep 5;
};

I use the following script for planted mine/explosive removal at base.

if (!isServer) exitwith {};
waitUntil {time > 62};

private ["_totalItems","_cleanup_mkrs","_nearestMines","_nearestMinebase"];

_totalItems = [];
_cleanup_mkrs ["Respawn_West","Helicopters","Mechanized","VehicleMaintenance","HelicopterRepair","AircraftMaintenance","Halo"];

for [{_loop=0}, {_loop<1}, {_loop=_loop}] do
{
if (!(_totalItems isEqualTo [])) then {_totalItems set [];};
{
	_nearestMines = getmarkerPos _x nearObjects ["TimeBombCore",50];
	{
		if (mineActive _x) then
		{
			_totalItems set [count _totalItems,_x]
		};
	} foreach _nearestMines;

	_nearestMinebase = getmarkerPos _x nearObjects ["minebase",50];
	{
		_totalItems set [count _totalItems,_x]
	} foreach _nearestMinebase;

	{deleteVehicle _x; sleep 0.1;} foreach _totalItems;
} foreach _cleanup_mkrs;
sleep 120;
};

This second script does have a foreach in another foreach but my observations show negligable performance impact

Share this post


Link to post
Share on other sites
Wouldn't a "Fired" eventhandler only get triggered once mine is detonated?

Nope, that's the problem with throwabels/placeables; EH fires when it's put down. Imagine you want to detect when a player detonates a bomb he placed before - that requires some scripting / explosion detection...

Anyway, take an explosive specialist, add this to his init and see for yourself:

this addEventhandler ["Fired", {hint str(_this);}];

Share this post


Link to post
Share on other sites

Idea: you can make an array of elements where you stored any fired object if _this select whatever == "PUT" then arrayofmines = arrayofmines + [_this select whateverelse]; and then make a loop check if those are still alive or not exploded and a check of their position...

Share this post


Link to post
Share on other sites

There's also an explosion detector script by mrflay. It's reliable and does a good job:

/* FLAY_fnc_ExplosionDetector
* 
* Description:
*      This script is used to detect when a satchel or demolition charge detonates.
*
* Usage:
*      [<detector>, (<radius>), (<callback>)] call FLAY_fnc_ExplosionDetector
*
* Params:
*       <detector>: OBJECT - Any object (used to determine the detection radius). 
*         <radius>: NUMBER - Maximum distance from the detector an explosion will be detected.
*         <callback>: CODE   - Function that should be called when explosion is detected.
*
* Notes:
*      The callback is passed two arguments when an explosion is detected:
*      
*        <detector>: OBJECT - The detector object. 
*       <explosive>: OBJECT - The explosive object that detonated.
*/

private ["_detector", "_radius", "_callback"];

_detector = _this select 0;
_radius = [_this,1,50,[0]] call BIS_fnc_param;
_callback = [_this,2,{},[{}]] call BIS_fnc_param;

_detector setVariable ["flay.detector.status", false];
_detector setVariable ["flay.detector.radius", _radius];
_detector setVariable ["flay.detector.callback", _callback];

FLAY_ev_ExplosionDetectorHandler = {

   _ammo = _this select 6;

   if (_ammo in ["DemoCharge_Remote_Ammo", "SatchelCharge_Remote_Ammo"]) then { 

       _this spawn {

           private ["_detector", "_unit", "_ammo", "_explosive", "_distance", "_radius", "_callback"];

           _detector = _this select 0;
           _unit = _this select 1;    // unit that placed the explosive
           _ammo = _this select 6;

           _explosive = (position _unit) nearestObject _ammo;

           waitUntil { not (alive _explosive) };

           _distance = _explosive distance _detector;
           _radius = _detector getVariable ["flay.detector.radius", 0];

           if (_distance < _radius) then {
               _detector setVariable ["flay.detector.status", true];
               _callback = _detector getVariable "flay.detector.callback";
               if (!isNil _callback) then {
                   [_detector, _explosive] call _callback;
               };
           };
       };
   };
};

_detector addEventHandler ["FiredNear", { _this call FLAY_ev_ExplosionDetectorHandler; } ];  

But I think Kydoimos just wanted to track when the player places something, not when it detonates.

Share this post


Link to post
Share on other sites

oh... not alive _explosive Cool.

I used a different method in A2 in my IED kit. My IEDs were always covered/hidden/disguised by a clutter object and the handledamage EH was placed on them. That way, I could determine when the explosive actually goes off.

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  

×