Invisible trait - I don't know if this is how it's supposed to work or a bug

My expectation is that this is a tool that provides a fog of war dynamic such that an opponent cannot see your piece(s) unless some condition is met. This would imply that if my opponent is invisible, there is something I can do to make them visible. And this is the heart of the problem. That dynamic doesn’t seem to work.

What works: (but doesn’t provide the expected functionality.)

Assume side A and side B. Side A has a piece with the invisible trait and a trigger action that will respond to a global key command to activate CTRL-I. Side B has a GKC that sends a command (such as SHOW_ME) which activates the trigger action.

This part is the crux: If I set the invisible trait parameter “Can be hidden by” to “Any player,” this sequence works. (but with non-optimal results.) –

Player A hides the piece. Retire and move to side B. Side B Now sees the transparent version of the piece and can unhide it. The non-optimal part is that player B can see the transparent “hidden” piece, defeating the entire purpose of it being hidden. But, the following process works mechanically:

Now, let’s add a GKC and some trigger commands. I have a GKC that will send a SHOW_ME command to trigger action traits for all pieces on the board. I know, from watching Reports that those pieces are, in fact, receiving the SHOW_ME command in their trigger actions. The trigger actions then fire CTRL-I just fine. The reason for all this complexity is an attempt to get around the Any player setting. I was hoping GKCs and trigger commands were agnostic of piece ownership and command “ownership”. They are not.

Once again, IF I set “Can be hidden by” to “Any player,” the GKC and trigger actions work fine, but since I can already see the transparent version of my opponent’s piece, the result is trivially useless.

If I set “Can be hidden by” to “Any side” of if I specify sides, then the invisibility mechanic works as expected, BUT I cannot change my opponents invisibility. In this case, Player A sets the piece to invisible. Retire and come in as Player B. Piece is, in fact, invisible - no longer transparent. HOWEVER, the GKC will no longer change the invisibility state via the trigger actions. Report traits reveal that the SHOW_ME command is being received by the trigger actions, but the Invisible and InvisableToOthers properties do not change. The triggers receive the GKC but do not act on it.

Net result: I can only reveal my opponent’s pieces if I can already see them. If they are properly hidden, I can’t reveal them. Thus the concept of sending a scout piece into a zone and having it look around is not implementable with the invisible trait as it exists today.

If I’m all wrong and have missed something in my implementation, please advise. Honestly, I would like to be wrong here.

Your analysis of the Invisible trait is correct:

  • If Can be hidden by is set to Any player, then any player may indeed trigger the trait and hide/un-hide the piece.
  • If Can be hidden by is set to Any side, then only the side that initially hid the piece can make it visible again.

Global Key Commands are always executed in the context of the current player (identified by a password - not user name) and current side (the side associated with a player).

From your above description, it sounds like you are playing in “hotseat” mode. When you retire, you are actually not changing the player (as identified by the password), only the current side. That’s why you, as the same player, with Can be hidden by set to Any player, can still see the transparent piece and make it fully visible again.

If you play in PBEM or network mode, each player will be distinct, and they will not see the piece when Can be hidden by is set to Any player.

I guess what you a trying to achieve is something akin to

  • Side A places a submarine, submerged, on the map. It is invisible to the other sides.
  • Side B flies a recce plane across the map and executes a Global Key Command with some range, which should make the submerged submarine visible if in range.
  • Side B can now target the submarine with Anti-Submarine-Warfare (ASW) from a near-by destroyer.

That would indeed be a very nice thing to have. However, I fear that it isn’t really possible, unless I’ve overlooked something. I tried to do something like the above in Littoral Commander: Indo-Pacific, but I don’t think I got it to work properly.

Yours,
Christian

Which means the Any Side setting is not working as expected. If I set Can be hidden to Any side or actually specify the sides, then it seems to me that trait should be controllable based on side, not player. But in that scenario, only the owning side can actually unhide the piece. This really does sound like a bug to me.

Thanks for your feedback. Sorry to hear you ran into similar difficulty. My game is actually using carriers and search aircraft, so we’re in the same neighborhood.

I think the trait is working as intended, it just doesn’t work as you and maybe others would like it to - that’s not a bug but a feature :slight_smile:

The point is that commands (whether by key-stroke or by name) are executed in a particular context of CurrentSide (or CurrentPlayer), and if that does not match the side (or player) that initially made the piece invisible, then the command isn’t honoured.

