Invoking Vengine.jar from another program


If you’re not already aware, I’ve written a program to create HTML labels for VASL scenarios, that’s lets you create things like this:

Discussion at Game Squad is here.

I’ve recently added a feature that takes the scenario details the user entered into my program, and invokes Vengine.jar to automatically create labels in a .vsav file (or update them if they’re already there).

A couple of things came up during the development of this…

(*) While calling GameModule.getGameModule().getGameState().decodeSavedGame() loads a .vsav file sufficiently for me to look at what’s in it (by traversing the Command tree), to be able to make changes to it, I need to execute the Command returned. However, this causes the UI to sometimes come up. I never see it in the Fedora VM I use for development, but it always comes up on Windows, so I imagine there’s a race condition between the UI starting up and my making changes to the game state and saving it out. The UI actually crashes, presumably because I haven’t initialized something, but as long as I manage to successfully make my changes and save them, I consider things to have worked.

So… is there any way to load a saved game, in such a way that I can make changes to it, without the UI coming up?

(*) To save a game, I would like to call GameState.saveGame(), but it calls getRestoreCommand(), which does nothing unless the saveGame action has been enabled :frowning: There doesn’t seem to be any way for me to get access to this object, due to Java access protections, so I had to reimplement the whole of getRestoreCommand(), and every other function it calls, with this check disabled.

Is there any chance you could add a getter for GameState.saveGame, so that I can just enable it, and then a call to GameState.saveGame() would Just Work ™…?

(*) While things seem to work, I’m a little concerned that the .vsav file I’m writing out is borked in some way because I haven’t done things properly. It would be very mch appreciated if someone could comment on my approach…

(-) Instantiate a ModuleManagerMenuManager (it seems to be needed to load VASL).

(-) Load the VASL module:

DataArchive dataArchive = new DataArchive( vmodFilename ) ; BasicModule basicModule = new BasicModule( dataArchive ) ; GameModule.init( basicModule ) ;

(-) Configure where the boards are:

Prefs prefs = GameModule.getGameModule().getPrefs() ; String BOARD_DIR = "boardURL" ; prefs.setValue( BOARD_DIR, new File(boardsDir) ) ;

(-) Load the scenario:

Command cmd = GameModule.getGameModule().getGameState().decodeSavedGame( new File( scenarioFilename ) ) ; cmd.execute() ;

(-) Look for existing labels by checking the Command and its children (via getSubCommands()), that meet the following requirements:
- must be an instance of AddPiece
- whose target is an instance of DynamicProperty
It’s state field is split into its component fields, using “\+\t” as a separator, and we take fields #3 and #4 as the label fields.

(-) To add new labels, I iterate over all the PieceSlot’s using:

GameModule.getGameModule().getAllDescendantComponentsOf( PieceSlot.class ) and look for one with GPID 6295.

I create a GamePiece, by calling PieceSlot.getPiece(), then expand the piece:

gamePiece = PieceCloner.getInstance().clonePiece( gamePiece ) ; I get the GamePiece’s state by calling getState(), replace the default values with the content I want to appear in the label, and then insert it into the GamePiece by calling setState().

(-) To update an existing label, I do something similar to the above, but using the label’s existing GamePiece object.

(-) To delete a label, I create a RemovePiece object, using the label’s existing GamePiece object, and execute it.

Is this approach valid? Is it going to cause problems for peoples’ scenarios down the road…?