Properties and Expressions

I see some blue sky thinking going on with regards to VASSAL 4.

In a similar vein, I would like to get the developers’ thoughts on properties and expressions. They strike me as very clunky and ad-hoc. You’ve got global properties, calculated properties (not even documented as far as I can tell), dynamic properties and markers. The names of some of the VASSAL properties seem to vary in quite awkward ways. And ways of changing them are different in different parts of the system.

Is there some scope for some rationalization? Something like the following:

  1. Many classes in VASSAL are sub-classed from VASSAL base objects.
  2. VASSAL base objects can have properties.
  3. There is a VASSAL root object that partly exists to store what might be called global properties, which can be accessed from anywhere in the system.
  4. Properties can be calculated, constant or dynamic (i.e. methods are defined to modify them). I am not sure whether it is better to think of markers as simply very simple calculated propertied or something slightly different. Efficiency maybe.
  5. For properties that VASSAL must provide by default a consistent and logical naming scheme is worked out.
  6. The new system needs to support all the functionality that is currently supported but it might be easier and better to start again to do so.
  7. Is this something where some work would be farmed out to Lua?
  8. Sometimes one uses $$ brackets and sometimes not. Could that be standardized?

I will admit I would love if “old style syntax” happened to go away in the up-conversion and in Vassal 4 EVERY expression was a beanshell-style expression. It could even tolerantly auto-convert things like single-equals-signs on the fly.

Also if we could have a ternary ? operator as an alternative to If(,) and if a numeric “0” evaluated as “false” in a matching expression and any other numeric expression evaluated as “true”

Brian

Absolutely. Vassal 4 should not be constrained by the way Vassal 3 does things. As long as we can provide ‘equivalent functionality’ to what is provided in Vassal 3, then it should not matter if the way that functionality is provided changes. Vassal 4 will be a complete redesign from the ground up based on Vassal 3 concepts and lessons, but not implementation.

The issues with Properties you mention have resulted from the development of Vassal 3 over time as more and more functionality was loaded on top and the need to maintain the existing functionality. Originally, there where Markers and a handful of accessible properties and that was it.

The $variable$ syntax was added to allow the value of properties to be included in the messages generated by the Report Action trait.

Dynamic Properties where added, because who doesn’t want a property that can be changed?

Calculated properties where added to expose the results of BeanShell expressions.

More and more properties names where exposed to allow access to useful information.

‘Global’ Properties where added at the Map and then the Zone level (Zones where a late addition as well) to allow more flexibility.

The {} syntax was added to allow in-line Beanshell expressions to be used just about anywhere. The {} was required to differentiate a Beanshell expression from whatever legacy data type was previously stored in that same field.

So what we have ended up with is a mish-mash that does what we want, but not in an elegant or consistent way.

Properties will still be extremely important in vassal. In fact, the plan is that many of the current GamePiece traits will be folded into the base GamePiece as efficiently stored and accessed properties. Obviously Markers, Dynamic Properties and Calculated Properties will go this way. As you state, Markers and Calculated Properties are really special read-only cases of Dynamic properties. Many other traits will go this way as well. For example the ‘Does Not Stack’ trait would be replaced by a set of properties defining a Movement ‘Scheme’ and a ‘Stacking Scheme’. These would be Dynamic Properties, so the movement and stacking scheme could change over time.

So, in reply to your points.

In Vassal 3, there is hierarchical Structure in the order that Properties are evaluated. Property Names are simple character strings, so to evaluate property X, you need to check the following in order:

GamePiece → Current Zone → Current Map → Vassal

You can’t check for a Map property directly, even if you know what you are looking for is there. You also can’t check for properties outside of this hierarchy.

I think we need to impose a naming convention to access properties directly. Something like how Javascript is integrated with the DOM elements when running in a browser.

So if an expression in a GamePiece asks for property X, it goes through the Hierarchical search. But you can shortcut this by asking for property Vassal.X or Vassal.map[“left”].X or zone[“red”].x or even Vassal.map[“right”].zone[“blue”].x which will access a property that is not in the hierarchy of the current piece.

This also has security implications. What if map[“right”] is a Private Map to which your Side does not have access?

This is just an example, but absolutely I agree with your point that we need to standardize property names and the way they are accessed.

Absolutely. We define a clean and elegant design to implement.

?

Lua will have access to Properties, but Property handling is so fundamental to Vassal that we will want to implement the Property-handling core as much as possible in C++.

The original reason for the $$ brackets was to be able to substitute property values into the strings being reported by the Report Action trait. This was later expanded on and used just about everywhere else. In general, you will find that mostly, you can use either $$ syntax or {} syntax and both will work. But not always. We had to go through the code field by field and update every case. We didn’t get them all.

So, for example

The $animal$ sat on the $object$.

is equivalent to

{“The “+animal+” sat on the “+object+”.”}

Nobody wants to have to type the second version in all the time, so the $$ syntax version has persisted.

There are also issues around the translation of these sort of strings. For instance, we usually do want to translate the string in a Report Action trait, but we usually don’t want to translate the string in a Set Global Variable value, for example.

We will still need some sort of syntax to incorporate property values in strings that can be displayed to users and translated into different languages.

We could perhaps move to a more C style approach

“‘The %s sat on the $s.’, {animal},{object}”

The user would not actually type this in, the UI would take care of building it. In fact, a smarter string builder UI that is consistently applied may

Brent,

That is a very reassuring response.