X-Wing module has all ship movement disabled in 3.4.x

any idea why the change from v3.3 to v3.4 would disable every x-wing ship token movements in the x-wing module? I used the AffineTransform java class to deal with translations and rotations

I do it programmatically instead of through the vassal editor traits since I can pack them all up in a compact source file and just edit values, there are lots of them related to all the kinds of movements in the game, multiplied by 3 ship size

another idea, has the placeOrMerge command been deprecated? Command placeCommand = getMap().placeOrMerge

Here’s the code for my ship movement:
github.com/Mu0n/XWVassal/blob/m … ition.java

No idea, would have to look into your custom code, understand it, try to reproduce etc. Did you do that yourself? What exactly is different?

Your code still depends on Vassal 3.2.17, I made a PR where I updated your Vengine.jar to 3.3. It’s already old and you could update it all the way to 3.4.

Also look at my other PR which fixes a possible NPE in your module.

No, Map.placeOrMerge() is not deprecated, it’s still good.


The other thing to look for is the use of unquoted $$ variables in Beanshell expressions. These can cause problems in V4 if used in Global Key Command Property Match Expressions. I can’t see any of these in your buildfile though.

Has the HotKeyConfigurer.getString method changed? That’s what I’m using to detect all my keystrokes (whether typed in manually, or fed in by my mouse interface buttons), which are verified against hard coded strings which have worked for the past 3 years.

edit - indeed, where “SHIFT 1” was used, “Shift+1” is now the detected keystroke string.

Brian will have to weigh in on this, but yes, there have been changes. HotKeyConfigurer.getString() was never designed to be used in the way you seem to be using it. You should be comparing KeyStrokes directly, or their encoded values, not the String representation of them. As well as the recent changes, HotKeyConfigurer.getString() can potentially return different things on non-English systems to what you are expecting.

If necessary, you can create a customised version of the KeyNamer component to ‘fix’ the Key display Strings the way you want, but I would look at changing the way you compare keystrokes to do it properly and compare using HotKeyConfigurer.encode() which is guaranteed to never change, or to just compare KeyStrokes directly using equals. (understand this may not be possible). You may also want to look at using NamedKeyStrokes and NamedKeyStrokeConfigurer which have replaced (and incorporate) the older KeyStroke and KeyStrokeConfigurer classes.


I’m in the process of modifying my shortkey detections and I noticed that ALT-W on Windows is trying to open a game or a continuation and pops up the file picking dialog. I’ll have to change my shortcut. Do you have a list of other brand new shortcuts I should know about? I use quite a lot of them.

Good thing I chew up ALT-W, process it, then flush it for the rest of the processes if and only if it’s done with a highlighted ship. So there’s no interference, leading me to think it was always there and I’ve never had a problem with it and will keep on never having a problem with it :smiley:

Hi Mu0n,

I was out last night and it looks like Brent already gave you correct information, but I will share some additional nuance:

  • HotKeyConfigurer.getString() is designed to return text “for display purposes”. Among other thing, those strings (e.g. “Shift”) will now start being translated into other languages. They may already be translated for users in French and Spanish, and will certainly be in upcoming versions and additional languages.
  • With the KeyStroke object you are presently passing to HotKeyConfigurer.getString(), you can instead use its getKeyCode() method to get an “int” key code, which you can then compare to e.g. KeyEvent.VK_A, KeyEvent.VK_B, KeyEvent.PAGE_UP, etc. Likewise, you can call its getModifiers() method and then use “&” to mask it against the various modifier key masks (KeyEvent.SHIFT_DOWN_MASK, etc). This will provide a much safer way of detecting specific keystrokes. A complete list of the Java keystroke names can be found here: docs.oracle.com/javase/7/docs/a … Event.html
  • Brent mentioned the KeyNamer class – that didn’t quite make it into 3.4 and is scheduled for VASSAL 3.5. It will provide an overridable interface for module designers who want to rename keystrokes, and it will have its own entry in the buildFile to make that overriding easier. But for the moment that’s in the future.

I hope this helps you get things on the right track! Let me know if you need any more information.



Thanks for the very informative nuanced post. It helps to gain a better scope of understanding about those changes.

