Vassal 3.4 Release Notes

In addition to many bug fixes, stability improvements, and performance enhancements, we’ve also added more new features to Vassal 3.4 than we have added in a while. This article will give you a quick tour of the new features, as well as listing some significant player-facing bug fixes.

New Features

New Expression Builder Functions


Expression Builder Improvements

Many new methods are supported in Expressions. The Expression Builder is a good tool for finding them. Some, such as the string and math methods simply make it easier to use the Java string and math methods which were always accessible previously. Others, such as the Random and Count families are genuinely new. Some of the fun ones described in the table below:

Method Description Method Description
Random(X) Random number between 1 and X Random(X,Y) Random number between X and Y
IsRandom() True 50% of the time IsRandom(p) True p% of the time
Count("{expr}") Number of pieces matching expression on all maps Count("{expr}", "Map") Number of pieces matching expression on specified map
PropertyName.contains("String") True if PropertyName contains “String” Math.abs(NumericProp) Absolute value of numeric property

HTML Chat Log


Chat log w/ colors, bold, italic, and images!


Enabling HTML support in Global Options

VASSAL’s Chat Log now features HTML support, which means that your Report Action traits can now use <b>..</b> tags to create bold text, <i>..</i> to create italics, <span>..</span> tags for custom styling, and <img src="image.jpg"> tags to display images, like the dice shown at left.

