hansen111 12 Posted November 28, 2020 Hello all So im writing a function (grid system) to avoid overhead on a algorithm that checks if players are in certain areas, the question is: Do the standard triggers/modules support this already or do they just iterate through all players with something like _unit distance _center on a defined interval? If its the ladder then using the already supported mapGridPosition function would greatly reduce overhead: //INIT GRID FOR MONITORING _gridCenter = [_gridX,_gridY]; _gridID = "mygrid_" + _gridNum + (mapGridPosition _gridCenter); missionNameSpace setVariable [_gridID, true]; //CHECKING IF PLAYER IS IN GRID _gridID = "mygrid_" + _gridNum + (mapGridPosition player); Method 1: if(isNil _gridID) then {hint "player IS NOT in grid"}; Method 2: if(missionNameSpace getVariable [_gridID, false]) then {hint "player IS in grid"}; So the question becomes: what is the speed comparison between _unit distance _center <= _radius and isNil ("mygrid_" + mapGridPosition player) ? I guess i will run some simulations on this. Thoughts? Thanks in advance. Share this post Link to post Share on other sites
stanhope 411 Posted November 28, 2020 Do you mean this? https://community.bistudio.com/wiki/inArea Share this post Link to post Share on other sites
hansen111 12 Posted November 28, 2020 9 minutes ago, stanhope said: Do you mean this? https://community.bistudio.com/wiki/inArea Sure or some other stock function module we already have in the wiki, the important thing is if the grid system can greatly outperform those stock functions/modules. I did some testing and so far it seems the standard distance function is highly optimized, on 7 million iterations on my system there is only 4.5 seconds gained by using: isNil "somevar" instead of using player distance _pos <= _radius !? That is super surprising to me. Why would checking if a varibale isNil take almost as long as a full distance check!? I will test further.. Share this post Link to post Share on other sites
pierremgi 4871 Posted November 28, 2020 Incomprehensible... mapGridPosition is just a way to modify the format of position. So, at what time if (isNil yourGridposition ) could be useful to detect a "in grid ??" stuff? Share this post Link to post Share on other sites
hansen111 12 Posted November 28, 2020 Ok, so I will illustrate this better, here is the situation for a case: https://steamcommunity.com/sharedfiles/filedetails/?id=2301831648 We have 7 zones, we want to check 1 time a second what players are in these zones. Now I know of all the modules and functions in the wiki ect. that does this but we can do a lot better performance wise, or at least i think so :-) by using the grid system, I will explain why: So the normal routine to check if someone (or something) is in a certain area is by doing a function, module, trigger that uses distance checks in a certain time period in a certain area, like 1 time a second for this example, we have to do this for each zone, so 7 triggers if we use those. BIS have made a great article explaining the performance of different functions here: https://community.bistudio.com/wiki/Code_Optimisation In there we can see: // with a 30 items array _someoneIsNear = (allUnits findIf { _x distance [0,0,0] < 1000 }) != -1; // 0.0275 ms _someoneIsNear = { _x distance [0,0,0] < 1000 } count allUnits > 0; // 0.0645 ms _someoneIsNear = { if (_x distance [0,0,0] < 1000) exitWith { true }; false } forEach allUnits; // 0.0390 ms that it would take 0.0275 ms to do 30 distance checks (30 soldiers). This is for 1 zone, we have 7, so it would be for each check: 0.0275 * 7 = 0,1925 ms In the grid system we would not need to do 7 distance checks, we need to do 7 isNil checks og 1 call to the mapGridPosition function, but only 1: _mapgrid = mapGridPosition player; { if(isNil ("mygrid_" + _x + _mapgrid)) then {hint "not in zone"}; } forEach _zones; Remember we ran a short init code before the mission begins that sets the zone variables, this is done only 1 time in init: //INIT GRID FOR MONITORING _gridCenter = [_gridX,_gridY]; _gridID = "mygrid_" + _gridnum + (mapGridPosition _gridCenter); missionNameSpace setVariable [_gridID, true]; On the BIS optimisation link above you can read the time 1 isNil check takes: isNil "varName"; // 0.0007 ms So we have reduced a 7 time distance check (0.0275 * 7 = 0,1925 ms) to a 7 time isNil check (0.0007 ms * 7 = 0,0049 ms). The grid system is 275 times faster! - from that we have to deduct the time that 1 call to the mapGridPosition takes so its a bit slower but still a fantastic optimisation! Share this post Link to post Share on other sites
pierremgi 4871 Posted November 28, 2020 _gridID = mapGridPosition player; this function always return a string. So, _gridID is a string , isNil _gridID will be always false in your code. { if(isNil _gridID) then {hint "not in zone"}; } forEach _zones // no sense. Triggers with anyPlayer are fine. If the 0.5 sec check seems to be too quick for you just script them with setTriggerInterval With trigger you know what trigger (so what area) is activated (cherry on the cake imho). If you want to know if a trigger is activated, no matter which, just waituntil {sleep 1; [trg1,trg2,tr3...] findIf {triggerActivated _x} > -1}; You are using markers, not triggers, or even scripted areas? waitUntil {sleep1; { ["mk1","mk2","mk3"] findIf {!(allPlayers inAreaArray _x isEqualTo [])} > -1 }; in Polygons ? Share this post Link to post Share on other sites
hansen111 12 Posted November 28, 2020 (edited) It was mostly pseudo code to prove the system, I have now edited it so it would actually run, but you have to understand the system here instead of typos. The facts remain, the grid system on 7 zone case on 30 soldiers is 275 times faster (minus 1 call to the mapGridPosition function which I cant find a ms time on). Again the whole difference is that you dont have to do 7 distance checks but 7 isNil checks (+ 1 mapGridPosition call) Edit: And oh btw, yes im using grids. If you want to know if someone is in the circle area you have to run distance checks on those that is in the main grid, its still very few distance checks compared to running only triggers. Edited November 28, 2020 by hansen111 forgot something Share this post Link to post Share on other sites
phronk 898 Posted November 28, 2020 Haven't tried your method @hansen111 but if it's 250+ times faster than inArea, that sounds yummy. One thing with triggers though is you can also use thisList with triggers, which returns all objects in the trigger that can trigger it, if any. So if player is in the trigger, thisList will equal [player] if the trigger is set to "ANYPLAYER". That method has been fastest for me, but I'm all about optimization so who knows. Maybe you're onto something. I find a lot of stuff on the wiki to be situationally correct or inaccurate sometimes. Trial and error through experimentation and do what works for you! Share this post Link to post Share on other sites
pierremgi 4871 Posted November 28, 2020 1 hour ago, hansen111 said: It was mostly pseudo code to prove the system, I have now edited it so it would actually run, but you have to understand the system here instead of typos. The facts remain, the grid system on 7 zone case on 30 soldiers is 275 times faster (minus 1 call to the mapGridPosition function which I cant find a ms time on). Again the whole difference is that you dont have to do 7 distance checks but 7 isNil checks (+ 1 mapGridPosition call) Edit: And oh btw, yes im using grids. If you want to know if someone is in the circle area you have to run distance checks on those that is in the main grid, its still very few distance checks compared to running only triggers. This is not a "typo" remark. Your "pseudo" code runs fast because, as is, it has no interest at all... the result is immediate: isNil (mapgridPosition whatEverObject) returns false at once. You should explain your "grid system". At this time, the simple use of mapGridPosition has no sense and most of readers can't understand how to you manage your areas, the distances, the radius... and all geometric things you don't mention here. Now, if you're attempting to work with the dynamic simulation grid or something like this, you should explain a little bit. Share this post Link to post Share on other sites
hansen111 12 Posted November 28, 2020 (edited) 2 hours ago, phronk said: Haven't tried your method @hansen111 but if it's 250+ times faster than inArea, that sounds yummy. One thing with triggers though is you can also use thisList with triggers, which returns all objects in the trigger that can trigger it, if any. So if player is in the trigger, thisList will equal [player] if the trigger is set to "ANYPLAYER". That method has been fastest for me, but I'm all about optimization so who knows. Maybe you're onto something. I find a lot of stuff on the wiki to be situationally correct or inaccurate sometimes. Trial and error through experimentation and do what works for you! Yup, when im actually coding the system im going to have a routine putting players in arrays so its easy to use, it would be something like this (Not tested but you get the idea). //INIT _zoneNumbers = [0,1,2,3,4,5,6]; _gridZonePlayers = []; {_gridZonePlayers pushBack []} forEach _zoneNumbers; //ROUTINE { _player = _x; _mapgrid = mapGridPosition _player; { _zonenumber = _x; if(!isNil ("mygrid_" + str _zonenumber + _mapgrid)) exitWith { _playersInZone = _gridZonePlayers select _zonenumber; _playersInZone pushBack _player; }; } forEach _zoneNumbers; } forEach Allplayers; //To get the array of players in the zone 1; _zoneOnePlayers = _gridZonePlayers select 1; Edit: And btw if someone is wondering about grid sizes, radius ect then this system is based of the standard arma grid that the mapGridPosition function returns, a grid is 100m X 100m, every position in that grid translates to the same unique grid id which the mapGridPosition function returns when inputting the position. This system does NO distance checks but uses only mapGridPosition hence its much faster. If you need a circle distance check then you need to do normal distance checks but only for the few players inside the corresponding grid and not all players, again optimizing the method compared to only triggers. Edited November 28, 2020 by hansen111 Share this post Link to post Share on other sites