Bug: Refresh Counters resets Layer & Text (+workaround)

I notice that Refresh Counters will reset a layer that is activated, so that it becomes inactive after the RC.
This might have an adverse affect on pre-defined scenarios, at least requiring rework and maybe causing a problem if RC is used part-way through a game.

Another area where I have noticed Refresh Counters causing a reset is Text Labels that have literal text in the text fields, rather than using a property in the field and setting the property externally. A Refresh Counters operation will clear the text settings IF the text trait is changed in someway. Caveat: It is probably v3.3 at least since I tested this.

Workaround for Module developers is to use a separate property (e.g. Dynamic Property) to set the layer or text field. The setting of the property, and therefore the layer / text, will be preserved across Refresh Counters. In general, I find this a more controllable way of using these traits anyway, but the Refresh Counters issue means that the extra complexity should be considered even in a simple case.

Mark

Do you have a log or save file where this occurs
I would like to reproduce the issue.

I have not managed to reproduce the layer issue in a small module yet , but here is a log for the text one. Uses module Commands & Colors Napoleonics v3.42

Even replicating the sequence as closely as I can, I’ve been unable to replicate the issue for layer. If it happens again I will create a log file there and then. Meantime, I have to assume it was down to some peculiar circumstances whilst I was editing.

Mark,
I played your log, when you say
now editting the Text Trait for leaders. => does that mean you did “Change Label”?
colour chsanged to blue. => I do not see anything happening here, what did you do?

So 1st Refresh no effect on label and then you do a second one and the label disappears?

What Vassal version did you use to create that log and do the refresh counters?

Kr
Claudio

Hi Claudio - here is a full description to help you understand the demo for the disappearing text.

Introduction:
The demo uses Commands and Colors Napoleonics, v3.42.
The Text Trait used for the demo is defined in a Prototype called “Leader”.
In the demo, you notice some leader blocks (e.g. across the top half of the hex-field: Trant, Wellesley, Fergusson).
Each of these names is a text label that has been previously manually applied to the block i.e. it is not predefined in the Text Label trait. The module will allow you to manually set the label with Control/L.

The log file:
Log created in Vassal v3.4.6
First Refresh Counters is immediately after load of the log-file. It has no adverse effect.
The module is open in the editor and I next amend the Text Trait in the Leader prototype… all I do is change the text colour from black to blue.
The next Refresh Counters clears the text field.
If you save the game file and reload it, the lost text remains lost.

If you use the Control+L command on any of the Leader blocks to set some new text, you can see that the blue text change was applied.

Mark

I created a bug for this issue.
Was able to reproduce it and spot the code issue.
vassalengine.org/tracker/sho … i?id=13539

Looking for a solution to fix this.

Bye
Claudio

Mark,
The issue with the TextLabel refresh deleting the text entered in the saved game should be fixed in 3.4.7
Could you retest against the snapshot of 3.4.7 below and let me know if it works?
vassalengine.org/~uckelman/t … -d013b7949

If you can reproduce the layers issue, I will look into that one too.
Kr
Claudio

Mark,
While the fix might work here, I juste discussed with Brent Easton and the fix I proposed is not in line with the trait design and will not work in all situations. Pls ignore the post above. The solution is more complex. I will get back to you if I have an update.

Kr
Claudio

Hi Mark,

I have been discussing the problem with Claudio and the issue is quite complex.

In a nutshell, The information defining a piece is split into two parts, the Type and the State.

The Type information consists of all the stuff that does not change during a game. For a Text Label, this is stuff like the font details, the offset and the command name and key. For a Layer trait it is the List of Layers and the various commands.

The State information consists of the stuff that changes during a game. For a Text Label it is the text of the label. For a Layer it is the Activation status and the Activated layer number.

The Refresher works by taking a piece, finding it’s matching Piece Slot from the GamePieceId and then creating a completely new piece from that definition with the new Type and with all traits reset to their default State (i.e. Labels will default to the text in Piece Slot, Layers will reset to the Piece Slot setting).

Stage 2 of the Refresh is to then try and copy the State information from each old trait to the ‘corresponding’ trait in the new definition. This is where we run into problems. How do you tell if an old trait even has a corresponding version in the new unit, let alone which it is?

The method the refresher uses currently is for each trait in the new piece, look for a trait in the old piece that has EXACTLY the same Type information. If one is found, then copy the State information from it. If not, then the new trait will have the default State from the Piece Slot.

The upshot of this is that for any trait that has some changeable State, and you change something (anything) in the Type, then the comparison fails and the State does not get copied across, causing that unit to ‘reset’.

