Restrict Command Behavior

In the course of using Restrict command based on some trait, I come to realize that if I hide or Disable a command, they are just hidden (or disabled) in the right click menu. If I execute the key stroke they still happen and a trigger command still happens.
Am I on crack or is this the expected behavior?

Correct. They are designed to prevent a player from seeing and/or initiating those commands through the right-click menu. They where never designed to be a control mechanism to prevent those commands being executed by automation, which is assumed to be handled by the module designer in other ways.

Doesn’t seem to work that way with ownership. If I deny ownership to a user it seems to break hot keys for that user.

Sorry, I don’t understand the relevance of that statement.

You are saying restricting commands does not block the corresponding hot key.
I am saying that restricting ownership does seem to. It may be a digression but I am finding it a little annoying.

Fair enough.

It gives you more control to be able to turn manual access to commands on and off, while retaining access to them via automation. Restricting ownership is all or nothing.

That’s very deflating for me to read after spending 200+ hours building a module around the assumption that they did prevent those commands from being executed. That explains a whole ton of “bugs” I’ve been witnessing. Both the online help and the Designer’s Guide explicitly state “In either case, the restricted action will not be invoked when its corresponding keyboard combination is pressed.” I just experimented by “accidentally” grabbing stacks of cards and invoking keystrokes hidden by Restrict Commands, and they are most certainly INVOKED. Seems like I’m going to have to rewrite my entire module…

Upon further testing, it seems the actual behavior is somewhere in-between. Hide and disable DO prevent those keystrokes from being invoked when a Piece is selected by a user and the corresponding keystroke is pressed. What they DO NOT prevent are those keystrokes from occurring by automation. However, keystrokes that have no Menu Text often still are functional, which is potentially disastrous. Not as bad as I thought, but still something that needs to be addressed if one wants automation that is not easily broken…

Oh interesting - I was just coming in here to say that I’ve actually had to write traits to temporarily un-restrict something SO that automation could trigger it (and then re-restrict it). Specifically I had a “Mark When Moved” trait on units in Paths of Glory, and I didn’t want it to clutter up on the popup menu and unfortunately at the time (though now fixed for 3.3.2 or so) the trait would put a blank line in the menu even if the command text was empty, so in the automation I needed to use it for I would unrestrict it, fire the key command, and then re-restrict it to hide it again. Because when I left it restricted all the time it wouldn’t fire. But I can’t remember if at the time that happened I still had it set to Ctrl+M (i.e. a “real” keystroke) or a Named Keystroke.

It would certainly be nice if behavior was consistent (either restriction NEVER affects automated keystrokes or it ALWAYS does). But I’m not sure yet we’ve figured out the parameters of the current behavior.

Ok, so I think you’re saying that it is actually behaving exactly as stated in the manual and as I outlined earlier.

Based on your description of the way your module works and the type of errors, I still think the primary cause of your errors is the completely broken Undo system for Send to Location, Send Back and Return To Deck traits in Vassal 3.3.1 and before. These bugs would completely decimate your module, especially when Undo is performed by a different user than the one who did the original moves.

M3, you are breaking new ground and using automation in ways and combinations I haven’t seen before. I am not surprised you are pushing up against boundaries.

I would suggest that the easiest way forward is to just not issue GKC commands to counters that you don’t want to be affected by them. Include something like &&CurrentMap==“MainMap” or &&CurrentMap!=“OffMap” where appropriate. Or add a new Dynamic Property where you track the current status of the unit and allow it to be selected by different GKC’s, or not.

This looks like a candidate for future vassal re architecture to make consistent.

Yes although your first reply on this thread seemed to contradict the manual. The OP’s statement certainly does. In any event, I’m glad it’s not as bad as the OP suggested. If it were, stable automation with Vassal wouldn’t be feasible.

I agree that if the undo problems are fixed, most of the problems go away. There is a bit of a multiplier effect going on here. I very purposely constructed my Pieces with a bottom-up architecture that was intended to leverage Prototypes to scale very efficiently and accommodate future revisions. Basically, every type of Piece is constructed like this:

Piece (markers defining all Prototype traits below to make each unit unique i.e. XIX Corps)
Unit Type Prototype (traits unique to units by type i.e. infantry, armor, air)
Nation Prototype (traits unique to units by nationality i.e German, British)
Side Prototype (traits unique to units on each side i.e. Axis, Allies)
Unit Prototype (traits common to all units)

This necessitates that the bottom Prototype defines every possible keystroke that might apply to a Prototypes above it. I placed Restrict Commands within each Prototype operating under the false assumption that a keystroke command was never active if it didn’t have Menu Text. Thus there are many hidden “backdoor” commands. It’s a relatively harmless problem if CTRL-ALT-E is a hidden keystroke defined in the bottom Prototype that eliminates a unit. A player will NEVER accidentally invoke that command. HOWEVER, it suddenly becomes a big problem if the sticky mouse behavior retains the selection of units, so when a player invokes a legal command on unit A, it invokes a seemingly impossible (hidden) command on sticky selected unit B; or a MASSIVE problem when an undo by the Axis player causes a GKC invoked by the Allied player, to select every unit on the map (because it ignored the expression match) and sends everything to an off-map dead pile. This all makes sense now…

Last night I pulled all the Restrict Commands out of each individual Prototype and placed them at the bottom of each Piece as follows:

Piece (markers defining all Prototype traits below to make each unit unique i.e. XIX Corps)
Unit Type Prototype (traits unique to units by type i.e. infantry, armor, air)
Nation Prototype (traits unique to units by nationality i.e German, British)
Side Prototype (traits unique to units on each side i.e. Axis, Allies)
Unit Prototype (traits common to all units)
Restrict Command Prototype

That effectively locks down every hidden backdoor keystroke. My GKCs are already very selective, so not much to change there other than I might abandon some of them in favor of Calculated Properties because that seems to be a more stable method if it’s not too CPU-intensive.

That will never happen. It would break a ton of modules. Furthermore, the behavior is not necessarily undesirable. I view it much like the bottom-up trait behavior. Once you understand how it works, it’s a feature, not a bug. My biggest issue with Vassal is that the documentation is not good, so there is a steep learning curve, combined with many bugs that led me to many false assumptions even though I’ve been programming for over 35 years. But I’m not going to criticize Brent or Joel or anyone else who is actively developing. They part of the solution, not the problem…


I think the behavior IS consistent. Restrict Command disables a keystroke for every trait above it. It does NOT disable that keystroke in traits below it. Thus, if you select a Piece and invoke a key command that has no menu text, it will still execute every instance of that keystroke BELOW the Restrict Command, but not above it. The solution is the wise placement of your Restrict Commands - not necessarily a trivial endeavor if you rely heavily on Prototypes. Furthermore, the execution of keystrokes starts to appear chaotic if you have Trigger Actions that are invoked by the original key command. That might cause Vassal to start processing a whole new set of key commands from the bottom-up before it finishes the original command. Most traits are processed bottom-up, a handful are top-down. I’m starting to get pretty good at predicting behavior but I’m not quite at 100% yet.