Can someone tell me if it is intended that GKC buttons at the module (or Map) level are limited in function by the player who triggers it in the same way that local piece hotkeys are limited by things such as the invisibility trait and deny access trait?
I have been noticing some side-effects related to the player side of the activating player. It would seem to me that the module-level GKCs would be sort of pseudo-admin and take effect regardless of the activator’s side … unless specifically tested for “playerSide”. If this were true, designers would not need to worry about which player triggered the Turn Counter which triggers a GKC, and they would not have to block the GKC and the Turn Counter from advancing if the wrong player triggers. In other words, this pseudo-admin permission would prevent unexpected anomalies from occurring with some GKCs at the module level AND it would still permit the designer to differentiate based on “playerSide” if desired.
So, are GKCs at any level given special permissions to circumvent barriers that would otherwise stop the non-owning player from triggering a piece level hotkey? Or is the behavior of piece level hotkeys still going to block non-owning player actions even when originating from a Map or Module level GKC?
Currently, my perception is that some functions are permitted and others are not. So, the behavior is unpredictable and I’m not sure what is a bug and what is intended functionality.
I get the impression my question was too long. Here’s the short version:
Am I supposed to be getting different behavior from Global Key Commands depending on who triggers it?
I have deliberately implemented such functionality by having the GKC trigger an invisible command piece on the board.
It seems you can also run into issues with GKCs triggering effects that are above a Mask trait, so I guess “ownership” and activating PlayerSide is baked into the system at some level.
Basically, yes. Anything that’s restricted to only respond to particular players doesn’t care about where commands come from, just which player triggered them. There is no such thing as a “neutral” GKC; some player is always responsible for triggering it at some level, so any pieces that the triggering player doesn’t have access to will ignore the GKC (or any other command from that player).
I’m pretty sure this is deeply baked into the structure of VASSAL, and would be difficult to change. Might be nice for VASSAL 4.0 (which will be a complete rewrite) to have a feature for GKCs or other commands that ignore player ownership, but I wouldn’t expect such a feature to be added to 3.x.
Edit: If you need to process restricted pieces belonging to multiple players, you’ll need to provide an interface that makes it clear that each player needs to trigger the action for their own pieces (e.g, each player clicks a button that triggers a GKC to process end-of-turn actions for their side, instead of trying to have a single button click process them for everybody). This has its own issues, as if things need to process in a particular order, you need to make sure multiple players don’t click the button at the same time, as then the actions will process in parallel (each players’ actions on their own system)… (Obviously, this only a problem with live play, not PBEM!)
Odd, but I would say the exact opposite—basically, NO. GKCs don’t behave differently on who triggers them unless they are programmed to do so.
Thanks to all who replied. Based on the feedback, I think I have a bug…
I think it is good that we can test for who triggered the action and support keeping the “playerSide” property alive on module-level GKCs. I have found great utility in my current project for this property.
But, it would be great if it was left to the designer whether or not a GKC should be allowed to work differently for each player, instead of always blocked for certain things.
It sure would be good if it worked this way.
Do you believe your description is the intended functionality?
If so, I need to submit a bug.
It would be really useful it Joel and/or Brent could comment at this point; I think they have the best understanding of how VASSAL works. Unfortunately, I’m not sure if it’s possible to flag this for their attention…
You can use
@ to notifiy people. E.g., @Brent_Easton. I don’t have any comments about GKCs myself.
I have never seen a case where a GKC at any level is linked to a particular player except when the programmer has created such a link. There are certain features (traits) such as masking where a GKC’s behavior could change depending on who pressed the button, but I regard these as programmer-created links.
I re-read the OP’s original note, and I don’t see a concrete example of what they are talking about, so it’s impossible to comment further.
Thanks for your reply. I think I will need to submit a bug, based on the feedback I am getting.
One concrete example that I have isolated right now is a case where triggering a GKC at the module level triggers a piece trait “Place Marker” on an opponent’s unit. The opponent’s unit is invisible to the GKC triggering player until the marker is placed. The marker is invisible to the player who’s unit is discovered, so he doesn’t know it has been discovered.
The “Place Marker” trait is below the “Invisible” trait and is reachable by the Module level GKC regardless of player activating it…no problem so far.
But, the stack of markers is always hidden if the opponent triggers the GKC and always visible if the owning player triggers it. (edit: only the top marker is visible…no indication of the stack)
My confidence is growing that this is a bug.
I am sure this is intended and not a bug. These are what @shilinski refers to as “programmer-created links”.
The GKC buttons themselves are, by default, not restricted but they only pass the “global command” to the target pieces, they do not bypass any processing of that command by the target piece(s).
Talking of the Restrict Access and Restrict Command traits, an approach that I think you could find useful is to use a parallel key command on the target piece, one that is not restricted. One technique you can use is to put your user menu command in a Trigger (that is subject to restrictions, if you need them) and have the Trigger activate the underlying function via a key command with no menu entry. The GKC should use that same hidden key command.
As suggested by @Benkyo, a hidden (or at least, immobile) control piece can be helpful too; for instance to hold the module’s global functions such as complex GKCs, Global Hotkey and Set Global Property traits. Typically, none of these traits will have a user menu entry and you will control access via the criteria in one or more GKC buttons.
I do not have experience with Invisibility, but I am surprised if the piece is logically “invisible” to GKCs. If so, then maybe specifically that should be looked at but maybe that too is a trait ordering issue.
Thanks very much…I also get the sense that invisibility should not affect the application of a GKC.
The fact that I am getting some different behaviors is likely accidental.
Thanks for the tips on indirect application of GKCs.
Invisibility is, by definition, a trait that restricts access to a piece. Therefore, any GKC initiated by a player to whom that piece is invisible is not going to be processed by that piece. (I’m really hoping Brent puts in his 2 cents soon, in case I’m completely wrong about how things work internally!) And yes, trait order will affect this–if the GKC is triggering a trait listed after the Invisibility trait, it should still work, as the Invisibility will only hide traits listed above itself.
…appreciate you and everyone else weighing in on this. I think I will put in a bug post this evening with details…
GKC’s are only applied to pieces that are visible to the player who initiates the GKC.
The GKC is then applied to each selected piece by issuing the specified Key Command as if the player initiating the GKC directly issued that command to the piece. How the piece handles that is up to you and there are no special conditions when applying the GKC. So if you have a Restrict Command trait that prevents a player from accessing a specific trait, the GKC cannot initiate that trait when clicked by that player.
As jrwatts suggested, the way to work around this is to provide an alternate Named Key Command pathway to activate the hidden functionality.
Actually, I think that was Mark’s suggestion.
Edit: Now I’m slightly confused, as you seem to be saying that an Invisible piece will be completely ignored by the GKC, while the Reference Manual says that Invisible will only actually hide traits that are listed before it. Can you clarify which is correct, @Brent_Easton?
Yes, you are correct, the GKC will be applied to all pieces on the board, regardless of their state. It is then up to each piece to do with that Key Command what they will.
Got it…thank you. That all makes sense.
I will prep my .vlog before submitting my bug.
A related use case:
Designer intent - global processing should occur when the turn is advanced, both every turn (basic housekeeping) and some specifics on special dates (e.g., deploy new year units).
- I have a Global Hot Key (GHK) defined for the turn counter to activate on tun advance
- I have a GHK to GKC translator button defined in the menu bar
- Various pieces have traits defined that cause effects on receiving the GKC
Does the Vassal behavior in question mean that whoever advances the turn counter is the “triggering player” and as such, if opponent units are restricted (invisible, masked) their GKCs won’t get processed??? That’s IMHO a significant problem… Regardless of who advances the turn counter, the associated processing shouldn’t belong to a specific player…