Create account / Log in

GKC Trait Matching Properties not working

Talk about module design ideas and techniques.

Moderators: uckelman, Tim M

GKC Trait Matching Properties not working

Postby m3tan » May 29th, 2020, 12:20 pm

I have a Piece level GKC Trait in a Prototype that has a Matching Properties expression that is not working no matter what I do. It seems very straightforward and actually matches precisely the example provided on Page 48 of the Designer's Guide. I have a Marker named Power above the GKC Trait in the Piece and Markers named Power in all the GKC targets. It always evaluates the expression {Power==$Power$} as true no matter what the value of the target Marker is. So if Power=Germany for the Active Piece, the GKC triggers on every target, whether Power equals "Germany", "Italy", "China", or anything. The nutty thing is when I change the expression to {Power=="Germany"}, it works fine. So what I've done is taken the GKC out of the Prototype and specified that target Power manually for every single Piece. But it's driving my nuts why I can't get this to work using the Prototype...
User avatar
m3tan
 
Posts: 105
Joined: August 12th, 2018, 11:49 pm

Re: GKC Trait Matching Properties not working

Postby shilinski » May 29th, 2020, 3:31 pm

You need to understand the difference between the old classic syntax and the beanshell syntax. Stop doing this: {Power==$Power$}. It mixes beanshell and classic syntax in a beanshell expression. In classic, Power is a string, and $Power$ dereferences a property to its value (e.g. “Germany”). In beanshell, Power is a property that is dereferenced, and $Power$ should either be seen as a property, $ included, or it should create an error because beanshell doesn’t really know what to do with those $. Brent probably added code have beanshell understand, but I think that was a mistake.

How does vassal know when to use classic vs beanshell? These: { }. That’s beanshell. You want classic? Don’t use them.

So what you are saying with this {Power == $Power$} is: test if the contents of Power equal the contents of Power. Of course it’s true all the time!

I suspect your problems stem from a scope misunderstanding, but you don’t provide enough information about how Power is defined to unravel this. Just understand this: when a piece makes a test, it’s using properties AS IT SEES THEM, and it doesn’t matter if stuff is in a prototype or not. There is a great temptation to think you are passing or referencing a property the caller sees, but that’s not the case. You can’t pass arguments to a piece like you can in a function call. You CAN do it, but you must put the value in a global property that has a different name than Power.
shilinski
 
Posts: 167
Joined: December 22nd, 2007, 8:46 am
Location: Laurel, Maryland

Re: GKC Trait Matching Properties not working

Postby m3tan » May 29th, 2020, 3:49 pm

Thanks. That is helpful. I didn't know that $ was deprecated by beanshell. There is no mention of beanshall at all in the Designer's Guide so I'm sort of stumbling blind and learning by trial and error and asking frequent questions here. Is there some document that describes beanshell in detail?

It's definitely not an issue with scope because it evaluates correctly when I enter an expression with a fixed value i.e. Power="Germany". It's just a matter of syntax. I can't figure out the correct syntax for the comparison <Power of each potential target>=<Power of Active Piece>. "Power" is Marker defined for all Pieces involved.
User avatar
m3tan
 
Posts: 105
Joined: August 12th, 2018, 11:49 pm

Re: GKC Trait Matching Properties not working

Postby m3tan » May 29th, 2020, 4:04 pm

OK. I got it working. Again the misunderstanding on my part is not knowing where certain syntax applies or does not apply. I had originally written: {Name=="Income"&&Power==$Power$}, which failed. Then I tried:

{Name=="Income"&&Power==Power}
{Name=="Income"&&Power==GetProperty(Power)}
{Name=="Income"&&Power==GetProperty($Power$)}
Name="Income"&&Power=$Power$
Name="Income"&&Power=Power
Name="Income"&&Power=GetProperty(Power)
Name="Income"&&Power=GetProperty($Power$)

Some of those were absurd, I know, but I was pulling my hair out. Turns out the issue is that beanshell wants quotations, classic doesn't. This worked:

Name=Income&&Power=$Power$.
User avatar
m3tan
 
Posts: 105
Joined: August 12th, 2018, 11:49 pm

Re: GKC Trait Matching Properties not working

Postby Cattlesquat » May 29th, 2020, 5:07 pm

Quick rule of thumb is that any time you're inside a { } then you should not use $ $.
User avatar
Cattlesquat
 
Posts: 565
Joined: December 2nd, 2019, 4:57 pm
Location: Baltimore, Maryland, USA

Re: GKC Trait Matching Properties not working

Postby m3tan » May 29th, 2020, 6:17 pm

