Editor: Duplicating Game Piece Image causes Uncaught Exception

Steps to reproduce:

1.) Edit the RemoveUnusedImages_0.1.vmod
2.) Go to Game Piece Layouts → CounterBase → Soviet.png
3.) Right click and select “Duplicate this game piece Image”
4.) Uncaught Exception

2022-01-19 22:41:55,865 [10040-main] INFO  VASSAL.launch.StartUp - Starting
2022-01-19 22:41:55,881 [10040-main] INFO  VASSAL.launch.StartUp - OS Windows 10 10.0 amd64
2022-01-19 22:41:55,881 [10040-main] INFO  VASSAL.launch.StartUp - Java version 17.0.1
2022-01-19 22:41:55,881 [10040-main] INFO  VASSAL.launch.StartUp - Java home C:\Program Files\VASSAL-3.6.4\jre
2022-01-19 22:41:55,881 [10040-main] INFO  VASSAL.launch.StartUp - VASSAL version 3.6.4
2022-01-19 22:41:56,037 [10040-AWT-EventQueue-0] INFO  VASSAL.launch.ModuleManager - Manager
2022-01-19 22:42:32,465 [10040-SwingWorker-pool-2-thread-1] INFO  VASSAL.launch.AbstractLaunchAction - Loading module file C:\Users\marcus\Documents\Spiele\CtoSx\_Vassal\RemoveUnusedImages\RemoveUnusedImages_0.1.vmod
2022-01-19 22:42:32,511 [10040-SwingWorker-pool-2-thread-1] INFO  VASSAL.launch.TilingHandler - No images to tile.
2022-01-19 22:42:32,511 [10040-SwingWorker-pool-2-thread-1] INFO  VASSAL.launch.AbstractLaunchAction - Loading module Remove Unused Images
2022-01-19 22:42:32,527 [10040-SwingWorker-pool-2-thread-1] INFO  VASSAL.tools.io.ProcessLauncher - launching C:\Program Files\VASSAL-3.6.4\jre\bin\java -Xms512M -Xmx512M -Duser.home=C:\Users\marcus -Duser.dir=C:\Program Files\VASSAL-3.6.4 -cp lib\Vengine.jar VASSAL.launch.Player --load -- C:\Users\marcus\Documents\Spiele\CtoSx\_Vassal\RemoveUnusedImages\RemoveUnusedImages_0.1.vmod
2022-01-19 22:42:33,496 [5748-main] INFO  VASSAL.launch.StartUp - Starting
2022-01-19 22:42:33,511 [5748-main] INFO  VASSAL.launch.StartUp - OS Windows 10 10.0 amd64
2022-01-19 22:42:33,511 [5748-main] INFO  VASSAL.launch.StartUp - Java version 17.0.1
2022-01-19 22:42:33,511 [5748-main] INFO  VASSAL.launch.StartUp - Java home C:\Program Files\VASSAL-3.6.4\jre
2022-01-19 22:42:33,511 [5748-main] INFO  VASSAL.launch.StartUp - VASSAL version 3.6.4
2022-01-19 22:42:33,511 [5748-main] INFO  VASSAL.launch.Launcher - Player
2022-01-19 22:42:35,895 [5748-AWT-EventQueue-0] INFO  VASSAL.build.GameModule - Remove Unused Images version 0.1
2022-01-19 22:42:38,646 [5748-AWT-EventQueue-0] INFO  VASSAL.build.GameModule - Exiting
2022-01-19 22:42:44,626 [10040-SwingWorker-pool-2-thread-2] INFO  VASSAL.launch.AbstractLaunchAction - Loading module file C:\Users\marcus\Documents\Spiele\CtoSx\_Vassal\RemoveUnusedImages\RemoveUnusedImages_0.1.vmod
2022-01-19 22:42:44,626 [10040-SwingWorker-pool-2-thread-2] INFO  VASSAL.launch.TilingHandler - No images to tile.
2022-01-19 22:42:44,626 [10040-SwingWorker-pool-2-thread-2] INFO  VASSAL.launch.AbstractLaunchAction - Loading module Remove Unused Images
2022-01-19 22:42:44,626 [10040-SwingWorker-pool-2-thread-2] INFO  VASSAL.tools.io.ProcessLauncher - launching C:\Program Files\VASSAL-3.6.4\jre\bin\java -Xms512M -Xmx512M -Duser.home=C:\Users\marcus -Duser.dir=C:\Program Files\VASSAL-3.6.4 -cp lib\Vengine.jar VASSAL.launch.Editor --edit -- C:\Users\marcus\Documents\Spiele\CtoSx\_Vassal\RemoveUnusedImages\RemoveUnusedImages_0.1.vmod
2022-01-19 22:42:45,626 [976-main] INFO  VASSAL.launch.StartUp - Starting
2022-01-19 22:42:45,642 [976-main] INFO  VASSAL.launch.StartUp - OS Windows 10 10.0 amd64
2022-01-19 22:42:45,642 [976-main] INFO  VASSAL.launch.StartUp - Java version 17.0.1
2022-01-19 22:42:45,642 [976-main] INFO  VASSAL.launch.StartUp - Java home C:\Program Files\VASSAL-3.6.4\jre
2022-01-19 22:42:45,642 [976-main] INFO  VASSAL.launch.StartUp - VASSAL version 3.6.4
2022-01-19 22:42:45,642 [976-main] INFO  VASSAL.launch.Launcher - Editor
2022-01-19 22:42:47,960 [976-AWT-EventQueue-0] INFO  VASSAL.build.GameModule - Remove Unused Images version 0.1
2022-01-19 22:42:58,919 [976-AWT-EventQueue-0] ERROR VASSAL.tools.ErrorDialog - 
java.lang.NullPointerException: Cannot invoke "VASSAL.build.module.gamepieceimage.GamePieceLayout.getItem(String)" because "this.layout" is null
	at VASSAL.build.module.gamepieceimage.GamePieceImage.rebuildInstances(GamePieceImage.java:470)
	at VASSAL.build.module.gamepieceimage.GamePieceImage$DefnConfig.getConfigurer(GamePieceImage.java:175)
	at VASSAL.configure.AutoConfigurer.createConfigurer(AutoConfigurer.java:206)
	at VASSAL.configure.AutoConfigurer.<init>(AutoConfigurer.java:87)
	at VASSAL.build.AbstractConfigurable.getConfigurer(AbstractConfigurable.java:212)
	at VASSAL.configure.ConfigureTree$8.actionPerformed(ConfigureTree.java:894)
	at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1972)
	at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2313)
	at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
	at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
	at java.desktop/javax.swing.AbstractButton.doClick(AbstractButton.java:374)
	at java.desktop/javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:1028)
	at java.desktop/javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(BasicMenuItemUI.java:1072)
	at java.desktop/java.awt.Component.processMouseEvent(Component.java:6626)
	at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3389)
	at java.desktop/java.awt.Component.processEvent(Component.java:6391)
	at java.desktop/java.awt.Container.processEvent(Container.java:2266)
	at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5001)
	at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
	at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833)
	at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4948)
	at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4575)
	at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4516)
	at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2310)
	at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2780)
	at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:716)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:97)
	at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:746)
	at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:744)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
	at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:743)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
