Dynamic variable names difficulties

I want to create global property names that have dynamic portions.
Still struggling with getting this working.

I have a predefined list of Global Properties like:

  • gLocationSoviet3A=0
  • gLocationSoviet10A=0

For example, when the piece for Soviet 3A is placed, I’d LIKE to set the Global Property by calculating the variable name in real time in the prototype instead of hard coding it in each separate piece.
The goal would be to create the GP name (in this case gLocationSoviet3A and assign a value with a SetGP trait inside the piece.

Here is my Set GP dialog (right now, defined in the piece, not a prototype…)

I have checked my variable name construction via a Report Action output here:

This runs OK, but I don’t see the value in the GP ever change - I see the report action when the piece moves, so it should be triggering the SGP as well since they react to the same event.

When I attempt to print out the value in the Report Action using the constructed name to try and get a value:
ex: {$(“gLocation”+Side+BasicName)} -or-
{ $(“gLocation”+Side+BasicName)$ }

I get a Bad Module Data error.

Here is the error log snippet…

2023-07-05 15:50:58,824 [161309-AWT-EventQueue-0] WARN VASSAL.tools.ErrorDialog - Piece: 3A Trait: Report Action - Debug - gLocationSidePIece event - MovedOnMap Source: {$(“gLocation”+Side+BasicName)} Error: Expression evaluation error. See the errorlog for more details.
Expression Audit:
Source type=Piece Trait
Source name=Piece: 3A
Source description=Trait: Report Action - Debug - gLocationSidePIece event - MovedOnMap
Source field=Report format
Source Expression={$(“gLocation”+Side+BasicName)}
Side=Soviet
BasicName=3A
Error=: Command not found: $( java.lang.String )
2023-07-05 16:10:58,146 [161309-AWT-EventQueue-0] WARN VASSAL.tools.ErrorDialog - Piece: 3A Trait: Report Action - Debug - gLocationSidePIece event - MovedOnMap Source: {“location:”+$(“gLocation”+Side+BasicName)} Error: Expression evaluation error. See the errorlog for more details.
Expression Audit:
Source type=Piece Trait
Source name=Piece: 3A
Source description=Trait: Report Action - Debug - gLocationSidePIece event - MovedOnMap
Source field=Report format
Source Expression={“location:”+$(“gLocation”+Side+BasicName)}
Side=Soviet
BasicName=3A
Error=: Command not found: $( java.lang.String )

You can’t use $$ to construct the GP name inside the curly braces {} in this context. This method does have use in a search type function (it means “substitute the current value of the enclosed property, rather than the value on the target piece”).

For your application, I think just removing the curly braces will do the trick. That puts you in legacy mode, where the $ enclosed names will be evaluated and substituted to yield the actual GP name.
e.g. gLocation$Side$$BasicName$ might give you a GP of gLocationSoviet3A

That doesn’t work if you need indirection (a second level of substitution). In that case, go back to beanshell (curly braces) and use the GetProperty() function.

1 Like

Thanks! OK tried that in the SGP - no curlies. Seems OK for the SGP, but…

I assign the value on a Key Command of “MovedOnMap” as the location (the local variable in the piece…). Here is the SGP now:

Here is printout 1 (just the local location variable contents to make sure it has something

Here is the report action for the GP (using GetProperty…)

When I place a piece with this logic, I see

I see local loc = 622 (correct)
I see loc =
nothing - no value is printed out from GetProp function call… I am using the global property name literally just to check to see if it is set to anything…it appears that it is still empty.

Put double quotes around the GP name:

This report format will also work without curly braces, as
loc: $gLocationSoviet3A$

1 Like

Okee dokee. tried it - got this:

two Report Actions:


result


in the second one, I took out the “+” as well - it just takes the + out of the output…

I can share the module if that’s easier - this thing is driving me crazy :slight_smile:

Try setting the GP to $LocationName$ or {"LocationName"}, either should work.

In this trait:

1 Like

cool - first one yes, second one no. thx. I can sleep again maybe…lol

This is pretty finicky - I feel I am lacking in my understanding of how these get processed WRT to quotes, curlies, $, etc…

Now for the final task:

I want to use the dynamic name to print out the value…the puzzle continues
Any idea how I represent

gLocation$Side$$BasicName$ when I try and report out the value or assign it a value directly?

In general, don’t use $variable$ if Beanshell is available (Calculator icon on the field).

If BeanShell is available then from the point of view of an trait in the piece:

{"gLocation"+Side+BasicName} is the name of the GP you are interested in and
{GetProperty("gLocation"+Side+BasicName)} is the current value of that GP.

As mentioned, $variable$ should only be used in Global Command Property Match Expressions for the specific purpose of replacing sections of the expression with values from the piece issuing the Global Command.

The fact the $variable$ syntax works in some usages in various fields is a historical anomaly, you can’t depend on it.

If you want to learn a bit more about Beanshell syntax, read the chapter on expressions in any Java beginners course. Beanshell is pure Java syntax.

2 Likes

Thanks. Perfect - I’ll review the docs for BeanShell in Java.

1 Like

Not to be obtuse, but WHY??? Why would you create GLOBAL Properties, where every piece needs it’s own unique global property?

If you simply use a Dynamic (not Global) property “MyLocation” (or other name), IMHO you would vastly simplify your architecture.

Thus MyLocation for piece 3A might be 1067, while MyLocation for piece 10B might be 1572, etc.

I suppose I could, but I want to learn how this works…

Initially, I wanted to have access to some data for a small number of pieces, in this case, HQs. There are only about 20 total and usually not all in the game at the same time.

The game uses supply lines (terrain that is a road, rail, or town) to determine in or out of supply. Each supply line can be interrupted by the other side’s pieces. I was using the global props to maintain essentially a list of occupied terrain (location) as well as side and type of unit on that terrain so I can examine them during a supply check activity.

Ultimately, I may go a different direction altogether, but it was fun learning about it.