Trigger Nightmares

I think I might have fallen again for a nasty Vassal twists. Namely that triggers - below in the trait order - stay “incumbent” and are not really bypassed. They will fire later on even if the property check now resolves to true after all (above) triggers/traits are done.

Just to make sure, am I allucinating or is that really so?

If so, that makes even a simple bifurcation (do this if player=Axis, do that if player=Allies) really hard if things change during the trait execution (like if player turn is moved to Allies, when it was originally Axis, by the trait itself)…

Yes, this is true. The KeyEvent() methods for Trigger Actions and Report Actions suggest that these traits execute top-down after all other traits have been resolved bottom-up. To resolve your bifurcation, store the property in a dynamic property that won’t be changed in the course of execution:

  1. Set storedPlayer = $player$
  2. Check storedPlayer = Axis
  3. Check storedPlayer = Allies
  4. Go to town changing ‘player’ all you want


Yeah, I had the solution already, just making sure I was not allucinating.

Anyway, this is kinda nasty, isn’t it? Wish a piece/card could give a straight answer to a question without 2nd or 3rd thoughts ;)

Or maybe it’s a feature…

Well, what’s the alternative? To check all the property matches before performing any of the keystrokes specified in the triggers? Then how could you have triggers affect other triggers at all?

Yes, sure, sometimes it’s actually convenient to have a trigger dynamically change its answer. But that is like an “advanced” exploit which should not force one to take snapshot of all his variables (like setting OldPlayer = $Player$ in your example), before doing anything, just in case a long sequence of things you might have forgotten about happens to change them later on in the command evaluation.

Imagine when I have like 100 or 1000 variables to copy, just in case… because the command sequence I am starting involves lots of prototypes, pieces, decks, the turn counter, the works…

I think it would be easier to have

a) “normal” behaviour: triggers evaluate a property expression just once (bottom-up),

b) “advanced” behaviour: triggers re-evaluate property expression when above triggers have completed (top-down)

with “advanced” being a check box in the trigger trait.

Triggers do not ‘re-evaluate’ property expressions. They evaluate them only once - they just happen to do this top-down instead of bottom-up. The bottom line is, if you want to be able to change property values mid execution but also refer back to the previous values of those properties, you’re going to have to store the old value somewhere safe. This is not a Vassal idiosyncracy, it’s how memory works.


Ah, now I got what you are saying. Of course you are right.

I guess my point is then that it would be nice to have a TRIGGER 2.0 version which implements elseif/else functionality:

Trigger Name: …
Command name/key: …
Trigger on: …

Expression check: …
Execute this:

Elseif expression check:
Execute this:…

… (other elsif blocks)…

Else expression check:
Execute this:…

I noticed that 3.2.0 has a “loop” functionality… what does that do?