Is this deck Hotkey working as expected? [issue: 11429]

The following deck is configured, notably with a Hotkey when the deck empties:

The hotkey fires this Action Button:

In an online game, the Purple player’s control token stack became empty. This set of messages appeared in the chat log:

It is evident from that log that the one deck-empty-event Hotkey has triggered the Action Button independently for each of the 3 players in the game, even though it was only activated by one player (Chris / purple).

Is this the expected behaviour?

I was wondering why numerous other types of “deck empty” hotkey events are behaving fine in the same module - i.e. one event, one action; not one action per player.

One unique thing about the problematic deck/event is that there is one deck per player, each with different names but the “Hotkey to send when deck empties” is the same in each deck.

If I change that Hotkey for one of the players and empty that player’s deck, I get the behaviour I expect - just the message for the player.

The other thing about these decks is that at some point during module development I probably cloned them from the original one.

UPDATE: Though the workaround of having unique hotkey per deck appeared to work at first, once I completely reset with the “workaround” in place it did not work anymore. Back to the drawing board.

Issue 11429 logged, including a canned demo.

Replicates at least back to Vassal v3.5.8.

Hmmm. I have looked at the implementation of the Hotkey on Deck empty key and it fires off when the last unit is removed from the Deck. This is happening independently in each client. As each Deck in each client is emptied, each one fires off its own Deck empty hotkey.

Another issue is that a separate Command issued for the Deck empty key, so you need to press undo multiple times to step backwards. This problem I can fix, but I am unsure what I can do about the independent firing of the Deck Empty Key.

However, If I made the firing of the Deck Empty key (and all of it’s downstream processing) atomic and part of the movement Command, it would allow you to do the full processing for the Deck Empty before another client saw the Deck Empty command.

You still have the same problem though, the other client sees:
a) The last piece is moved out of my Deck
b) Therefore I need to execute my Deck Empty Key, not knowing that the next Commands in sequence will refill the Deck.

I suspect that the firing of the Deck Empty key should only ever happen on the local client as a result of Deck emptying initiated by that local client, never as a result of Deck emptying caused by commands coming through from online. Or from a VLOG file for that matter.

This sounds like a good answer to the problem. If I understand it correctly, the other instances would at least be able to tell - through the coding - that another instance had caused the event. At the moment, I don’t think there is a foolproof way to do that (i.e. without relying on the game module to infer it).

What if there’s a game somewhere that requires each player to do something (that can be automated) if a deck empties? That’s about all I can think of. Also, I just thought… this deck feature provides a potential method to force other players to do something automatically. I don’t think there is another way to do that without custom code. May be useful, I guess.

Hi Mark, Have a play with the 11429-Batch-DeckEmpty-hotkeys ( Builds of vassalengine/vassal ) build. It should guarantee that any sequence of commands that involves emptying a Deck and firing the Deck Empty Hotkey should be completely executed on the local client before being sent to the other clients as a single Command.

Note that any movement of a piece out of a Deck will still initiate the Deck Empty Key on the target client. If you don’t want it to execute, you will need to have set a flag in a GP (for example) BEFORE you initiate the Deck Emptying that you can check on the target client.

It;t not ideal and will be messy, but should allow you to work around the problem.

1 Like

Thank you, Brent… I’ve tested and I haven’t noticed any difference between v3.6.6 and 11429-Batch-DeckEmpty-hotkey. I was only using two machines in the test. However, I can get both to work in the fashion you describe (maybe, as you suggest, the new build is just more reliable).

The method I’ve used for a test is to have a GP that increments with each deck empty hotkey. The GP max value is limited by player count and wraps; so can be used to prevent any repeat action. I also proved to myself how this feature can be used to trigger a user-specific action - e.g. an Alert(). I will post an updated test module on the problem ticket which demonstrates these features.

I discovered a race condition through playing with the empty deck feature. If you set up P1 and P2 instances and empty the deck with P1; then, while a message is displayed on P1’s screen, drag the remaining card off the same deck on P2’s screen. Continue and you will notice that one of the player’s now has a duplicate card. What’s more the piece seems to be in a strange shadow-state - try moving both of the duplicates around and you will see what I mean. Whilst I provoked this situation with an extreme test, I wonder if it can still potentially occur in more normal use.

By the way, the demo module can also demonstrate this issue with UnDo and Empty Deck (UnDo when it empties a deck triggers the HotKey!).

Hi Mark,

No, I didn’t expect any difference between the two versions with the current module, the Hotkey will still be triggered in all clients. The change I added just makes sure you can reliably detect (with extra module-fu) who actually triggered the Hotkey.

The Undo issue sounds like Deck Empty Hotkeys firing should be completely disabled if the current Command being executed is part of a Command stream initiated by the Undo Button. Does that sound right to you.

The other problem. Brrrrrrr. By ‘message displayed’, do you mean a Beanshell Alert() message?

Yes, that sounds right because when Deck Empty Hotkey is allowed, any commands executed are new rather than undo which to me doesn’t make sense.