The long-term solution is allocate each trait within a GamePiece in a Piece Slot a ‘Trait Id’ that is unique within the GamePiece and that can be used by the Refresher to determine exactly which trait in the new piece corresponds to a trait in the old piece. This is a fairly major piece of work which will probably not happen before version 3.6 and will only be of use for save games created with that version or later.

I think the short-term solution is to modify the Refresher to have the option to use less than the full Type information to match up the traits. For example, for the text Label trait, a match on the ‘Description’ field should be sufficient. For the Layer trait, a match on the ‘Name’ field would be sufficient.

If you have changed the Name/Description field, there is nothing much we can do.

Thoughts?

Hi Brent and Claudio,

Thanks for your in-depth work on this one. Also for the explanation Brent - it is very useful to help understanding of how Refresh Counters works.

Your Short-term proposal sounds like a good compromise. Description and Name seem like good choices for likely to be unique for Traits on a given GamePiece.

If I’ve understood the explanation correctly, would it be possible/worthwhile to add an “alternate id” mode as an option in the Refresh Counters Test/Run/Exit window ? The idea being that the “alternate id” mode would make Refresh Counters use other fields to do the trait match. So, for example, a module dev who wanted to change the Description on a Text Field, could make that change and avoid the alternate fields; then Refresh Counters using “alternate id” mode. The same dev could then do some changes to any other fields and use Refresh Counters a second time but, in “normal” mode, to apply those changes. Integral help /links from the Refresh Counters panel could help users understand the option and when to use it.

Longer term, there are certain “type” fields that could usefully be “state” fields; offset is a common one, but variable colour is a reasonable requirement too (integration within the trait delivering a less complex module overall). Perhaps such ideas will not see the light of day but it would be goodness to open up these possibilities.

Getting back to the short-term solution,
The Text Trait has at least other two fields unlikely to ever become “State” fields and so good proxies for “Trait ID” and also likely to be unique (or easily made unique) for Text Traits on the same GamePiece- Keyboard Command and the - often unused - Property Name.
Layer has the Layer Names as well as its four Key commands (both may often blank or unused, but a module dev could give them a value if this helped getting Refresh Counters working for their circumstances).
Would these be good alternatives to “Description” and “Name” ?

Whilst on the topic of new Refresh Counters options, maybe a “verbose” mode that copies error reports and maybe other information to the chat window or to the Refresh Counters window ?

Hope this helps. Thanks again for the explanation, it’s nice to know that the Layer issue that I observed was probably an instance of the same problem even though I couldn’t reproduce it.

Mark

Nice reading this post. I observed that same thing. I just did not report it as I could do a manual reset of the auto reset counters.

Good news is that latest versions of Vassal have a Refresh Counters that does deal with Text Label and Layer traits. You just need to be careful to change the description and other fields independently of each other, doing a refresh in between. The clue that you’ve got it wrong is that the trait will reset to its default state. Many thanks to Claudio and Brent for this and the mass-refresh ability that has also been added. Developing a module with lots of pre-set scenarios is a lot easier now.

There are other traits out there with a similar issue, Rotate is one. Any trait with a state which is manipulated through key commands, as far as I can tell. A design workaround to avoid the issue going forward, is to use a property to set the state, where this is an option (e.g. Text Label and Layer).

I have the problem that layers that are inactive become active on a refresh. This is a problem for my pre-defined setups. I can set them inactive manually, but I have a few decks where I don’t know how to apply the key command that sets them inactive.

Hm, come to think of it, I could create a counter that contains a GKC to switch all layers inactive. Any better ideas?

You won’t need to create a counter, you can simply add a module level GKC that is triggered by the hotkey VassalPostRefreshGHK, and select that option for a refresh, as shown:

Also, how are your layers controlled?

I’m aware of one major outstanding gap in Refresh - Dynamic Property changes will cause the DP to be reset to its initial value. That could show as a Layer or DP reset, I guess.

I have two layer traits that have shown this problem. One has stopped the behaviour after I changed it to “Always Active” and included the main image in the list of layers, but that is not possible with the other. There is no Dynamic Property involved: the layer is managed by simple menu commands to activate/deactivate, increment and reset.

I’ll do the module level GKC. thanks. Great idea. It is no problem to use with PDS’s, but it won’t work for saved games, where some forces are supposed to have the layer active, where others don’t. But then, many of my module updates have involved new counters or other stuff that is not corrected by a refresh.

By the way, the two troublesome layer traits are both new relative to when the PDS’s were created, so I think this thread explains reasonably well why I have the problem. I just don’t understand why the layers are set Active by the refresh, and not Inactive.