Game Refresher Fixes

Thanks to Brian supplying some test cases, I have tracked down and fixed 2 issues that affected many (all but me?) users of the Game Refresher.

There where 2 issues, 1 annoying, 1 fatal for most users

  1. Place Marker/Replace with Other traits recorded in Prototypes where ‘invisible’ to the Game Refresher and any pieces created by them could never be refreshed. This resulted in the annoying report ‘X pieces could not be refreshed’. In the error log, the reason was reported as ‘Cannot find matching PieceSlot’.

  2. There was a bug in the handling of pieces created by Place Marker/Replace by Other traits that could be refreshed that caused them to be replaced by a copy of the piece that created them, not by their own updated definition.

I typically used the Refresher on Scenario setups where no piece have been created by Place/Replace traits yet, so had not seen the problems.

I also changed the reporting of the GamePiece ID check/update process that occurs every time you edit module. This process cross-references all GPID’s (The id that connects a unit on the map to the Vassal definition that defined it) look for missing, invalid or duplicate GPID’s that can be created by naive editing of the buildfile. Any found are allocated new GPID’s. This used to happen silently, but I now report this in the Chat Window so Module Designers get the feedback that this has occured.

Normally, you would only see these messages the first time you edit a module after editing the buildfile and copy/paste/insert unit or prototype definitions without carfully adjusting the GPIDs. Quite a few designers may see some of these messages the first time they edit a module after this fix is applied as Place/Replace traits previously hidden from the Check/Refresh process are assessed for the first time. Theses traits will have correctly allocated GPIDs (if created since Vassal 3.0), and if the buildfile has never been manually edited, should still be valid and not generate any messages.

From this point on, The Refresher should work as expected for all newly created games in modules edited and saved since the patch was applied.

For older save games, the Refresh experience is still going to be somewhat hit and miss. In general, the results should be better than before, but it will depend on the age of the module, the age of the prototypes in the module and buildfile editing history.

I’d like to warn users trying to refresh older save games, but it is not obvious how to accurately detect them. Once an older save game has been refreshed by an updated module, it is good to go from then on.

I don’t think we have any sort of game metadata recorded in the GameState that tells us stuff like the version number of the module or of vassal that created the save. I would actually need to know the version of vassal that the module was saved with that created the save game, if this is < X then I need to warn the user that their may be problems with the refresh process.

It would be fairly easy to add this. GlobalOptions would be a good place, turn it into a CommandEncoder and have it save/load a MetaData command to/from the load files. I can see this being very useful for future compatibility checking.


Yeah I would definitely recommend writing both the version of Vassal and the version of the Module into the save file. That will not fail to be useful. BTW it would be nice if properties exposed those pieces of information to the module - because as a module designer I might “know things” about my module and be able to pop up messages w/ Startup Global Key Command if I perceive an issue. Or even take corrective action.

Thanks so much for digging into this, by the way! Life is going to be a whole log simpler in Paths of Glory land!


I’m thinking GlobalOptions is probably not the place to manage it, better in the GameState.

I am thinking of a GameStateInfo class that would have it’s own Command to be stored into and loaded from the save game file.

I think I require the following information:
a) Vassal version number that created the save
b) Module Version number that created the save (I don’t actually need thus, but useful).
c) Vassal version that the Module was last saved with.
d) ‘Refresh’ version. Version number of the GameRefresher that last refreshed the save game. New version will be “1”.

This would be sufficient for me to determine the Refresh ‘state’ of the save game. Assuming these changes went into 3.3.3 then a Refresh should be guaranteed to be error free if a >= 3.3.3 and c >= 3.3.3.

I see no problem with exposing some of this (and other) internal information as Global Properties.

These would seem to be useful:

VassalVersion - Current Vassal Version
ModuleVersion - Current Module Version
GameVassalVersion - Vassal version used to create current game
GameModuleVersion - Module Version used to create current game

Anything else?

That’s good useful stuff. If I were imagining other pieces of GameState data “not necessarily precisely related but could be awfully handy”, then I would add:
(1) Boolean if this game has EVER been connected online at any point in its history.
(2) Boolean if this game has EVER had more than one unique player at any point in its history.

By the way, I also love that the subtle nature of the bug’s “prerequisite conditions” explain why the refresher worked perfectly 100% of the time for some module designers, where for others it was more like What, Are You Crazy? It Breaks Literally Every Time! :open_mouth:

This is a very helpful thread given my current efforts to bring greater stability to the VASL module in terms of moving saved games from one version to another.

Do I understand correctly that if the buildFile is modified manually, say to add new prototypes or to add items previously created in an extension into the main module, that it may result in changes to Piece GPID’s? Will it always do so? Or does it depend on the nature of the changes?

Are there other ways to inadvertently change Piece GPID’s beyond manually editing the buildFile?

I am trying to ensure that GPID’s only change when we knowingly decide to change them and want to avoid/prevent any development practices (good or bad) that would change GPID’s without our intent.


1 Like

I’m pretty sure that it’s when you specifically add in new pieces - via Palettes, deck or at-start stack or via the Place Marker / Replace With Other traits that you risk a recalc of GPIDs.

In a recent case, I got problems when I merged in some pieces from one module to another until I cottoned on to the idea of putting the incoming pieces at the end of the last palette in the buildfile. Once I did that then the re-calculation of GPIDs only affected the new pieces. If you follow this technique to introduce the new pieces, you can subsequently safely move them to their final destination (deck or wherever), using the editor.

The Place / Replace traits can be a particular problem I find. I think it is best to avoid defining the piece directly in those traits and instead use the option to select a piece from a palette (or At-Start Stack or Deck). Even so, I find that renaming a palette or perhaps even moving a piece from one location to another can cause a trait to reset and pick up some apparently random other piece (presumably the first one it finds).

1 Like

Thanks for this. Super helpful.

What about deleting pieces, either via the Editor or by editing the buildFile directly? Does that change GPIDs (beyond removing one obviously)?

The gp id’s appear in the buildfile as such: gpid=“48”.

Vassal will only re-calculate gpid’s where there are duplicates, i.e. 2 piece slots with the same gpid. In that case, the second of the duplicates that appears in the buildfile will be renumbered to use the next available gpid. No other piece slots will be touched, only the second (or more) occurrence of the duplicated ones.

However, Pieces in Game Palettes are not the only elements that have gpid’s, the following also have them:

  • Prototype Definitions
  • Cards defined in Decks
  • Pieces defined in At-start stacks
  • Pieces defined in ‘Replace with Other’ traits.
  • Pieces defined in ‘Place Marker’ traits.

You can successfully merge buildfiles by manually ensuring there is no duplication of the gpid’s between the two buildfiles.

The alternative technique earlier of adding the new buildfile material lower down in the buildfile works because the newly added gpids will always be the later ones if they duplicate any existing gpid’s, so only the newly added gpids will be renumbered. Once the module has been saved once and any gpid duplicates resolved, you can then move the merged material anywhere you like.