Skip to content

Possible fix for Detach UnDo issue#14298

Open
riverwanderer wants to merge 5 commits intovassalengine:release-3.7from
riverwanderer:release-3.7-detachbug2
Open

Possible fix for Detach UnDo issue#14298
riverwanderer wants to merge 5 commits intovassalengine:release-3.7from
riverwanderer:release-3.7-detachbug2

Conversation

@riverwanderer
Copy link
Copy Markdown
Collaborator

@riverwanderer riverwanderer commented Oct 16, 2025

Replacing #14297.

AI-mediated, passed an initial test.

This fix addresses a critical bug in the Deselect trait (when configured with the "Remove piece from stack" / unstack option) where a piece would disappear from the map after the Detach action was undone.

AI-described fix:

Root Cause
The root cause was the implementation within the Deselect.myKeyEvent() method when unstack was true. The command chain generated for the detach action was structurally flawed:

It relied on Map.placeAt(outer, pos) to unstack the piece, which generated a Command that did not reliably restore the piece's parent (the original Stack) upon undo, causing the piece to lose its Map/Zone reference.

It immediately followed the unstack with unnecessary and confusing logic that attempted to create and place a new, empty stack at the same location. This compounded the state corruption during the undo operation.

The Fix
The fix involves simplifying the command chain and removing the faulty logic to rely on the VASSAL engine's core capability to manage piece container changes.

Faulty Logic Removal: The code that called m.getStackMetrics().createStack(outer) and subsequently placed this new, empty stack was removed.

Command Isolation: The resulting command (c) is now isolated to only the single necessary action: c = m.placeAt(outer, pos);. This command removes the piece from the original stack and places it directly on the map.

By simplifying the command and removing the conflicting state changes, the Command generated by placeAt is now correctly reversed by the VASSAL engine's undo mechanism, ensuring the piece's parentage is fully restored and the piece reappears in its original stack upon undo.

File(s) Modified:

VASSAL/counters/Deselect.java

…h dice roll.

Creating a single masterCommand in DR().

Appending all actions (Hotkeys, Chat Report, Property Set, and the ShowResults command) to this single master command.

Calling GameModule.getGameModule().sendAndLog(masterCommand) only once at the end of DR().

This process ensures that a single user action (the dice roll) generates one log entry, which then only requires one undo step to revert the entire sequence, correctted in previous Commit.
…sync with dice roll."

This reverts commit 5873501.
Accidentally pushed.
@riverwanderer riverwanderer self-assigned this Oct 16, 2025
@riverwanderer riverwanderer added bug Something isn't working Awaiting Testing/Feedback Change is good, but neeeds testing or feedback labels Oct 16, 2025
@riverwanderer riverwanderer added this to the 3.7.19 milestone Oct 16, 2025
@riverwanderer
Copy link
Copy Markdown
Collaborator Author

The fixed snapshot has been used in several games with the module that exhibited the bug. No recurrences or other issues so far.

@uckelman uckelman modified the milestones: 3.7.19, 3.7.20 Dec 30, 2025
@uckelman uckelman modified the milestones: 3.7.20, 3.7.21 Feb 6, 2026
@riverwanderer riverwanderer added Ready for Review Ready to be reviewed for Merging and removed Awaiting Testing/Feedback Change is good, but neeeds testing or feedback labels Apr 2, 2026
@uckelman uckelman removed this from the 3.7.21 milestone Apr 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working Ready for Review Ready to be reviewed for Merging

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Undo of a Detach (Select trait) may cause a piece to disappear

2 participants