One could of course define another trait that would not block the command based on a mismatch between the CurrentSide and the side that “owns” the piece. That would require some custom code, including a custom command encoder - not impossible, but a little convoluted.

I didn’t have exactly the same problem - I just made an educated guess based on your description :smiley:

Yours,
Christian

Rather than the Invisible trait, use a Layer. First add a Marker such that the piece identifies with a side: Marker - Side = Red, for example. Add a Dynamic Property, call it Visible/Detected/Found, whatever fits. Add Key commands to hide/unhide setting the value directly to false/true respectively. For the Layer, check Always active and Levels follow expression. The Follow expression would be something like: {Side==PlayerSide||Visible?1:2}, where Side is the same as the Marker and Visible is the Dynamic Property. Image 1 is the typical image of the piece. Add a level but don’t assign an image to it. You should have two layers (Image 1 and Image 2).

The expression does two things. For the player assigned to that side the piece is always visible. It is however not readily apparent whether or not the piece is hidden to other players. A Text Label or Border Outline are possible options to indicate the visibility state to the owning player. For other players, visibility depends on the Dynamic Property. If not visible, it uses image 2 of which there isn’t one, so the piece is not shown.

Any player can use the Global Key hide/unhide commands to change the visibility. You will have to add the appropriate gating/filtering to limit which pieces to reveal where and when. Other pieces can have a Global Key search command with a fixed range defined to spot what is near, for example.

It is not a bad idea, but I think there are a number of problems with this.

If a side, to whom the piece should be invisible, does a drag-select over the piece, it will be revealed by an outline around the invisible piece.

You also have to make sure that the BasicTrait has no image - otherwise that image will be shown.

Unlike with the Invisible, the pieces hidden by layers are not immune to all sorts of key commands issued by a non-controlling side - unless extra logic is built in to protect against that.

If anyone is curious as to what happens in the code, you can see it in line 295 of VASSAL.counters.Hideable, and code called from there.

Perhaps a better option is to select Any of the Specified Sides for Can be hidden by and then list all sides. And then, implement logic that disallows a non-owning side from hiding the pieces explicitly or implicitly (e.g., a “Submerge” menu command is contingent on the current side), but allow making the pieces visible through recce.

The design of the Invisible,trait sort of assumes a flow like

  • Side A has submerged a submarine in hex 1020.
  • Side B performs recce in an area that encompasses that hex, by declaring to do so.
  • The player controlling side B ask the player controlling side A to reveal any submerged submarines in the searched area.

That is, there’s some back and forth between the players. This certainly models how it would be done in many real-life board games.

Yours,
Christian

Very helpful. Need some clarification.

I understand the PlayerSide property - it’s available in the expression builder. I don’t understand what you mean by Side. There is no such property and I’m not sure what you mean for its use. Or what kind of variable it is. Or how it’s assigned. Do you mean the RestrictedAccess trait?

OK, I got a piece to toggle between visible image and hidden image using a dynamic property defining side and the comparing that to PlayerSide. I had to read the instructions on ?:!!#ponytail to figure out your playerside expression. Not sure if this is what you had in mind, but it works. I can now hotseat and see a piece visible/hidden based on who player is. Huge breakthrough.

thanks!

Alrighty, got this all to work. I place a piece owned by player A as player A. I switch to player B. I bring in scout piece and it reveals Player A’s hidden piece. Had to use Layer, Dynamic Property, Trigger Command and Global Key Command.

My only gripe is that I can’t have the Restricted Access trait on the piece that is being toggled, otherwise player B GKC has no effect. This means player B can move player A’s piece. Not a game stopper, but would be nice to enforce things.

BUT – thanks to you BOTH!

I don’t understand what you mean by Side

This is referring to the Marker property. I just arbitrary choose the name of ‘Side’ for the marker. It can be anything that makes sense but it is what is used in the layer expression. A Marker trait is like a constant that you can use in expressions.

I can’t have the Restricted Access trait on the piece that is being toggled

Position matters in the trait order. Put Restricted Access closer to the top. Something you may have to finesse to limit access to only select functions.

a drag-select over the piece, it will be revealed by an outline around the invisible piece

Not seeing that that is the case, no outline visible. Band select does select the “hidden” piece and it can be moved. This can be mitigated with Restricted Access to prevent non-owning players from moving the piece.