Coming back to triggers seems to be a habit of mine :). I could have just added this to the last post I made on triggers, but this is actually quite important so I will make it a separate post. It seems that discovering that triggers are global objects caused quite a bit of confusion as to how to make it work via scripts. Let me remind you that triggers placed in the editor (i.e. triggers defined in mission.sqm) are automatically created only on server and automatically get all the relevant params assigned to them on clients. If you don’t want headache, place triggers in the editor.

If you want more control over your creation, then doing what editor is doing via script is a bit tricky, nevertheless not impossible. It might sound simple, create a bunch of triggers on the server and then add params to them on each client as clients join. And it is really simple, but you have to make sure the triggers do exist already when you start setting params on them on clients. There is no dedicated command to get all the triggers like you can with vehicles or allUnits, but you can do this with allMissionObjects “EmptyDetector”, though this command is tad bit demanding. But if you use it once on join, that’s alright.

Ok, so first thing first, an MP tip. If you are creating multiple global objects in a loop, DO create them in scheduled environment, preferably use spawn command to run each object creation. Why? spawn starts with slight delay as it is placed in scheduled queue for execution. If you make a bunch of global objects at once, each object will need to be sent over network to other PCs with all its params so that it can exist everywhere. SQF is very fast, so during unscheduled multiple object creation you will just spam the hell out of network. Red chain and disruption in network traffic is almost guaranteed. If you do it in scheduled environment the impact on network will be much less noticeable and can go much smoother.

putin_propaganda

The following example demonstrates some “humane” spawn of a thousand of global objects on the server with no loss of client or network performance:

0 = [] spawn { for "_i" from 0 to 1000 do { _script = position (allUnits select 0) spawn { createVehicle [ "Land_Loudspeakers_F", _this, [], 0, "NONE" ]; }; waitUntil {scriptDone _script}; }; };

Now back to triggers. We spawn all triggers on the server on server start, then set and broadcast global variable triggersMade to everyone. Each client will have to wait until triggersMade is not nil, which will indicate that all triggers are available and it is OK to set them up. I’ve also added an ID to each trigger in case you want to know which one is which when on client. Note the use of waitUntil {time > 0} when creating triggers and assigning global variable to them. It should not be necessary, but unfortunately there is currently a bug in Arma 3.

_triggerPositions = [[0,0,0],[1,1,1],[2,2,2]]; //make triggers on server if (isServer) then { 0 = _triggerPositions spawn { waitUntil {time > 0}; //^^^ needed to make sure that public var //assigned to trigger later broadcasts properly //it's a bug that might get fixed in the future { _script = [_x, _forEachIndex] spawn { _tr = createTrigger ["EmptyDetector", _this select 0]; _tr setVariable ["trID", _this select 1, true]; }; waitUntil {scriptDone _script}; } forEach _this; triggersMade = true; publicVariable "triggersMade"; }; }; //set triggers on client if (!isDedicated) then { _triggersSet = 0 spawn { waitUntil {!isNil "triggersMade"}; { _trID = _x getVariable ["trID", -1]; if (_trID >= 0) then { _x setTriggerArea [1,1,0,false]; //continue with the rest of trigger params }; } forEach allMissionObjects "EmptyDetector"; }; //continue with the rest of code //waitUntil {scriptDone _triggersSet}; if needed };

Enjoy,
KK

Basic Multiplayer Coding V2