You’re probably wondering what I’m so mad about? I will tell you, it is the obligatory use of randomize.sqf scripts with Arma 3 assets. Despite numerous feedback tracker tickets and requests (1 2), new assets keep coming with own randomize.sqf scripts. These scripts are normally launched from asset init event handlers defined in CfgVehicles. For example:

class C_Offroad_01_F: Offroad_01_base_F { /* config params */ class EventHandlers: EventHandlers { init = "(_this select 0) execVM \ ""\A3\soft_F\Offroad_01\scripts\randomize.sqf""\ "; }; };

Here are several points to consider:

  1. These scripts are hardcoded and launched every time asset is created or a new player receives the asset and cannot be overridden
  2. These scripts are launched in scheduled environment with execVM command with no handler returned. This means unknown ETA of script completion
  3. Because vehicle init is executed for every JIP player as well, syncronising randomisation between clients may become difficult
  4. Some scripts, like a working clock in cargo vans, spawn endless while true loop eating CPU every 5 seconds. If you consider cost of such clock vs. gameplay value, the cost would appear to be disproportionately high
  5. Because of scheduled environment execution, spawned assets could be getting randomised with visible delay, making it quite noticeable and silly looking at that too

If it was for me I would have made BIS_fnc… library functions available for scripters and mission makers with various post randomisation features but left default asset spawn at bare minimum. I however doubt BIS would go down this road any time soon, so maybe there is a compromise to be reached?

The randomisation could simply be controlled with a single variable or a set of variables. I personally would have kept it simple and let one variable to globally disable randomisation because it is very easy to add randomisation if needed rather than remove it. However there could be several variables, one for vehicles, one for units, one for animals… etc.

So here some ideas I’ve been discussing with SaMatra (if you reading BIS please feel free to use for inspiration). Rather than having script files, the randomisation could be wrapped in BIS_fnc… and compiled alone with other CfgFunctions at the start. Then instead of execVM, spawn could simply be used. Added benefit is that functions could be re-used by mission makers to randomize their assets at will at any time.

class C_Offroad_01_F: Offroad_01_base_F { /* config params */ class EventHandlers: EventHandlers { init = "(_this select 0) spawn BIS_fnc_randomizeOffroad_01"; }; };

As I have mentioned before, JIP players could present a problem for randomisation. So BIS added setObjectTextureGlobal command and limited randomisation to run only on the server:

/* File: randomize.sqf Author: pettka Description: Removes all proxies from the car, randomizes use of rear doors (according to _rnd2) and randomizes one of the skins (according to _rnd1) Parameter(s): None Returns: Nothing */ if (isServer) then { _rnd1 = floor random 6; _this animate ["HidePolice", 1]; _this animate ["HideServices", 1]; _this animate ["HideBackpacks", 1]; _this animate ["HideBumper1", 1]; _this animate ["HideBumper2", 1]; _this animate ["HideConstruction", 1]; _rnd2 = floor random 3; if (_rnd2==0) then {_this animate ["HideDoor3", 1];}; _this setObjectTextureGlobal [0, [ "\A3\soft_F\Offroad_01\Data\Offroad_01_ext_co.paa", "\A3\soft_F\Offroad_01\Data\Offroad_01_ext_BASE01_CO.paa", "\A3\soft_F\Offroad_01\Data\Offroad_01_ext_BASE02_CO.paa", "\A3\soft_F\Offroad_01\Data\Offroad_01_ext_BASE03_CO.paa", "\A3\soft_F\Offroad_01\Data\Offroad_01_ext_BASE04_CO.paa", "\A3\soft_F\Offroad_01\Data\Offroad_01_ext_BASE05_CO.paa" ] select _rnd1]; _this setObjectTextureGlobal [1, [ "\A3\soft_F\Offroad_01\Data\Offroad_01_ext_co.paa", "\A3\soft_F\Offroad_01\Data\Offroad_01_ext_BASE01_CO.paa", "\A3\soft_F\Offroad_01\Data\Offroad_01_ext_BASE02_CO.paa", "\A3\soft_F\Offroad_01\Data\Offroad_01_ext_BASE03_CO.paa", "\A3\soft_F\Offroad_01\Data\Offroad_01_ext_BASE04_CO.paa", "\A3\soft_F\Offroad_01\Data\Offroad_01_ext_BASE05_CO.paa" ] select _rnd1]; };

What if I don’t want the randomisation? Part of the script above is essential, like hiding various elements to achieve plain look of the Offroad, but another part that deals with colours and doors should be 100% optional. So here is an idea. Introduce a description.ext parameter, for example “DoNotRandomize“. If absent or DoNotRandomize = 0; randomisation happens as usual. If DoNotRandomise = 1; randomisation is skipped. And the parameter is just a config entry that can be read with missionConfigFile command. This is how the above script would look:

//essential if (isServer) then { _this animate ["HidePolice", 1]; _this animate ["HideServices", 1]; _this animate ["HideBackpacks", 1]; _this animate ["HideBumper1", 1]; _this animate ["HideBumper2", 1]; _this animate ["HideConstruction", 1]; }; //optional if ( isServer && getNumber (missionConfigFile >> "DoNotRandomize") == 0 ) then { if (floor random 3 == 0) then {_this animate ["HideDoor3", 1]}; _rnd1 = floor random 6; _this setObjectTextureGlobal [0, [ "\A3\soft_F\Offroad_01\Data\Offroad_01_ext_co.paa", "\A3\soft_F\Offroad_01\Data\Offroad_01_ext_BASE01_CO.paa", "\A3\soft_F\Offroad_01\Data\Offroad_01_ext_BASE02_CO.paa", "\A3\soft_F\Offroad_01\Data\Offroad_01_ext_BASE03_CO.paa", "\A3\soft_F\Offroad_01\Data\Offroad_01_ext_BASE04_CO.paa", "\A3\soft_F\Offroad_01\Data\Offroad_01_ext_BASE05_CO.paa" ] select _rnd1]; _this setObjectTextureGlobal [1, [ "\A3\soft_F\Offroad_01\Data\Offroad_01_ext_co.paa", "\A3\soft_F\Offroad_01\Data\Offroad_01_ext_BASE01_CO.paa", "\A3\soft_F\Offroad_01\Data\Offroad_01_ext_BASE02_CO.paa", "\A3\soft_F\Offroad_01\Data\Offroad_01_ext_BASE03_CO.paa", "\A3\soft_F\Offroad_01\Data\Offroad_01_ext_BASE04_CO.paa", "\A3\soft_F\Offroad_01\Data\Offroad_01_ext_BASE05_CO.paa" ] select _rnd1]; };

100% backwards compatible. There are about 19 randomisation scripts, so in order to update them all, this line…

if (isServer) then {...

…has to become…

if ( isServer && getNumber (missionConfigFile >> "DoNotRandomize") == 0 ) then {...

…in all scripts (skipping essential parts like in the example above). And if you have a set of variables instead, then it could even look like this:

if ( isServer && getNumber (missionConfigFile >> "DoNotRandomizeVehicles") == 0 ) then {...

Best bit is description.ext params are global so every one will have the same condition. So let’s just hope this will finally be put to rest.


EDIT: Good news, now you can switch off randomisation just like this:

_veh = “C_Offroad_01_F” createVehicle position player;
_veh setVariable ["BIS_enableRandomization", false];