1 Like

Thanks - for now the workaround is to copy & paste Game Piece Image items rather than duplicate.

Yes, I do that. Or just create a new one from scratch. Usually, a Game Piece Image has only very few settings that might be altered.

Please try VASSAL-3.6.5-SNAPSHOT-86eb45c-fix_gpi_dupe_npe in the builds archive. Does that fix the problem for you?

Yes, it does no longer crash, but it is does not do a real duplication. Rather, it starts a new image from scratch. If, however, I use Copy and Paste I get indeed an exact copy. That is somewhat important if the Game piece Images get a bit more complex.

To demonstrate:

  1. Download https://redmabuse.de/vassal/RemoveUnusedImages_0.2.vmod
  2. Under Game Piece Palette → Units there is a nice looking “German_Red_Inf_4-4” Unit. Also, there is a Prepared “German_Blue_Inf_3-4” waiting for its image. I just want it to have a blue stripe and 3-4 as Combat Values.
  3. Go to Game Piece Image Definition → Game Piece Layouts → Infantry Units
  4. Select the German_Red_INF_44 and “Duplicate this Game Piece Image”

It does get created, but all the settings I made in the old piece are not there in the new piece.

If, however, I do a C&P, i get a copy where I have to change only the CV and the color of the stripe.

And two more points, when we are at it:

  1. The new image is not immediately available when selecting a picture for a layer. After creating the new image, I go to the “German_Blue_Inf_3-4” and cannot find the new Image in the Dropdown Box. I have to save and close the module and open it again.

  2. Could we have at least the dash “-” as an allowed character in Game Piece Images Names? I’d really like to name the pieces “…4-4” but the editor won’t allow me. And having the space would be nice, too. Then again, if that might break something: It’s not that important, only “nice to have”.

Thanks for testing that. What you found is what I was afraid of. I think we’ll just remove the ability to duplicate these.

1 Like

Weill there be an easy solution for images being available without a restart? That is the part that annoys me more.

I’m used to Copy and paste right now and won’t really miss the ability to duplicate.

We recently made this stricter to prevent names that can’t work as filenames, but it looks like we made it too strict. I’ll see what we can do about this.

That’s a known limitation of Game Piece Images.

1 Like

Try the current master build. That contains a change which permits hyphens and periods in the names of Game Piece Images.

2 Likes

It does so. A bit of testing did not reveal any unwanted side effects (so far), everything else works as before.

A big Thank you!

This change will go out in 3.6.5 when we release that.

2 Likes