dlegion 98 Posted July 17, 2017 hi guys! i was searching a way to spawn units in a very simple way, but most important to have better performance! // file is named : VEHresBplane1.sqf if (isServer) then { uiSleep 3; _Dveh = "B_plane_CAS_01_dynamicLoadout_F" createVehicle [getPos Bres1 select 0, (getPos Bres1 select 1) +5, 990]; uiSleep 1; _Dveh setpos [getPos _Dveh select 0, (getPos _Dveh select 1) +5, 990]; createVehicleCrew _Dveh; uiSleep 1; [group _Dveh, getPos Darea, 5000] call BIS_fnc_taskPatrol; uiSleep 1; waitUntil {sleep5;{alive _x} count crew _Dveh == 0}; uiSleep 30; waitUntil {sleep5;(_Dveh distance player) > 2000}; {_Dveh deleteVehicleCrew _x} forEach crew _Dveh; uiSleep 1; deletevehicle _Dveh; uiSleep 6; null = execVM "VEHresBplane1.sqf"; }; thats the code i writed, i fear its not very efficient, and i noticed that if i use it for a ground vehicle, often happens that gets damaged, crew exit and start walk on foot, vehicle gets deleted (because in fact there's no more crew alive in), but former crew is still walking around map, and will never be deleted! i wish to delete also the "former crew" (or on long times map will become overpopulated by them !! thanks for any help ! Share this post Link to post Share on other sites
Grumpy Old Man 3545 Posted July 17, 2017 What exactly is making you worry about performance in your example? Cheers Share this post Link to post Share on other sites
pierremgi 4863 Posted July 17, 2017 Don't do that! First of all, you're here in an SP context. In MP, difficulties are growing up; I can't imagine some vehicle spawning then despawning for one specific player. You need to take allPlayers into account. For planes, it's a pain in the ass. Even BI simulation manager (module) works fine for ground assets but fails for AIr (the area seems never updated). But, first of all, in your script, you spawn (unconditional) and despawn along with a distance > 2000 m . That means , your script is running every 42 s (roughly), each time the plane is 2 km away from the player... That's probably the case when it spawns at Bres1. My advice: For all patrol aircraft, let them live! Dynamic simulation will not help so much, as I already said, it's a poor one-way ticket enabling definitely the sim. Share this post Link to post Share on other sites
pierremgi 4863 Posted July 17, 2017 24 minutes ago, Grumpy Old Man said: What exactly is making you worry about performance in your example? Cheers Not using BIS_fnc_spawngroup, using distance instead of distance2D or distanceSqr... running the code too often,.. stacking deleted units and group variables perhaps. Share this post Link to post Share on other sites
dlegion 98 Posted July 17, 2017 yep....i'm a noob...so i "feel" that somethign was not good...but didnt know what was wrong :) pierre...just to be exact: it first waituntil (detect if there's no crew alive on board) ...then (and only then) waituntil (player distance > 2000) . in fact it do its job good....considering it runs on server , everyone should get updated about vehicle creation/delete or am i wrong ?@Grumpy Old Man heh....i dont know...just fear about doing errors :) Share this post Link to post Share on other sites
pierremgi 4863 Posted July 17, 2017 15 minutes ago, dlegion said: yep....i'm a noob...so i "feel" that somethign was not good...but didnt know what was wrong :) pierre...just to be exact: it first waituntil (detect if there's no crew alive on board) ...then (and only then) waituntil (player distance > 2000) . in fact it do its job good....considering it runs on server , everyone should get updated about vehicle creation/delete or am i wrong ? Not sure to understand. Send me an MP. We could discuss in French. You're right for your script. It waits for no more crew. Share this post Link to post Share on other sites
dlegion 98 Posted July 17, 2017 ...ah and i suspect that another optimization can be have 1 single script for more than 1 single unit. righht now i've 10 scripts for 10 different units....not great :( Share this post Link to post Share on other sites
pierremgi 4863 Posted July 17, 2017 Yep, sent you some MP script. Tell me if you need also several planes. It seems to me deleteVehicleCrew is broken (can be useful for everyone). Replace with {deleteVehicle _x} forEach crew _veh and furthermore, if some bailed out, start making an early array with the crew: _trueCrew = crew _veh; then, when necessary {deleteVehicle _x} forEach _trueCrew; Share this post Link to post Share on other sites
bad benson 1733 Posted July 18, 2017 a common optimization when it comes to createVehicle is to input [0,0,0] as a position and do setpos to the desired position afterwards i think. been a while but pretty sure this will help with stutter by making it generally faster. Share this post Link to post Share on other sites
das attorney 858 Posted July 18, 2017 1 hour ago, bad benson said: a common optimization when it comes to createVehicle is to input [0,0,0] as a position and do setpos to the desired position afterwards i think. been a while but pretty sure this will help with stutter by making it generally faster. Hey dude, Arma doesn't like [0,0,0] as a spawn pos. If you download the diag version of devbranch, spawn something at [0,0,0] then check the log, it complains about the spawn being too close to "origin" (or something like that). I haven't checked in a while, but last time I was doing that and using the diag version of dev-branch, it kept spewing those warnings. If I used [0,0,1000] then it was fine. I think the warnings are edited out of normal dev branch & stable, but underneath it still doesn't like it. Personally though, Arma seems better to me now (it used to be buggy with large % of explodes on spawn but now is much more reliable), so I just work out the position beforehand and then spawn it where it needs to be in the createVehicle code and using "can_collide" so it doesn't run that routine to check the spawn pos for badness. :) Share this post Link to post Share on other sites
bad benson 1733 Posted July 18, 2017 yes but i'm talking about this https://community.bistudio.com/wiki/Code_Optimisation#createVehicle.28Local.29 not sure if that is still valid but 200 times faster sounds worth doing to me (i wonder why it does getpos player twice though). i wonder if the 1k height makes any difference. probably not though. 1 Share this post Link to post Share on other sites
das attorney 858 Posted July 18, 2017 Right cool - I never use that syntax, but I can see why it is better doing it that way if that's the syntax being used. I generally use the createVehicle array syntax - never really bothered with the older variant. 1 Share this post Link to post Share on other sites
bad benson 1733 Posted July 18, 2017 3 minutes ago, das attorney said: Right cool - I never use that syntax, but I can see why it is better doing it that way if that's the syntax being used. I generally use the createVehicle array syntax - never really bothered with the older variant. oh yea. just going by what the OP used. i wonder though how both syntax compare. gotta do some testing. Share this post Link to post Share on other sites
pierremgi 4863 Posted July 18, 2017 And i'm using bis_fnc_spawnGroup, directly on position. I'm too lazy for creating vehicle then crew Share this post Link to post Share on other sites
das attorney 858 Posted July 18, 2017 23 minutes ago, bad benson said: oh yea. just going by what the OP used. i wonder though how both syntax compare. gotta do some testing. Here's my test: _thing = createVehicle ["Land_Maroula_F",place,[],0,"can_collide"]; deleteVehicle _thing 0.65942 ms _thing = 'Land_Maroula_F' createVehicle [0,0,0];_thing setPos place; deleteVehicle _thing 0.660502 ms That's my results (only tested once). The methodology is that "place" is defined in init as: place = player getPos [10,0]; Then both codes are using the same place to spawn, plus I had to include a deleteVehicle line or there would have been 10000 objects which may have skewed the result (but both tests use that so it shouldn't give prefernce one way or the other imo). Also I used "Land_Maroula_F" as it is static class so no physx to load up on spawn (less stress etc). As you can see though, the difference is 0.001082 seconds, which should be discounted anyway as that's virtually nothing. I'd say there's no difference in effect. Let me know if your results confer/differ. 1 Share this post Link to post Share on other sites
das attorney 858 Posted July 18, 2017 I though I'd try a physx object as well for comparison: _thing = createVehicle ["B_Heli_Attack_01_dynamicLoadout_F",place,[],0,"can_collide"]; deleteVehicle _thing 20.7347 ms _thing = "B_Heli_Attack_01_dynamicLoadout_F" createVehicle [0,0,0];_thing setPos place; deleteVehicle _thing 20.02 ms So createVehicle old syntax is noticeably faster this time (wow spawning helis is hard work on Arma btw). 2 Share this post Link to post Share on other sites
Grumpy Old Man 3545 Posted July 18, 2017 Interesting, 20ms is quite a bit, 4ms more than one frame at 60fps. Cheers Share this post Link to post Share on other sites
dlegion 98 Posted July 18, 2017 You scare me guys...looks like mad genious to my noobish eyes Share this post Link to post Share on other sites
dlegion 98 Posted July 18, 2017 EDITED...sry my fault... Share this post Link to post Share on other sites
dlegion 98 Posted July 19, 2017 good news ! thanks to PierreMGI for helping me really a lot with this, and thanks for all his patience! this is the script that more or less do what i need: if (isServer) then { [] spawn { while {true} do { _grpDveh = [[ getPos bres1 select 0, (getPos bres1 select 1) +5, 200],WEST,["B_plane_CAS_01_dynamicLoadout_F"]] call BIS_fnc_spawnGroup; _Dveh = vehicle leader _grpDveh; _crewDveh = crew _Dveh; // now you have an array with these guys (pilot or else) [_grpDveh, getPos Bres1, 9000] call BIS_fnc_taskPatrol; waitUntil {sleep 30;{alive _x && _x in _Dveh} count crew _Dveh == 0 || (!canMove _dVeh && fuel _dVeh == 0)}; {deleteVehicle _x} forEach crew _Dveh; // delete crew first in case Dveh cannot move deletevehicle _Dveh; // Dveh is empty OR cannot move...better delete it uiSleep 20; // wait some time so crew can die or move away _aliveCrew = {alive _x} count _crewDveh; // returns the number of alive crew units if (_aliveCrew > 0) then { format ["BLUE crew need EXFIL ASAP at %1",mapGridPosition ((_crewdVeh select {alive _x}) select 0)] remoteExecCall ["hint"]; sleep 6; // wait 600 secs = 10 minutes (6 as test now) TO DELAY RESPAWN TO PUNISH DEATH AND GIVE TIME TO SAVE CREW if ({((_crewdVeh select {alive _x}) select 0) distance2D _x > 500} count allPlayers > 0 ) then { {deleteVehicle _x} forEach _crewDveh } else {} } else {sleep 6; {deleteVehicle _x} forEach _crewDveh}; uiSleep 6; }; }; }; ...now i intend to spawn many vehicles with it....(lets say 10) ...so maybe there's a way to use just 1 script with a variable for the vehicle type so i the "execVM" can declare vehicle name/type, but i need help on this! ...and to be really perfect, i wish to make so the side that perform the rescue will have some sort of bonus...but i'm still thinking about this. (any idea is welcome!) Share this post Link to post Share on other sites
sarogahtyp 1108 Posted July 19, 2017 Clarify what exactly that script should do as it is by now! I doubt that it works as intended because I think saw some things... if (isServer) then { would be cleaner with: if (!isServer) exitWith {}; For what reason is that endless while loop? I thought u want to just spawn something? Also why are your vecs get damaged while spawning? Work on that instead of handling those weird behaviour. u defining the vec and its crew here: _Dveh = vehicle leader _grpDveh; _crewDveh = crew _Dveh; why later using } count crew _Dveh == 0 || instead of } count _crewDveh == 0 || Here I assume some logical errors: {alive _x && _x in _Dveh} count crew _Dveh == 0 || (!canMove _dVeh && fuel _dVeh == 0) u r looping through all vecs crew. and u only count those of them which are alive (ok) and are in the array with crew members. thats double trouble in my eyes. then after the || it means ( parts needed for moving are damaged AND there is no fuel left) I think that AND (&&) should be an OR (||) thats it for now. I ve to do a break here. maybe I continue this later. Share this post Link to post Share on other sites
dlegion 98 Posted July 19, 2017 heh thanks man ! thats exactly what i was talking about when i mean "optimization" :) from my noobish point of view i just "feel" that something wrong...but no idea whats wrong and how cure it :) well...my objective is to create/spawn a vehicle with its default crew, give him random waypoints (BI_fnc_taskPatrol works good for this) and delete it when it gets destroyed (maybe far from allplayers just for eye-candy reasons). then restart the loop (create/spawn ecc...) with no ending (its a persistant dynamic battlefield). for gameplay reasons, i really wish (if its not too overcomplicated) to have a special behaviour for a situation that may happen: sometimes the vehicle gets damaged, some crew die, some crew still alive gets out of vehicle, and start running to waypoint. i could simply delete them as if they died on impact....but i find very interesting (again...if its not too overcomplicated) to get some sort of timed "rescue" for them. so if a player decide to ignore the distress call, they will deleted after 10 minutes, but if player decide to go rescue the crew, and succeed in less than 10 minutes, he get some sort of reward (i thinked to spawn a second vehicle of same type...but this one with no possibility to save crew...to not accumulate more than 1 exta vehicle at any given time). at the end, in both cases the crew should be deleted (to not accumulate AIs in long times), and a new vehicle should be created/spawned to restart the whole cycle. my english is not very good...hope you understand what i mean :) Share this post Link to post Share on other sites
pierremgi 4863 Posted July 19, 2017 To make things clearer, and because my name was associated to another code, my code was: Spoiler if (isServer) then { MGI_crash = { params ["_grpdVeh","_crewdVeh","_dVeh","_centerPatrol"]; while {alive _dVeh} do { waitUntil {sleep 5; isTouchingGround _dVeh or !alive _dVeh}; uisleep 10; format ["A %1 crashed at coordinated %2",typeOf _dVeh,mapGridPosition ((_dVeh select {alive _x}) select 0)] remoteExec ["hint",WEST]; while {(count (waypoints _grpdVeh)) > 0} do { deleteWaypoint ((waypoints _grpdVeh) select 0) }; _timingrescue = diag_tickTime; waitUntil {(canMove _dVeh && fuel _dVeh > 0) or !alive _dVeh or diag_tickTime > _timingrescue + 900}; if (!alive _dVeh) exitWith {}; if (diag_tickTime > _timingrescue + 900) exitWith { waitUntil {sleep 5; {_dVeh distance2D _x > 200 && alive _x} count allPlayers == {alive _x} count allPlayers }; {deleteVehicle _x} foreach crew _dVeh; deletevehicle _dVeh; }; if (count _crewdVeh > 0) then { _wp = _grpdVeh addwaypoint [getpos _dVeh,0]; _wp setWaypointType "GETIN"; _wp waypointAttachVehicle _dVeh; [_grpdVeh, getPos _centerPatrol, 5000] call BIS_fnc_taskPatrol; }; }; }; { _x spawn { _type = _this select 0; _spawnPoint = _this select 1; _centerPatrol = _this select 2; while {true} do { _grpdVeh = [[ getPos _spawnPoint select 0, (getPos _spawnPoint select 1) +5, 200],WEST,[_type]] call BIS_fnc_spawnGroup; _dVeh = vehicle leader _grpdVeh; _crewdVeh = crew _dVeh; [_grpdVeh, getPos _centerPatrol, 5000] call BIS_fnc_taskPatrol; uisleep 5; [_grpdVeh,_crewdVeh,_dVeh,_centerPatrol] spawn MGI_crash; waitUntil {sleep 5; !alive _dVeh && {_dVeh distance2D _x > 200 && alive _x} count allPlayers == {alive _x} count allPlayers }; uiSleep 30; call { if ({alive _x} count _crewdVeh == 0) exitWith { {deleteVehicle _x} foreach _crewdVeh; deletevehicle _dVeh; }; format ["BLUE crew need EXFIL at coordinated %1",mapGridPosition ((_crewdVeh select {alive _x}) select 0)] remoteExec ["hint",WEST]; uisleep 900; {deleteVehicle _x} foreach _crewdVeh; deletevehicle _dVeh; }; }; }; } forEach [["B_plane_CAS_01_dynamicLoadout_F",bres1,darea]]; // example }; The if (isServer) then {} is truly intended, just to make this script workable in any part of an init.sqf The if (!isServer) exitWith {}; may exit this sqf regardless of any further code. Both works with added cautions in the second case. On my mind, at least the multiple vectors is solved. It's just a question of arrays in the last but one line. Thanks for the takeover. Share this post Link to post Share on other sites
dlegion 98 Posted July 19, 2017 (edited) thanks Pierre ! my latest version is this: Spoiler // GREEN ISLAND DEFENCE -- HELICOPTER 1 if (isServer) then { [] spawn { while {true} do { _grpDveh = [[ getPos Gres1 select 0, (getPos Gres1 select 1) +20, 40],INDEPENDENT,["I_heli_light_03_dynamicLoadout_F"]] call BIS_fnc_spawnGroup; _Dveh = vehicle leader _grpDveh; _crewDveh = crew _Dveh; // now you have an array with these guys (pilot or else) [_grpDveh, getPos Darea, 9000] call BIS_fnc_taskPatrol; waitUntil {sleep 30;{alive _x && _x in _Dveh} count crew _Dveh == 0 || (!canMove _dVeh && fuel _dVeh == 0)}; {deleteVehicle _x} forEach crew _Dveh; // delete crew first in case Dveh cannot move deletevehicle _Dveh; // Dveh is empty OR cannot move...better delete it uiSleep 20; // wait some time so crew can die or move away _aliveCrew = {alive _x} count _crewDveh; // returns the number of alive crew units if (_aliveCrew > 0) then { format ["GREEN crew need EXFIL ASAP at %1",mapGridPosition ((_crewdVeh select {alive _x}) select 0)] remoteExecCall ["hint"]; sleep 600; // wait 600 secs = 10 minutes (6 as test now) TO DELAY RESPAWN TO PUNISH DEATH AND GIVE TIME TO SAVE CREW if ({((_crewdVeh select {alive _x}) select 0) distance2D _x > 50} count allPlayers > 0 ) then { {deleteVehicle _x} forEach _crewDveh; format ["GREEN crew declared M.I.A."] remoteExecCall ["hint"] } else {sleep 6; {deleteVehicle _x} forEach _crewDveh;format ["GREEN crew was rescued! extra vehicle en route!"] remoteExecCall ["hint"];_grpDveh2 = [[ getPos Gres1 select 0, (getPos Gres1 select 1) +0, 120],INDEPENDENT,["I_heli_light_03_dynamicLoadout_F"]] call BIS_fnc_spawnGroup;[_grpDveh2, getPos Darea, 9000] call BIS_fnc_taskPatrol;} } else {sleep 6; {deleteVehicle _x} forEach _crewDveh;format ["GREEN crew died"] remoteExecCall ["hint"]}; uiSleep 6; }; }; }; it seems to work, and i'm happy with it for now ! thanks for all your help ! Edited July 19, 2017 by dlegion Share this post Link to post Share on other sites
dlegion 98 Posted July 20, 2017 hello guys ! for another script, i'm trying to randomize the spawn of the vehicles of a convoy....here's the code: _RBapc = ["B_APC_wheeled_01_cannon_F","B_engineer_F", "B_medic_F", "B_soldier_AT_F","B_soldier_M_F","B_ghillie_sard_F","B_soldier_AA_F","B_soldier_AR_F","B_soldier_GL_F"]; _RBtank = ["B_MBT_01_TUSK_F","B_engineer_F", "B_medic_F", "B_soldier_AT_F","B_soldier_M_F","B_soldier_AA_F","B_soldier_GL_F" ]; _RBaaa = ["B_APC_tracked_01_AA_F"]; _RBcar = ["B_MRAP_01_hmg_F","B_MRAP_01_gmg_F"]; _RBconvoy1 = selectRandom [_RBapc, _RBtank, _RBaaa, _RBcar]; // random select an array to spawn _RBconvoy2 = selectRandom [_RBapc, _RBtank, _RBaaa, _RBcar]; _Ga3 = [[ getPos Bres1 select 0, (getPos Bres1 select 1) +0, 1],WEST,[_RBconvoy1, _RBconvoy2]] call BIS_fnc_spawnGroup; ...it returns an error, saying that he expect a string and i (evil person) give him an array. i understand the error, but cant figure how solve the problem ! thanks for help ! Share this post Link to post Share on other sites