“Quick Colors” are also available by using a special character as the very first character in a line: ! for green, ? for pink, ~ for red, and ``` (back apostrophe) for purple.

In order to take full advantage of this feature for your module, you will need to check the Enable HTML Support in Chat Log option in the Global Options of your module (in the Editor, scroll down to the [Global Options] component and open its Properties). This is to maintain compatibility with existing modules which may already have e.g. < symbols in text messages, that would otherwise be misinterpreted as HTML.

Editor “Search” Function


Searching in the Editor

Starting with VASSAL 3.4 the Editor has a Search function: Ctrl+F or select Search from the Edit menu. You can search for the names of individual components or optionally the names of classes (component types). Presently you cannot search for Traits within a piece or prototype, but this may be supported in a future version.

Editor Documentation


Better Online Docs

The online documentation has been substantially improved and updated. All of the screenshots and articles should now be “current to Version 3.4”. Comprehensive documentation on the new Chat Log and other new features has been provided. There is also substantially more information on Trait ordering available in the Game Piece article. These documentation updates will eventually be rolled out to the Wiki and other locations as part of an ongoing effort.

Band Select controls in Does Not Stack


Band Select Controls

The Does Not Stack trait now contains an additional field which gives module designers separate control over whether a piece can be selected with a band-select (dragging a lasso or box around a group of pieces). This can be used, for example, to automatically filter out minor markers from band-selects (leaving only “real” units), or to filter out large stationary “pieces” that are used to denote the position of provinces on the map. A piece with band-select disabled can still be selected by clicking directly on it, meaning that such pieces can still have functional right-click context menus.

Movement Trails controls


New Movement Trails Controls

The Movement Trails trait now offers additional key commands, so that traits can be turned explicitly to the ON or OFF state, rather than merely toggled. Likewise the movement trail history of a piece can be cleared directly. These additional controls are intended to make it easier to implement Global trails on/off buttons e.g. on the Toolbar.

Menu Separator Trait


Menu with separators

A new Menu Separator trait is available for Game Pieces. Adding a Menu Separator puts a horizontal bar in the piece’s right-click context menu, so you can add these to your modules to provide better organization. The Menu Separator trait includes a Key Command field, which indicates only when the Menu Separator should be hidden from the menu – in other words you can assign it the same key as another trait, and if that trait is hidden the separator will also be hidden.

Game Piece Palette Scaling


Scaling for Palettes


Scaled pieces in a nice compact piece palette

The Game Piece Palette, as well as its [Panel] and [List] sub-components, now accept a scale (“zoom”) factor at which pieces within should be drawn. This can allow more usable, compact graphics in a piece palette, so that you can get more use out of valuable screen space (and won’t be dependent solely on scrolling lists).

User Interface Improvements

Menu Click Location

Beginning with VASSAL 3.4.0, two new properties are exposed on Basic Piece: ClickedX and ClickedY. These record the location, in map coordinates, of the exact location of the mouse the last time it was used to bring up the context menu (in other words, normally a Right Click, though on certain platforms other methods are possible). An example of use: imagine a large immovable piece that represented the area of a province or country. Right clicking on e.g. “Czechoslovakia” now leaves a record (in the Czechoslovakia piece) of precisely where the click occurred, so that if the menu item were to place a new piece it would be able to then move the piece to the exact click location.

Undo hotkey

The Undo button can now be assigned a hotkey (e.g. Ctrl+Z) by a module designer.

Mouse-over Stack Viewer Overlap

The Mouse-over Stack Viewer now offers an option to find all pieces overlapping the mouse location (rather than only pieces matching the precise location of the top piece found).

Resign Button Flow

The Resign (aka Switch Sides) button now has a streamlined flow. It is in particular designed to make switching sides in “Hotseat” games faster, and will offer “successive defaults” for that purpose. In most cases during “Hotseat”, pressing the shortcut key for the Resign button and then Enter will be all it takes to switch to the next player’s point of view – this removes three mouse clicks from the former flow.

Mac Interface modernization

In previous versions of Vassal, the Mac version did not use modifier keys in the recommended way. VASSAL 3.3.3 corrects that for the default interface: the Command key will now be the normal “shortcut” key, and will automatically map to shortcuts that on other platforms are mapped to the Ctrl key. Likewise if a module designer on a Mac gives a piece the Command+X shortcut, it will be shown as Ctrl+X on other platforms. Likewise, Command + Left Click on a piece will toggle that piece in and out of a selection. Meanwhile, the Control key on Mac is now set to do what it is normally supposed to do on Macs: to function as a way to generate a “right click” using the main mouse button.

For players who over the years have become “trained” to “The Old Way”, there is a preference offered to restore the “Legacy” controls, which will restore the behavior of 3.2.17, etc.

We’ve pulled back, at least for now, the Mac Interface modifications that we trialed in 3.3.3-beta1.

Center on Opponent Moves always a player preference

In the past, the module designer controlled whether “Center on Opponent Moves” was a player preference or was “always on” or “always off” for a module. This led to lots of confusion, annoyed users, mystified module designers, etc. So we bid all that adieu! From Vassal 3.4.0, “Center on Opponent Moves” is strictly a player preference – it will appear in the main preferences tab for every module.

Ctrl+Mousewheel Zooms In & Out on Maps

If a Map has a “Zoom Capability” component, then Ctrl+Mousewheel will now zoom in/out in addition to the other normal ways of zooming in and out.

SVG Art File dimensions

Previously VASSAL only supported SVG files if their dimensions were given in “px” (pixels). As of 3.4.0, SVG files with any of the standard “fixed” dimensions are supported (e.g., “pt”, “cm”, etc).

Notable Player-facing Bug Fixes

Although there are many many bug fixes and performance improvements in VASSAL 3.4.0, the following is a list of some of the more important ones for module designers and players:

  • “Undo” substantially cleaned up, with at least two major bugs fixed. The Undo button’s code is now quite solid. For those who’ve been afraid to use the Undo button in their online play, give it another try!
  • Beanshell property match expressions for Global Key Commands now evaluate e.g. { Nation == “$Nation$” } correctly to match target properties w/ issuing piece properties
  • Mouse wheel scrolls help/chart/chat windows at a more reasonable speed
  • No longer possible to accidentally band-select and move the entire contents of a Deck
  • Band-select can start on an immovable piece without being improperly turned into a drag
  • Inventory Window bug drawing piece images (especially cards) incorrectly cleaned up
  • Erratic Deck “Select Specific Cards” naming behavior cleaned up
  • Ctrl + Left Click (Command + Left Click on Mac)now toggles pieces in and out of selection (rather than only deselecting)
  • Global Key Commands within a Deck now apply to the correct (specified) number of pieces, rather than “All”
  • The “Drag Threshold” was broken, leading movement of even a single pixel while “clicking” to be interpreted as a drag-and-drop operation. This is now fixed with the default threshold adjusted to 10 pixels. A Mouse Drag Threshold preference on the main VASSAL preferences tab allows this to be adjusted to suit individual users.
  • Using Java string functions in Beanshell used to require some odd workarounds such as using GetProperty("TheProperty").length() or extra parentheses (TheProperty).length(). This is no longer necessary as of Vassal 3.4.0 and you can use simply e.g. TheProperty.length(). The old workarounds will still work.

Additional Fixes since 3.3.3-beta1

  • Pulled back, at least for now, the Mac Interface changes that were trialed in 3.3.3-beta1.
  • Ctrl+MouseWheel will now zoom the map in and out (Yay sneaky new mini-features!)
  • HTML-Enable player preference for Chat Log now appears properly for pre-3.4.0 modules
  • Fixed Beanshell issues with $$ variable processing
  • Don’t print “Saving game” twice when using Save As
  • Stop logging debug messages by default
  • Added inadvertently removed throws declaration for Embellishment0.getCurrentImage()
  • BasicCommandEncoder.DecoratorFactory and BasicPieceFactory should have remained public
  • Fixed NPE in KeyStrokeListener.keyPressed()
  • Multiline HTML labels no longer break toolbar alignment
  • VM Options file so that users who need to adjust e.g. D3D pipeline options have a place to put them
  • Editor: Prevent pasting a cut ancestor as its own child
  • Fixed NPE in Map.setup() when attempting to dock main map
  • Fixed NPE in FlowView$FlowStrategy.layoutRow()
  • Fixed ClassCastException: NullCommand cannot be cast to AddPiece
  • Fixed Setup stack doesn’t recover from a piece build failure
  • Fixed NPE in SendToLocation.getSendLocation()
  • Fixed NPE in MassPieceLoader$MyTreeTable.getCellRenderer()
  • Fixed Global Options icons do not update themselves properly

3.4.0: Additional Fixes since 3.4.0-beta1

  • Non-HTML text labels are now rendered directly at the required size rather than rendered at 100% and scaled
  • It is now possible to use SVG files with non-px dimensions
  • Improved save game write time
  • Editor: Additional fix for cut-and-paste
  • Prevent units in Zones setting OldLocationName incorrectly
  • Game refresher no longer incorrectly copies Marker state
  • SequenceEncoder.Decoder.copy() should uses start offset from parent
  • Don’t create new GPIDs for temporary pieceslots
  • Some characters in Text Labels were rendering poorly at 8pt on Windows in 3.3+ – made some improvements.
  • Fixed NPE in Decorator.getOutermost() caused by PlaceMarker
  • Fixed NPE in StackMetrics.merge()

3.4.1: Additional Fixes since 3.4.0

  • Chat Log less flickering when updated
  • Fixed NPE that prevented Module Extensions from being edited.
  • “NoSuchMethodError” due to change of setOldProperties() signature
  • Fixed exception in Embellishment.getProperty() (was affecting Luftwaffe and Mage Knight)

3.4.2: Additional Fixes since 3.4.1

  • Fixed piece drag so that pieces can be moved “just a few pixels” again
  • Legacy property match expression was malfunctioning in 3.4.1
  • Chat log fails to update. Note: if it seems to still not update, make sure no spurious < characters in Report text – change to &lt;
  • Two units in same hex were not stacking properly when hex overlaps two boards
  • Fixed piece window appearing beside main map and chat pane instead of just the chat pane
  • Prevented BeanShell from interpreting 1D, 1F, 1L as numbers
  • Chat log component better filters out Alt+Key commands on Windows
  • Removed “Preference” option for HTML for Chat Log
  • Pivot was auto-reporting moves when auto-reporting was turned off

3.4.3: Additional Fixes since 3.4.2

  • Allow Module Managers from different versions to run simultaneously
  • Java 15 (up from 14) now bundled with Windows and Mac packages
  • Fixed exceptions when adding or editing items when editing an Extension on Linux or Macs
  • Clarified deprecation messages
  • Added button for toggling password visibility
  • Multiple scaling or rotation of SVG images no longer fails to compound
  • Fixed NPE in BoardPicker.getSelectedBoardNames() when changing owning Board of an At-Start Stack
  • “Bad Module Data” messages with less-than symbols no longer misinterpreted as HTML when HTML turned on in module
  • OBSCURED_BY_OTHERS property now returns null instead of a value in face down decks when tested using GKCs
  • Fixed pieces moving too fast while “Repositioning stack” in HDPI monitors
  • Use better color picker on Linux
  • Fixed VASSAL creating saveGame twice in a row when starting a log file
  • Background transparency in Text Labels fixed
  • Improved handling of loading outdated modules.

3.4.4: Additional Fixes since 3.4.3

  • Backspacing to beginning of a Key Command field will no longer shift focus
  • Using BeanShell string functions in Calculated Property no longer crashes Editor
  • Always initializes Deck on New/Load game (fixes various Deck bugs)
  • Reinstated behavior of floating point expression evaluation
  • Fixed exception in Persistent Properties
  • NegativeArraySizeException when receiving first private message

3.4.5: Additional Fixes since 3.4.4

  • Fixed problem where Module Manager’s “Show Errorlog” button went to wrong place.

3.4.6: Additional Fixes since 3.4.5

  • Dragging a card/piece off the top of a deck will no longer “also band-select”
  • At-Start Stacks (and Decks) now treat “any Board” settings properly (will appear in right place on either/any map)
  • Fixed problem where modules couldn’t be saved (involved HTML img elements in HTMLChart or Chat holding the file open)
  • Fixed NPE in GamePieceOpImpl.getTileIndices()

3.4.7: Additional Fixes since 3.4.6

  • No longer raises a bug dialog on failure to read an MP3
  • Changed backup Resource directory from temp folder to base folder
  • Restored proper (i.e., 3.2.17) relationship between Move Fixed Distance and Rotate traits
  • MacOS now uses Command as modifier key for grid-resizing, setup-stack-moving in Editor
  • Made Command+Click the select/deselect combo for MacOS (and Command+Wheel to zoom)
  • HFS+ stores filenames in NFD, so must check for that variant when loading
  • Masked card dragged from Player Hand reporting fixed
  • Fixed pieces scaled incorrectly during drags on HiDPI screens on Windows

3.4.8: Additional Fixes since 3.4.7

  • Put backup in better location when writing to module fails and ensure Editor is not left in a bad state
  • Cache grid and grid numbering painting for better performance
  • Stacks properly restore their visual ‘layer’ level when saved/restored
  • Fix reporting on oldXXXXXX properties in ReportState
  • Beanshell count function with $$ variables in Restrict Commands property match
  • Stop converting preferences last written by 3.2.7 or earlier
  • Hitting Enter in Editor expands or edits nodes
  • Hitting Enter on Module Manager opens the module
  • Inventory window no longer remains open when the game is closed in the Player
  • Mass Piece Loader - Base Image can now be loaded into layers
  • Mass Piece Loader - Decrease key now loads correctly
  • Mass Piece Loader - Layers are no longer loaded Activated

3.4.9: Additional Fixes since 3.4.8

  • Grid caching interfering with drawing zone highlighters
  • Mass Piece Loader causing exception
  • NPE in Map.placeAt()
  • AbstractBuildable.getAllDescendantComponentsOf() does not recurse properly
  • Java reports incorrect amount of RAM on Linux ARM systems
  • Grids fail to display in grid editor
  • IndexOutOfBoundsException when drawing grids over SVG

3.4.10: Additional Fixes since 3.4.9

  • 13720: Tiles in last row, column of boards with colored backgrounds and no image render too large
  • 13688: Reversed boards with grids fail to display
  • 13679: IndexOutOfBoundsException in AbstractTiledOpImpl.getTile() via GridOp
  • 13677: NullPointerException in AbstractTiledOpImpl.getTileOp() via GridOp

3.4.11: Additional Fixes & Improvements since 3.4.10

  • 13728: Translucent solid-colored backgrounds of boards were incorrectly drawn opaque
  • 13679: Fixed - IndexOutOfBoundsException in AbstractTiledOpImpl.getTile() via GridOp
  • 13677: Fixed - NullPointerException in AbstractTiledOpImpl.getTileOp() via GridOp

3.4.12: Additional Fixes & Improvements since 3.4.11

  • 13829: HexGridNumbering.getRawRow() is now public
  • 13760: Upgrade bundled Java to 15.0.1+9
  • 13850: Fixed - Piece rotation fails to apply over masking
  • 13845: Don’t display empty items in context menus
  • 13836: “Too new” version check should compare minor version only
  • 13827: Ensure that extensions are loaded in alphabetical order
  • 13826: Restore scrolling in drop-down menus in BeanShell expression builder
  • 13825: “Module from older version” check was too strict
  • 13820: Ensure temp directory hasn’t been deleted before trying to write to it
  • 13819: Move Fixed Distance updating Movement Trail correctly
  • 13808: Don’t prompt to create new logfile before current one is done
  • 13807: SendToLocation should check outer traits when evaluating expression
  • 13805: Fixed - CounterDetailViewer incorrectly displayed non-stacking pieces
  • 13795: “Too new” version check should apply to all Module Manager items
  • 13786: NPE when Enter hit in Editor component tree with no node selected
  • 13738: IllegalArgumentException because Invisible trait permitted alpha values outside [0,1]
  • 13614: NPE in ZonedGrid due to thread-unsafe caching of Zone clipping
  • 13571: ArrayIndexOutOfBoundsException in Embellishment.getProperty()
  • 13446: Fixed - Pieces in a stack have the wrong offset while dragging

3.4.13: Additional Fixes since 3.4.12

  • 13920: CounterDetailViewer should support setting no foreground color
  • 13915: Boards with same source but different grids fail to render distinctly
  • 13903: SVG with viewBox and percentage width, height renders incorrectly
  • 13861: NPE in MassPieceLoader when adding Layer to piece template
  • 13285: Show useful message on AWTError due to bad Java Access Bridge install