Double Blind capability?

That ability could be very useful in many cases. For example, if a friendly unit moves into zone of reconnaissance of a hostile unit, and thus discovers it.

Unfortunately, both the Invisible and Mask trait does not support this kind of “third-party” actions (they share much of the same code, so not too surprising). To some extent the Restricted Access and Restrict Commands traits also has some limitations.

The problem is, that the traits filter what actions can be taken based on the current PlayerSide. Perhaps an example is illustrative:

  • suppose we have a piece a that has been “hidden” (masked, made invisible, restrict access or commands) by side A.
  • When ever a receives a “sensitive” command, it will check if the current PlayerSide matches the internally stored owner of the piece. If they do not match, then the action is rejected.
    • This mostly makes sense, because it prevents side B from “revealing” the piece.
  • Now suppose the current PlayerSide is B (or more accurately not A). The player performs some action that should reveal the piece a.
    • It could be that the End movement on this map command is triggered, and some logic in the module decides that piece a should be revealed - for example if a B piece - say b moves into the same hex as a.
    • The module logic can then send a command to piece a telling it to reveal itself.
  • However, to piece a, it looks as if PlayerSide B was the one that send the command, and will therefore reject it.
  • In other words, piece a will only accept “sensitive” commands when A is the current PlayerSide.

What the traits really need, is to allow for some command (perhaps only Named Commands) that will be processed no matter what. Of course, then it would be up to the module designer to make sure that those commands cannot be triggered in an “illegal” way.

Another problem may be, that when piece a is “hidden” by side A, it is not addressable when side B is active. That is, a command will never even try to be delivered to piece a if side A is not the current PlayerSide. However, I don’t think that’s a problem - only worth considering.

For the Mask trait (called Obscurable in the code), the culprit is in VASSAL.counters.Obscurable#keyEvent. Here, all key events are filtered based on VASSAL.counters.Obscurable#obscuredToMe which in turn uses

The logic is similar in the Invisible trait (called Hideable in the code) - see VASSAL.counters.Hideable#myGetKeyCommands.

Both of these traits could have additional key commands that are always executed no matter the current PlayerSide. That would allow the module to execute those commands “on behalf” of the “owning” side. It could also be done in derived traits so as to leave the old traits as they are.

If someone would submit a PR that did this, then now would be a good time, as it would have a chance going into the up-coming 3.8.0 release. Nudge, nudge, wink, wink :slight_smile:

Yours,
Christian