Is it alright if I compare the .encode() method, which I’ll then pass through this Map for detection? My process was just to perform what I wanted on my PC with my keystroke, output whatever came out as a string from .encode() in the chat, and just use that in my code. I use KeyEvent stuff elsewhere successfully in my code, but it’s just slightly more painful to type in, check back, debug, etc. I have several dozens, maybe more than a hundred of those to fix.

private static Map<String, ManeuverPaths> keyStrokeToManeuver = ImmutableMap.<String, ManeuverPaths>builder()
.put(“49,65”, ManeuverPaths.Str1) //SHIFT 1
.put(“50,65”, ManeuverPaths.Str2) //SHIFT 2
.put(“51,65”, ManeuverPaths.Str3) //SHIFT 3
.put(“52,65”, ManeuverPaths.Str4) //SHIFT 4
.put(“53,65”, ManeuverPaths.Str5) //SHIFT 5
.put(“49,195”, ManeuverPaths.LT1) //CTRL SHIFT 1
.put(“50,195”, ManeuverPaths.LT2) //CTRL SHIFT 2
.put(“51,195”, ManeuverPaths.LT3) //CTRL SHIFT 3
.put(“49,585”, ManeuverPaths.RT1) //ALT SHIFT 1
.put(“50,585”, ManeuverPaths.RT2) //ALT SHIFT 2
.put(“51,585”, ManeuverPaths.RT3) //ALT SHIFT 3
…and many, many more.

And while I have you focused on the topic of translations, I’ve noticed that the v3.4.1 editor gives me tree elements in French (I live in Quebec) and while yes, it is my first language and all, I often depend on the English version in order to tutor helpers of my game module who way more often than not, will be English speakers. I’ve seen a trend in video games where this choice is forced upon us and it’s never easy to revert when you don’t want it (especially in the era of Windows Vista and 7). I poked around a bit yesterday but couldn’t find it.

The objects you find in the encode/decode process (e.g. “49,195”) will I believe be the keystrokes themselves along with their modifiers (e.g. KeyEvent.VK_1, and KeyEvent.VK_SHIFT_DOWN_MASK + KeyEvent.VK_CONTROL_DOWN_MASK, in the case of “49, 195”). So I think you’re right that the values themselves shouldn’t change.

We have, however, been talking about changing the sequence encoders (moving to more of a JSON-based format). That would likely mean that your method would then break again at that point.

So it might be better if you worked out something more along the lines of:
.put(KeyEvent.VK_1, KeyEvent.VK_SHIFT_DOWN_MASK, ManeuverPaths.Str1) //SHIFT 1

I think that would end up working out much better for you and wouldn’t be subject to “things changing later” (unless Java changed, which I think is extremely unlikely in this area!)

Meanwhile on your mention of the localized strings starting to appear in the Editor – yes there is supposed to be a preference to set your language back to English (I think it’s at least presently in the player window’s preferences, which I find a bit confusing). HOWEVER I believe there is currently a bug (in the 3.4 line) where it will use your system’s language setting and forget to check your manual preference. This is, as you point out, not desirable, and I believe is scheduled to be worked on at least in time for 3.5.


Will be probably easiest to write a small tool that scans the relevant parts of your module code and replaces these “12,34” strings with the proper KeyEvent.VK_* constants. Change the map to Map<Integer, ManeuverPaths>, and use e.g. “KeyEvent.VK_1 & KEyEvent.VK_SHIFT” as the key for this map.

It looks like the constructor for KeyStroke would work with something like this:

  new KeyStroke('1', KeyEvent.VK_1, KeyEvent.SHIFT_DOWN_MASK, false);

So you could arrange to do something like…

.put(new KeyStroke(‘1’, KeyEvent.VK_1, KeyEvent.SHIFT_DOWN_MASK, false), …wherever this goes…) //SHIFT 1

To put it into some form you want to keep it around in. I believe the last parameter will always be false for your cases, unless you get into funky things.

Thanks, I appreciate the help and the warning about things to come.

Cattlesquat has it; a Java map can only mix 1 key to 1 value, the key modifiers would be out of place. It all has to go into one object, the keystroke and that constructor is how to do it.