Using Alert()

AANNNDDD so I attempted to implement what I said, and it didn’t work. I had pared down my test case to simplify, so this worked:
credits = 0 + Alert(“No money”)
but this didn’t: credits = if(credits < 10, 0+Alert(“no money”), -10)
What failed was not the Alert but the If. It unconditionally shows the Alert dialog box regardless if the “if” is true or false. It doesn’t matter how much money the player has, he gets the warning. It decrements properly, but he always gets the Alert every time.It’s as if vassal were executing both the true and false expressions at the same time. I wonder if there is a problem embedding one method inside another. In any case, I give up. I am out of ideas.

I don’t know if you meant to be snarky, but if so, it’s not helpful. I touched help from the Expression Builder and got the Expression Builder help page, but that page as far as I can tell has nothing there about the various functions. And I don’t see any links from there to anywhere else. I said “if it exists” because the function docs may exist, but I don’t know where they are. As far as updates, I couldn’t write anything with any certainty that it would be accurate. All my conclusions are from personal testing, and its easy to make mistakes.

I apologize for sounding grumpy Stan. I was tired and ill and mis-read what you wrote.

You are currently THE expert on the Alert function and are best placed to suggest changes to the reference manual. Documentation is an area where non-technical users can make a big contribution to a project. Developers are hopeless at writing documentation because often, they aren’t using the software ‘for real’.

The Beanshell If statement is a Vassal add-on, it’s not a piece of ‘code’ that is ‘executing’. It is presented with the 3 arguments (test, true case, false case) already fully evaluated. Normally, this wouldn’t cause any problems if you are just evaluating numbers or strings. But the Alert function has the side-effect of popping up a message so yes, you will always see it regardless of whether the If test is true or false. The Alert has already displayed before the If function checks the result of the Test. There is no real way around this. However, I may be able to upgrade Vassal to use the latest version of Beanshell which includes the A ? b : c ternary operator, the lack of which is the original reason I created the add-on if statement. This would allow you to write { credits < 10 ? alert(“Not enough money”) : -10} and the alert would only get evaluated/executed if the test was true.

The Alert function seemed like a good idea at the time, but as you have shown, it is actually next to useless in practice as you can’t fire it off when you need it. Probably should have made it a trait triggered by a keystroke.

Well holy crap! Our Beanshell already supports the ? operator. I got something like this:

{ (credits < 10) ? Alert(“Not enough money”)+0 : -10}

working. If credits < 10 do the popup and don’t decrement, otherwise decrement.

Just be careful about using the Alert function in any calculated property displayed in a label or you will end up in an infinite loop of Alert boxes!

Wow! It works! It’s the answer! You earned yourself a virtual lollipop. What flavor? I’d choose coconut cream pie.

So I experimented myself a little and discovered what you might already know: ++, --, >>, <<, bit operators & and | work too.
About ++, --. They work after a fashion, but not in a useful way. If I have properties x = 0, y = 0, and I set a global property x like this: x = ++y, then it increments y and stores the result in x, but it does not change y itself. It’s as if it put y in a register, incremented it, but never loaded it back into memory.

Just for fun too, I put this into the expression builder: int add(int a, int b) { return a + b; }
It gave me a green check mark (!), but I didn’t bother trying it out because it wasn’t an expression.

Beanshell is a full, interpreted version of Java. However, the binding between Vassal properties and Beanshell variables is only one way. Beanshell can read Java properties but not write to them.

An expression is converted into a small program fragment and ‘compiled’ which returns a list of undeclared variables. The undeclared variables will be references to Vassal properties. At run-time when the expression is evaluated, the undeclared variables are created as temporary variables and set to the value of the corresponding Vassal property before evaluation.

Writing values back into Vassal properties is beyond the scope of the ‘Expression evaluation’ use case and Vassal is (mostly) not built to handle it.

I just got this to work in a useful way for me. This strikes me as something that should be added to “Tips and Tricks!” at the very least.

I was able to get this working, but don’t have a second computer handy. Do you know who sees these alerts? Is it the active player? Everybody? Or is it map-based?

Good question. I ran a test, and only the player who issued a command to cause it got the message, so you can’t suddenly broadcast to everyone “winner! winner! chicken dinner!”

Bummer. I was hoping to use it for interrupts, preempts, op fire etc…

I wonder if there is a way to GKC it to something that everyone would see…

Strange. That should not happen if both clients are running the same version of the module, the same beanshell should get executed against the same properties on both clients and issue the Alert to each player on their own machine.

Perhaps it’s intentional? In any case, please don’t change that behavior–we use Alert() in the Terraforming Mars modules to provide additional instruction when a player has to place a tile which has special placement restrictions. It would be rather annoying if the Alert pop-ups were visible to all the players.

Aha. I know what is happening and no, we won’t be changing the existing behavior.

Technical blah: The reason the Alert box is not being seen by other players is that the Alert box does not generate a Command as such, it is just the side effect of the execution of a piece of Beanshell during the creation of a Command in the source client (Assuming the Beanshell is even executing during creation of Command, which is not necessarily true). However, the generated Command has already incorporated the results of the Beanshell execution so that the destination clients don’t actually run the Beanshell at their end, they just use the results of the Beanshell calculations sent through from the source to directly update their state.

So, in a nutshell, if we want a Dialog popup that will be seen by other players, the behavior has to be incorporated into a Command that is sent through sendAndLog() and a Beanshell function inside the Expression Evaluator is not the place to do it. It really has to built into a new Trait. Good starter project for you m3tan :slight_smile:

“Baby’s First Custom Class!!!”

Yeah not happening anytime soon. ;-) I have 2 games I need to build Vassal modules for and my programming background led me unrealistic timeframes as to how quickly I could finish them. I recognize now that Brent and others have done a standup job of morphing Vassal to do things it was never intended to do, but this whole BeanShell vs. Classic learning curve has probably put me at 100 hours for stuff I could have accomplished in 20 hours if it wasn’t a total newb. I figured it would have divided my normal output by about 2-3X, but it’s been about 5X. The real pain was going back and completely rewriting stuff that I thought would work, once I found out the hard way it wouldn’t…

I have had no problem with putting global properties at different levels as long as I obey the scoping rules it forces. I suppose selectively restricting commands would work, but I’m not looking for a different solution to my credits problem. I am looking for an answer on alert(), and the credits problem is just an example to better illustrate what I want to do.

An expression is converted into a small program fragment and ‘compiled’ which returns a list of undeclared variables. The undeclared variables will be references to Vassal properties. At run-time when the expression is evaluated, the undeclared variables are created as temporary variables and set to the value of the corresponding Vassal property before evaluation.

Writing values back into Vassal properties is beyond the scope of the ‘Expression evaluation’ use case and Vassal is (mostly) not built to handle it.

Regards

Can alert include $$ strings, or global properties in some way? Or should I use ? : with unique alerts?

$$ strings work just fine.

Oh wow, I do like alerts. Old me would have just assumed a player would look to the reports to see what happened, but now I think that alerts are a very nice way to avoid player confusion due to a set sequence of consequences being resolved instantly. For example, you can pause mid-trigger to tell a player exactly what will happen next, just after a visual layer change on a piece and just before the piece gets deleted.

Just one question: What is the best low-impact way to trigger an Alert() from a key command, independent of a calculation? Currently I have a pointless “send to location” trait with the destination being a Zone {0+Alert(“text here”)} to trigger the Alert, but is there a better way to do it?