Another UnDo bug example

Whilst working on a bug in the C&C Napoleonics v3.42 module, I realised that there was what I am pretty sure is an undo bug affecting decks.

In this module, there are two player hands (private windows). Each window has two multi-action buttons defined that perform the following-
Selects all cards matching the specific marker type (e.g. “Command”)
Discards the selected cards to an empty deck that is offset from the board (hence, hidden)
The deck is “always shuffle” and “draw face-down”.
A card is drawn from this pile and sent to the main board, where is appears masked but the owning player can see it / flip it.
Finally, all remaining cards in the temporary deck are returned to the player’s hand.
There is a bug in this function, in that the returned cards are also masked (they should all be flipped up). That is not the problem, however.

The case is:

  1. Press one of the multi-action buttons
  2. UnDo
  3. The affected cards will now be back in the player’s hand but all are masked as if no longer owned by the player e.g. can no long be flipped.

I have developed a fix to the module bug that results in flip-down on return to the player hand in normal operation but the undo bug persists. As part of this fix, I created an action button that flips all cards in hand by performing the same action as the afore-mentioned buttons apart from the random draw to board. This results in all cards being turned face up, including the masked cards from the Vassal undo bug.

Deck UnDo bug - Example for CCN module v3.42

Thanks for that. I have added it to my collection.

Doesn’t surprise me. Have I mentioned before how dodgy Vassal 3 Decks are :slight_smile:

Generally speaking, it is better implement UnDo as going forward rather than going backward.

A stack is build of moves relative to an initial stage (new game). A command is added to the stack for every move. The command (move) brings the map from a past stage to a present stage. An UnDo from stage n to stage n-1 is not done by recreating n-1 from n, but by ‘playing the game’ (executing commands on the stack) from stage 0 to stage n-1.

This ‘playing of the game’ is done programmatically and is of course not visible to the user. Only when the ‘game’ is at stage n-1 is the map displayed.

Stages may be different from separate moves. If a stage of the map is reached by a number of moves (that can not be separated), then UnDo will go back to the last stage were the map can be displayed in a meaningful way.

Hi @marktb1961,

Your’re log file didn’t really work for me as you where doing everything as Solitaire and the Masking is per-player, so what I saw did not match what you saw. However, I was able to reproduce the problem from your descriptions.

I will look into it. The discard button is a Multi-action button that is sending all of the cards in the hand to the always shuffled Shuffle deck, discarding 1 at random, then sending all the cards back to the hand. The Undo is leaving the cards masked as they where when they where momentarily in the deck.

Out of interest, I was able to fix the behaviour of your module quite easily by changing the settings on the Shuffle Deck to ‘Contents are Face Down’=Never and 'Draw new cards face up=Ticked. The bug is still happening, but now the state of the cards in the Deck is the same as the state of the cards in the hand, so you don’t notice it. Sadly, this would require all of your scenario start-ups to be re-built, so is probably not practical. Hopefully I can fix the bug :slight_smile:


Rhett, you are absolutely correct and would work well if the Model was completely separated from the View. You could just roll the model back to the last full state load, then roll-forward the changes up to the move before the current one, then refresh the display. It would remove the need for ‘Undo’ Commands altogether. It has the potential to be slower as you have a lot more work to do, but you could generate additional intermediate GameState snapshots to help with this.

Unfortunately, Vassal is very, very far from having a clean MVC design and all players would need to sit through a visual replay of all steps in the session each time you needed to Undo one step :astonished:

@Brent - sorry, I may have missed your post / reply back in June or I think I would have replied with an amended log file.

Anyhow, I came back here because I just noticed that the bug as I saw it seems to be fixed in v3.4.6 (and maybe earlier, for all I know).