How to create an "if" statement to fire specific key?

I’m tearing my hair out over this.

I have an action button which is essentially a toggle. If a variable is 0, it changes it to 1 and does one other function. If that same variable is 1, it instead changes the variable to a 0, and then does the same other function.

I started by creating an action button which sends command ‘trigger’. Then i created 2 triggers, one which executes if the variable is a 0, and one which triggers if the variable is a 1.

I think the problem is, BOTH triggers are occurring. I can’t figure out how to execute only ONE set of commands. It appears to be executing the triggers one at a time, so it works like this:

Trigger: (Is variable 0?) changes variable to 1
Trigger (is variable 1?) (changes variable to 0)

So a single press of the button will change it, and then change it back (not what I want).

I can’t figure out how to execute only ONE of the triggers and prevent the script from continuing. How can I create an If/else statement? I don’t think it’s possible with triggers.

Yes, Triggers are executed one at a time, there is no multi-threading in Vassal, if you change anything, later actions within a trigger will see the results of earlier actions.

The easiest way would probably be to add a third trigger and do this:

Trigger: (Is variable 0?) changes variable to 2)
Trigger (is variable 1?) (changes variable to 0)
Trigger (is variable 2?) (changes variable to 1)

or alternatively, set the new value into a separate property ‘newValue’ instead of changing the original property and after both triggers have run, set the original property to the value of ‘newValue’.

Oh yeah, that’s super frustrating when you get one of those. So what’s happening is this:
(1) “trigger” comes firing through your piece
(2) Hits first trigger – “Variable is 0” so it changes it to 1.
(3) Hits second trigger – Variable IS NOW 1, so it changes it back to 0
(4) You pull your hair out

Depending on your application, there are several different ways you can go about getting it to work right:

Method #1:
(1) “trigger” comes firing through your piece…
(2) Dynamic Property (or Global Property) trait for Variable has a SINGLE response to “trigger”, which is to “set to specific value”, and in the value you put the expression { If (Variable==0,1,0) } or in this specific simple binary case you could just put { 1 - Variable } but the first format will work for strings and things like that too.
(3) Then, in additional Trigger traits that process “trigger”, do any other processing based on whether Variable is now 1 or 0

Method #2: (sometimes needed in more complicated situations – overpowered for the situation you describe, but a useful pattern)
(1) “trigger” comes firing through your piece
(2) Dynamic Property “Semaphore” is now set to 0
(3) Any number of “trigger” responders fire (e.g. one for Variable==0, one for Variable==1)… but all of them also filter for (Semaphore==0).
(4) Any of these that actually “match” and therefore “execute”, they do their stuff (change Variable or whatever), but they ALSO set Semaphore to 1. Which means that all the rest of the things checking for Semaphore==0 will now fail – in other words you won’t be setting Variable to both 0 and then back to 1 because TWO of your traits fired when you really only meant one per time.
Like I said, this “Semaphore” pattern is just slightly overpowered for the specific case you mention, but you may find it useful in similar “I only want to do ONE thing and then stop processing” kinds of situation.


Brent and I answered at the same time, me just more verbosely – any of these should work.

Couldn’t you also create 2 Layers and cycle through them with a Dynamic Property? That way you could also have images showing the toggle status.

Actually… if 0 and 1 are the only legal values, set up the value as a Dynamic Property with these settings:

Is numeric
Minimum value = 0
Maximum value = 1
Wrap = ‘yes’

Set a key command to add one to the value. When you hit your button, it sets off the key command, and all the 0s become 1s and all the 1s become 0s (because the wrap back to 0 when going over max value).

For doing the actions, your button just does the actions you want, checking the current value of the Dynamic property.