Jump to content
🛡️FORUMS ARE IN READ-ONLY MODE Read more... ×
Sign in to follow this  
Tankbuster

Dedicated Server triggers. All about them and potential pitfalls

Recommended Posts

Could those that know better than me, and there's a lot of you, have a look over the following?

I was unexpectedly plunged days of research and testing when I found out;

  1. triggers created in the mission editor exist on all machines, server and clients
  2. triggers created by script, only exist on the server

This isn't too bad though. triggers that are only on the server, can still be activated by clients. It'd be nonsense if they couldn't.

But, you have to be a bit clever with the condition fields. Previously, I was using vehicle player in thisList to see if a player (not an AI) comes into the trigger.

As I understand it, there are no players on the server so this code would be replaced by { isPlayer _x } count thisList > 0 So that's a boolean, rather than an object. Going to have to look at how I do my 'vehicle player' and stuff.

So, have I got all the above right?

Also, I notice other people use thisList and others use list when working with entities that have could activate a trigger. I'm not confident I know why I should use one over the other so I'd love some insight on that.

Are there further pitfalls in store for me?

Anything else that might be relevant?

Share this post


Link to post
Share on other sites

First an answer to some of your side questions and then to the heart of the matter:

-"triggers created by script, only exist on the server" if the script is run on the server. If it is run on a client it will exist there too.

-Use thisList when referring to the trigger within its own condition, activation, and deactivation code.

-Use list when referring to a trigger outside of itself. So, if you wanted to refer to units inside a trigger's detection area from an external script or a different trigger then you use list.

Now, on to pitfalls and the crux of the matter. IMO, outside of a few circumstances, if you have a complex condition to evaluate, then it should NOT be done within a trigger's condition field.

Now, I realize this is easier said than done...because it is easier said than done. To make what you are trying to do MP compatible is not a simple task outside of a trigger. A trigger is a powerful and neat little package but the more complex the condition code...the harder it is to control the power.

I will have some example alternatives for you later...but I just wanted to put that out there.

Share this post


Link to post
Share on other sites

I'm surprised to see you say that you shouldn't do complex evaluation in the condition field. Are you suggesting that you should do a single, simple eval there, then fire up a script, pass list and do the rest of the condition checking in the script?

Share this post


Link to post
Share on other sites

You can do complex evaluations in trigger condition fields, that's not a problem at all. It's even possible to run complex scripts in trigger conditions and add false as last statement (the trigger condition will never be met with this and is running as long as the mission is running). Trigger condition fields are evaluated about two times a second, the code is running in the so called non scheduled environment like event handlers (no sleep and no waitUntil possible). Non repeatedly triggers do still evaluate the condition even when the condition was met once.

Triggers are always local. Even editor placed triggers are local, they are no network objects like vehicles. So deleting an editor placed trigger on the server doesn't delete the trigger on the clients too and vice versa (you can also delete an editor placed trigger on one client, the trigger is still available on all other clients plus the server).

Triggers created by script do only exist where the script was executed.

Xeno

Edited by Xeno

Share this post


Link to post
Share on other sites

Thanks everyone. It's becoming a little clearer. I think I have to iterate through thisList and do my funky checks on _x. Xeno, your domi code (which as you know, I know almost as well as you do :)), has been helpful too!

Further question, if I'm testing server side triggers, how can I have them do something the client can know about for debug purposes? I mean, in testing and development, if a server side trigger fires in the on activation, I can write to diag_log, or spawn an object (a chicken is good because you can see it and it moves). I tried the effects menu to make a sound but clients can't hear it, also, globalchat doesn't appear for the client.

Is there something obvious, and repeatable, in a serverside triggers on act field, I can have the trigger do so that all clients see it without filling my test missions up with chickens? :)

Share this post


Link to post
Share on other sites

Oh yeah, that's working. :) The sound loops.. but I can't delete it. I've tried using deleteVehicle to delete the object created by createSoundSource but that doesn't work. I've also tried deleting the trigger itself, but that doesn't work either, the sound keeps playing.

Share this post


Link to post
Share on other sites

if (!isServer) exitWith {};
_tnul2 = createAgent ["Goat01_EP1", getMarkerPos "marker1", [], 3, "NONE"];
_tnul1 = createTrigger ["EmptyDetector", getMarkerPos "marker1"];
_tnul1 setTriggerArea [5,5,0,false];
_tnul1 setTriggerActivation ["WEST","PRESENT",true];
//_tnul1 setTriggerStatements ["this", "_tnul3 = createAgent ['Hen', getMarkerPos 'marker1', [], 5,'NONE']", "diag_log 'trigger off'"];
_tnul1 setTriggerStatements ["this", "_tnul3 = createSoundSource ['Sound_Alarm', getMarkerPos 'marker1', [],0];", "deleteVehicle _tnul1"];
sleep 15;

deleteVehicle _tnul3;

I've tried deleting the sound object and the trigger itself, both in the statement after the long pause and in the triggerdeactivation and all permutations of the above.

Share this post


Link to post
Share on other sites

I think the problem is that _tnul3 is local to the setTriggerStatements block and is not accessible in the main scope of the script. Try making it a global variable instead.

Share this post


Link to post
Share on other sites

Oh damn! I already knew that. :) I discovered that you can't use deleteVehicle on _objects a few weeks ago. I even posted about it. LOL.

---------- Post added at 07:31 PM ---------- Previous post was at 07:15 PM ----------

tnul1 setTriggerStatements ["this", "tnul3 = createSoundSource ['Sound_Alarm', getMarkerPos 'marker1', [],0];", "deleteVehicle tnul3"];

works a treat. Thanks. :)

Share this post


Link to post
Share on other sites
Sign in to follow this  

×