Cattlesquat wrote:Quick rule of thumb is that any time you're inside a { } then you should not use $ $.

After wasting hours on something that usually takes me seconds, that is crystal clear now. What about the quotations? My understanding is quotations denote a value, no quotations denote an expression. That's programming 101, but it's not always the case here apparently.
User avatar
m3tan
 
Posts: 105
Joined: August 12th, 2018, 11:49 pm

Re: GKC Trait Matching Properties not working

Postby shilinski » May 29th, 2020, 6:59 pm

About classic:
It's all about string concatenation and deranged operator notation, e.g. "=" means "test if equal." Forget about integer arithmetic or even arithmetic operators. When you type Power, it means "Power" in classic. Want to get a property value? Enclose it in $ like this $Power$.

About beanshell:
The world is your oyster, so to speak, and I think thanks to Brent. Forget all about the classic crap. It's more like real programming. "==", not "=". In beanshell, if you write Power, beanshell sees a property and gets its value. Want it as a string? Enclose it as double quotes. For example if country is a property containing "Greenland", then {"I live in " + country} creates "I live in Greenland". If a property can be translated to a number, then beanshell and vassal will do integer arithmetic for you.
For example, debt = cash - spent will compute a number if cash and spent are numeric properties.

In addition, in beanshell you can use a limited set of functions. See the Alert() function I talked about in another thread. You can have popup windows. Getproperty if you want to if the value of a property is a property and you want to get its value. Note to Brent if you are watching: could you add a random integer method and slip it into 3.3? Pretty please?

You will also see the "If" method. It is powerful and essential -- and now deprecated. To everyone who is watching, "If' can fail at times. (See the Alert discussion.) Instead, use the "?:" operator. For example, I want to set the property 'thing' to -10 if 'elevation' is negative and +10 if it is 0 or positive. I would write (in various property commands) thing = (elevation < 0)? -10 : 10

Beanshell also provides a bunch of other functions such as Math functions (random, round, et al) plus others no one has discovered yet.

In short, don't use the classic method unless you absolutely have to. If you mix it up, you'll be sorry and confused.

Q: When can I use beanshell, and how can I tell when I can't?
In vassal, beanshell is almost everywhere. If you look just to the right of an field and see what looks like a microscopic calculator, it means you can use beanshell. Press the calculator, and it opens the beanshell expression builder. As you type, you will see either a red x or green check, which tells you if your syntax is very roughly correct. When you close the builder, your expression will be enclosed in curly braces. Those braces tells vassal you are astutely using beanshell, and it now sees you with some respect. Maybe it won't core dump on you anymore. Maybe.

The only places you won't see the micro-calculator is when vassal wants a printable string. Places where in a programming language you would use printf or format statements. In vassal, it's always in reports and in the text trait. In those cases, you are building strings, and you must use the $$ to de-reference properties. (I wish it used a printf syntax, but so it goes.)
shilinski
 
Posts: 167
Joined: December 22nd, 2007, 8:46 am
Location: Laurel, Maryland

Re: GKC Trait Matching Properties not working

Postby Cattlesquat » May 29th, 2020, 7:03 pm

Been there. Part of the "steep onramp" for Vassal is comprehending the mix of legacy expressions and beanshell expressions, especially insituations where both are supported.

Inside { } i.e. beanshell, quotations mean what's inside is a literal string value. In non-beanshell (old-style Vassal, where you might see some $ $) you never use quotes AFAIK, but there are some left-side / right-side exceptions that are special.

So one thing that's now pretty hard and fast for me -- if field I'm typing in using *supports* using Beanshell (e.g. the { } expressions), then I *always* use that. Because it's more sane, more like programming, mostly supports more, etc, etc.

Alas there are plenty of e.g. text display fields where one is still limited to $ $ but that's the only place I use them.

I would definitely be in favor of Vassal 4 enforcing eradication of most/all of the old-style stuff when one "upconverts" a module, converting it all to "Beanshell" (or whatever it is that corresponds to Beanshell). Substitution in text lines may be the steepest climb.

Brian

p.s. EDIT - I see shilinksi and I posted at the same time, and w/ the same general conclusion: INSIDE THE { } LIES SANITY! OUTSIDE, MADNESS!
User avatar
Cattlesquat
 
Posts: 565
Joined: December 2nd, 2019, 4:57 pm
Location: Baltimore, Maryland, USA

Re: GKC Trait Matching Properties not working

Postby shilinski » May 29th, 2020, 7:16 pm

You reminded me of some things in classic that I've forgotten that I almost never use it anymore. If I recall, you can write an expression to be evaluated as true or false like this: Power=Germany. It will treat 'Power' as a property if it is on the left side of the single '=' and 'Germany' as a string. If 'Germany' were a property, you'd have to write $Germany$.

I know for a fact that Vassal judges you by how you write your code. It's built into the code. If you use classic when you don't have to, it thinks little of you as a person. Watch out if it every becomes sentient and can talk. Trust me; this is all true.
shilinski
 
Posts: 167
Joined: December 22nd, 2007, 8:46 am
Location: Laurel, Maryland

Re: GKC Trait Matching Properties not working

Postby Brent Easton » May 29th, 2020, 10:27 pm

Excellent summary by Shilinksi.

Think Beanshell = Java. Whatever is written inside a {} is executed as if it is Java Code. If something looks like a Java variable, then it will be bound to the value of the corresponding Vassal property based on the piece it is being executed against.. All unbound variables in the Beanshell expression are bound to the property values from the same piece at the same time.

If a Beanshell expression contains $xxxxx$ expressions, then these will be stripped out and replaced by the corresponding Vassal property on piece or component that is generating the expression before the Beanshell expression is evaluated. Think of it like a pre-processor macro expansion.

The need to include the $xxxx$ expressions is for Global Key Commands where the expression is generated by one piece, but executed against another piece. The $xxxx$ expressions allows a limited type of parameter passing that would otherwise be very clunky to implement.

So, assuming a piece issuing a GKC belongs to Germany, {Power=="$Power$} in the matching expression gets changed to {Power=="Germany"} before being checked against the Target pieces. The target pieces are checking their Power against the Power of the piece that issued Matching expression. {Power==GetProperty("Power")} will always return true because this is being executed on the target pieces, so it is comparing the target pieces Power to its own Power).

The Classic syntax is a very different beast. It assumes anything on the left side of a comparison is the name of the property and anything on the right side of the comparison is a string value without quotes. It uses '=' instead of '==', does not support () and using and (&&) and or (||) does not not follow proper operator precedence. The $xxxxx$ expansion works in the same way though.
User avatar
Brent Easton
 
Posts: 2982
Joined: December 21st, 2007, 3:06 am
Location: Berry, NSW, Australia

Re: GKC Trait Matching Properties not working

Postby Cattlesquat » May 29th, 2020, 10:41 pm

I did NOT realize that $$ could work in GKC filters that way! Key useful tidbit!
User avatar
Cattlesquat
 
Posts: 565
Joined: December 2nd, 2019, 4:57 pm
Location: Baltimore, Maryland, USA

Re: GKC Trait Matching Properties not working

Postby Brent Easton » May 29th, 2020, 10:44 pm

A GKC Manual update has been added to my 3.3 fix-up list.
User avatar
Brent Easton
 
Posts: 2982
Joined: December 21st, 2007, 3:06 am
Location: Berry, NSW, Australia

Re: GKC Trait Matching Properties not working

Postby Cattlesquat » May 29th, 2020, 11:36 pm

You know, I sort of wonder if as of Vassal 4, the whole "manual" should really be a Wiki "and nowhere else" -- a centralized spot that can also evolve as people have time to improve and edit it.

Brian
User avatar
Cattlesquat
 
Posts: 565
Joined: December 2nd, 2019, 4:57 pm
Location: Baltimore, Maryland, USA

Re: GKC Trait Matching Properties not working

Postby Brent Easton » May 29th, 2020, 11:43 pm

The problem was that a not insignificant number of people where using Vassal offline and we needed the reference manual built in. Now, the manual pages are just (braindead) HTML, and the same pages could be built into a Website. Someone looked into this, but it ended up being too difficult to incorporate the same pages into the wiki so this didn't go anywhere.

It would be great if we could work out some way of having one source for the reference manual pages that could be used for both Vassal internally and also accessible from the web.
User avatar
Brent Easton
 
Posts: 2982
Joined: December 21st, 2007, 3:06 am
Location: Berry, NSW, Australia

Re: GKC Trait Matching Properties not working

Postby m3tan » May 30th, 2020, 1:52 am

Guys, all the responses on this thread have been super helpful and really gave me some clarity. Thanks! I'm starting to see the big picture now. I realized my mistake was treating the outdated Designer's Guide as a bible. I always started with beanshell but if it didn't work, I'd rely on the DG for guidance so I'd inevitably start mixing classic with beanshell. I'm going to purge it from my hard drive ;-)
User avatar
m3tan
 
Posts: 105
Joined: August 12th, 2018, 11:49 pm

Next

Return to Module Design

Who is online

Users browsing this forum: No registered users and 2 guests

cron