New program to help set up VASL scenarios

Will Fleming

Senior Member
Joined
Apr 22, 2003
Messages
4,410
Reaction score
424
Location
Adrift on the Pequod
Country
llUnited States
If this works as described, excellent. I will try to give it a go on my two current PBEM games to see if it works.

Does it matter if some of the already in play counters are concealed? Would be great if it did for my current purposes, but it could be used nefariously (or accidentally) to find out what OB options a player selected in say a VotG scenario.

Won't matter here as my opponent already knows mine, but just thinkin'.
 

Will Fleming

Senior Member
Joined
Apr 22, 2003
Messages
4,410
Reaction score
424
Location
Adrift on the Pequod
Country
llUnited States
Update:

Looks like it got 2 of 3, but missed the AA truck from VotG27. That is a special vehicle I think, so certainly no alarm there. Russian OB (mine) found the ATG and MTR correctly. Loaded a .vlog file and seemed to work fine with that.

For ASL42, it got the British Carriers (2), but missed the others (some tanks and AC). On quick glance, scanning the German (mine) counters seemed to get all or nearly all. Loaded a .vsav for this one.
 

Pacman Ghost

Senior Member
Joined
Feb 25, 2017
Messages
590
Reaction score
298
Location
A maze of twisty little passages, all alike
Country
llAustralia
but it could be used nefariously (or accidentally) to find out what OB options a player selected in say a VotG scenario.
Bugger. It did occur to me ages ago that I could write something to find out what my opponent's concealed and HIP pieces were; the information is just sitting there in the .vsav file, unencrypted :) It's possible I might need to add something to vasl-templates along these lines, but I was mindful of the possibility of using it for cheating, but I didn't think about this feature being used to identify variable OB's :-( You could argue that the less-than-100% accuracy is a feature, not a bug :)

I've pulled the release while I have a ponder over what to do...
 
Last edited:

Pacman Ghost

Senior Member
Joined
Feb 25, 2017
Messages
590
Reaction score
298
Location
A maze of twisty little passages, all alike
Country
llAustralia
Update:

Looks like it got 2 of 3, but missed the AA truck from VotG27. That is a special vehicle I think, so certainly no alarm there. Russian OB (mine) found the ATG and MTR correctly. Loaded a .vlog file and seemed to work fine with that.

For ASL42, it got the British Carriers (2), but missed the others (some tanks and AC). On quick glance, scanning the German (mine) counters seemed to get all or nearly all. Loaded a .vsav for this one.
If you send me the .vsav files, I'll take a look.

I know there are some issues with extensions, that's a problem at my end, but VASSAL and/or VASL is doing weird things when it comes to saving pieces in the .vsav file.

Technobabble: I deserialize objects from the .vsav and look at their class to decide if it's something I'm interested in. Most of the time, pieces seem to be stored as objects of type DynamicProperty, but sometimes Hideable (this seems to happen with some 1/2" pieces), sometimes Clone, I found one piece that was stored as an object of type FreeRotator (?!) I'm probably going to make the list of recognized classes configurable, but I was sick of tracking this stuff down and just wanted to push the release out :-/
 

Pacman Ghost

Senior Member
Joined
Feb 25, 2017
Messages
590
Reaction score
298
Location
A maze of twisty little passages, all alike
Country
llAustralia
I put the two logfiles I used here.
The ASL042 scenario imported correctly for me:
9841
Did you set the nationalities beforehand? (nb: the extra British 51mm MTR was hiding in a big stack off-board, on the right, so vasl-templates did the right thing importing it, I just missed it. This happens a lot :-/).

For the VotG scenario, it missed the SdKfz 10/5. When I open this scenario in VASSAL, I can see this piece, but I can't find it anywhere in the counter tray, so I'm not sure where it's coming from :-/ The analysis actually detected this piece (GPID 5341), but because it's not defined anywhere in the vasl-template data files, it couldn't create an entry for it.

On the VotG, not sure if you meant to include MOL-P info, but that might have been missed by the scan too.
Only vehicles and ordnance are imported. MOL-P's are not defined in the data files, so no entry will be created for it.
 

Will Fleming

Senior Member
Joined
Apr 22, 2003
Messages
4,410
Reaction score
424
Location
Adrift on the Pequod
Country
llUnited States
ASL042: Ahh, that was it then. I needed to set "British" for the nationality first. IIRC, "Russian" nationality found (2) types of carriers.

VotG27: I asked about the MOL-P as I suspected that was an unusual counter, similar to the German AA truck and also due to the fact that the small/SW 50mm Russian MTR showed up.

Looks like it is working quite well.
 

Pacman Ghost

Senior Member
Joined
Feb 25, 2017
Messages
590
Reaction score
298
Location
A maze of twisty little passages, all alike
Country
llAustralia
"Russian" nationality found (2) types of carriers.
Yes, I confirmed that and while that shouldn't normally happen, this a weird corner-case. These vehicles are available to the Russians as Lend-Lease, so the code considers them to be "Russian" vehicles, hence importable.

also due to the fact that the small/SW 50mm Russian MTR showed up.
Mortars, even 1/2" counters, appear in the Chapter H tables, since they have depletion numbers, Chapter H notes, etc., and so vasl-templates has to know about them. MOL-P's don't, so they're not defined in the vasl-templates data files. While it's possible to create a label with data pertaining to MOL-P's, that's done in a different way to the normal handling of vehicle/ordnance counters.

The program will sometimes detect ATR's and other small SW, for the same reason. If you can manually create an entry for a vehicle/ordnance in vasl-templates, then vasl-templates knows about it, and will import it if that counter is found in a .vsav file.
 

Sully

Senior Member
Joined
Feb 2, 2003
Messages
1,156
Reaction score
244
Location
Mpls, MN
Country
llUnited States
Technobabble: I deserialize objects from the .vsav and look at their class to decide if it's something I'm interested in. Most of the time, pieces seem to be stored as objects of type DynamicProperty, but sometimes Hideable (this seems to happen with some 1/2" pieces), sometimes Clone, I found one piece that was stored as an object of type FreeRotator (?!) I'm probably going to make the list of recognized classes configurable, but I was sick of tracking this stuff down and just wanted to push the release out :-/
I honest haven't looked at what you're doing here, and maybe you already understand how VAS(SA)L saves and loads the pieces, but I can shed some light on what you're seeing here and why.

VAS(SA)L pieces are composed of a series of traits. If you open up the VASL editor and click on a piece you can see the set of traits that piece is using [EXC: many traits are inherited via prototypes, but that can be ignored for this discussion].

Pieces are not stored as objects, but as a text string that represents the set of traits it is using. If you open up the buildFile you'll see the default text string for each of the pieces. Here's the prep fire counter as an example:
<VASSAL.build.widget.PieceSlot entryName="Prep Fire" gpid="0" height="48" width="48">+/null/prototype;DBGlobal AreaOfEffect;;30;0;true;;;Night;true;;\ label;76,130;Label;10;255,255,255;0,0,0;t;0;c;0;b;c;$pieceName$ ($label$);Dialog;0;0;TextLabel;\\ emb2;;0;;Flip;2;F;;0;;;;0;false;0;0;MS\/FirePrep,MS\/FireBnd,MS\/FireOpp,MS\/FireAdv;Prep Fire,Bnd. Fire,Opp. Fire,Adv. Fire;true;;;;false;;1;1;true;;70,130;\\\ piece;K;D; ;Prep Fire/ \ \\ 1\\\ null;0;0;0</VASSAL.build.widget.PieceSlot>

When you save a VAS(SA)L game, each piece is saved in that format, minus the XML wrapper, but including is current status (e.g. if it is flipped). Here's the important part: when you load that game VAS(SA)L fires off a command for all pieces in the save file, and for every trait possessed by each piece. Each of these are recreated in VAS(SA)L by creating a Command object for that trait. VAS(SA)L listens for these commands and uses them to recreate each piece.

If you want a fail-safe way to know what's in a save file you want to listen for these commands when the file is loaded and then inspect the command text to get the details you need to add your setup data. Again, I don't know what you're doing under the covers, but it seems you need to find the command that identifies each piece and then key off of that.

An example of how to listen for commands is located here: https://github.com/vasl-developers/vasl/blob/develop/src/VASL/build/module/map/PieceLinker.java
In this example the PieceLinker listens for the "link piece" command so it can recreate the links when the game is loaded.

If you try to inspect the piece by checking it's "object type" you're in some muddy waters. It's going to be hard to explain, but VAS(SA)L uses what's called a "decorator design pattern" where each trait "wraps" the previous trait (and therefore the previous class) as a decorator, creating an onion effect of classes within classes all the way down to the first trait. If you look at the class of a piece it's going to show you the class of the outer-most trait. That's why some pieces are "dynamic properties" and others are "free rotators:" these are all just the outer-most decorator. And if a piece changes, like someone adds a trait, your logic is going to break.

-Sully
 

Pacman Ghost

Senior Member
Joined
Feb 25, 2017
Messages
590
Reaction score
298
Location
A maze of twisty little passages, all alike
Country
llAustralia
Cool, thanks for this.

it seems you need to find the command that identifies each piece and then key off of that.
I load the scenario, then recursively walk the Command tree looking for AddPiece commands. I get the associated GamePiece and check its type to see if it's something I'm interested in.

VAS(SA)L uses what's called a "decorator design pattern" where each trait "wraps" the previous trait (and therefore the previous class) as a decorator, creating an onion effect of classes within classes all the way down to the first trait. If you look at the class of a piece it's going to show you the class of the outer-most trait.
Understood. This is the bit I was missing, and certainly explains what I'm seeing.

However, it's just occured to me that I might not need to check the object type. If I have an AddPiece command, get its associated GamePiece target, can I assume the last field in the GamePiece's state is a GPID? EDIT: It seems that I can't :-( I'm seeing Stack and Immobilized targets, which have what looks like piece ID's as their last field, not GPID's. I could perhaps ignore targets of these type, and perhaps others, but then I'm back to checking object type :-/

All I want to do is get a list of GPID's for the pieces in the scenario (the main program is able to figure out which ones are vehicles and ordnance).
 
Last edited:

Pacman Ghost

Senior Member
Joined
Feb 25, 2017
Messages
590
Reaction score
298
Location
A maze of twisty little passages, all alike
Country
llAustralia
Seeing that you're here, I'd really appreciate some feedback on the validity of what I'm doing (I posted in the VASSAL forums, but didn't get a reply). I'm worried that if I'm doing something wrong, it'll cause problems for people down the road because the .vsav file hasn't been created properly.

There are several times where I need to interact with a .vsav file:

(*) Creating labels:

I create a GamePiece from the appropriate PieceSlot (GPID 6295), replace the content fields, then add it to the game state.

(*) Looking for existing labels:

I walk the Command tree looking for AddPiece commands. I originally tried checking if the target's name was "User-Labeled", but that didn't seem to work. However, I can figure out if a label is one of mine based on its content.

(*) Get a list of GPID's for the pieces in a scenario

Similar to looking for existing labels, I walk the Command tree looking for AddPiece commands, then extract the target's GPID.
 

Pacman Ghost

Senior Member
Joined
Feb 25, 2017
Messages
590
Reaction score
298
Location
A maze of twisty little passages, all alike
Country
llAustralia
VAS(SA)L uses what's called a "decorator design pattern" where each trait "wraps" the previous trait (and therefore the previous class) as a decorator, creating an onion effect of classes within classes all the way down to the first trait.
This was the clue I needed. How's this:
Code:
for ( GamePiece gamePiece: GameModule.getGameModule().getGameState().getAllPieces() ) {
    GamePiece gp = Decorator.getInnermost( gamePiece ) ;
    if ( !( gp instanceof BasicPiece ) )
        continue ;
    String gpid = ((BasicPiece)gp).getGpId() ; // ta-da!
}
Much simpler, too :) It still doesn't work on really old save files, but I can live with that :-/

It occurs to me I should maybe walk the piece chain and use the outer-most BasicPiece, but this feature is supposed to be used on newly-created, not-yet-started scenarios, so it's probably not necessary.
 
Last edited:

Sully

Senior Member
Joined
Feb 2, 2003
Messages
1,156
Reaction score
244
Location
Mpls, MN
Country
llUnited States
If you want help from VASL developers posting here is probably the best approach. You could also get looped into the VASL development repository on Github.

The approach for finding the piece ID above looks right, although I haven't coded in a month of Sundays, so I haven't spent much time looking at your code.

I do think, if you're taking the time to add chapter H material to VASL games, it might be better to just add it to VASL itself. I.e. add a trait to pieces that would pop-up the chapter H material so you don't have to add the labels. I think it was talked about, but there were concern with including copyright material.

-Sully
 

Pacman Ghost

Senior Member
Joined
Feb 25, 2017
Messages
590
Reaction score
298
Location
A maze of twisty little passages, all alike
Country
llAustralia
If you want help from VASL developers posting here is probably the best approach. You could also get looped into the VASL development repository on Github.
These are all VASSAL issues, which is why I posted over there. I got bit by this difference before :)

I do think, if you're taking the time to add chapter H material to VASL games, it might be better to just add it to VASL itself. I.e. add a trait to pieces that would pop-up the chapter H material so you don't have to add the labels. I think it was talked about, but there were concern with including copyright material.
I did originally think about updating the VASL module, but I specifically didn't want to add a popup. I hated that I had to find the counter, then select it within the stack, then press Ctrl-I, to get a tooltip that was usually too small for me to read :-/ Hence, the tabular labels, that contain information for all your vehicles, always visible and easy to read.
9874

Plus there's support for all the other labels as well e.g. SSR's, LATW hit tables, setup notes.

For the vehicle/ordnance notes, yes, copyright is a real issue, which is why I don't distribute any of that content, people have to set it up themselves.

Anyway, thanks for the help. The code's a lot cleaner now, and I'll push out a new release soon.
 
Last edited:

Pacman Ghost

Senior Member
Joined
Feb 25, 2017
Messages
590
Reaction score
298
Location
A maze of twisty little passages, all alike
Country
llAustralia
Since it came up the other day, below are more detailed instructions on how to run this program from the source code. You might want to do this if you're not running on Windows, and it also starts much faster. Tested on Linux, should be OK on a Mac, can work on Windows but needs to be adapted (although it should be OK under WSL).

(*) The program requires Python 3, so make sure you've got that:
Code:
python3 --version
(*) Create a directory to hold everything:
Code:
mkdir vasl-templates
cd vasl-templates
(*) Create a virtual environment for Python (this lets you install stuff and keep it separate from any other Python programs you might have on your computer):
Code:
virtualenv -p python3 .venv
You may need to install virtualenv first:
Code:
sudo pip3 install virtualenv
(*) Activate the virtualenv:
Code:
source .venv/bin/activate
(*) Get the source code for vasl-templates:
Code:
git clone https://github.com/pacman-ghost/vasl-templates.git
cd vasl-templates
(*) Install the Python requirements:
Code:
pip install -e .
(*) To run the server:
Code:
XXX/.venv/bin/python \
    XXX/vasl-templates/vasl_templates/webapp/run_server.py
where XXX is the directory where you set things up. For convenience, put this in a shell script and just run that (don't forget to chmod +x it).
This will let you open scenarios that were created using the vasl-templates program.

(*) To create new scenarios, open a browser and go to http://localhost:5010/.

(*) To configure the program, edit the files in vasl_templates/webapp/config/, then restart the server.
 

Will Fleming

Senior Member
Joined
Apr 22, 2003
Messages
4,410
Reaction score
424
Location
Adrift on the Pequod
Country
llUnited States
Got the program running with images loading. Some warning messages about extensions, but I suspect that is due to the extensions.

Chapter-h looks to be working, can see images in the VASL save files and also in firefox (localhost:5010). I assume as soon as I run the script I can start VASL. Tanks much!

Edit: for those doing the config, it seems to take your 'home' directory as a start, so any directories/files you put in the config, just start from there (i.e. /home/<username> is already in there, so say vasl-templates/champter-h would go into the config file)

I think I needed to install a Quicktime Python file, but that might be my particular situation or simply a mistake by me working through this. (PyQt5 or similar) Not needed if things work for you, but in case you see some errors.
 
Last edited:

Will Fleming

Senior Member
Joined
Apr 22, 2003
Messages
4,410
Reaction score
424
Location
Adrift on the Pequod
Country
llUnited States
Here is my config file which seems to work. I use mega.nz for file storage (similar to Dropbox) so I can easily do reinstalls or keep settings consistent across multiple linux machines. I don't really hang onto the setup files for vasl-templates, so the last setting (USER_FILES_DIR) could probably be set to a better location if you hang onto yours.


[Site Config]

; configure VASSAL and VASL
VASSAL_DIR = MEGA/VASSAL/
VASL_MOD = MEGA/VASSAL_ext/VASL-6.4.4.vmod
VASL_EXTNS_DIR = MEGA/VASSAL_ext/vasl_ext/
BOARDS_DIR = MEGA/VASSAL_ext/vasl_ext/boards/asl/

; configure support programs
; JAVA_PATH = ...configure the Java executable here (optional, must be in the PATH otherwise)...
WEBDRIVER_PATH = MEGA/vasl-templates/web_driver/chromedriver

; configure your user data
CHAPTER_H_NOTES_DIR = MEGA/vasl-templates/chapter-h/
; CHAPTER_H_IMAGE_SCALING = ...optional scaling percentage for Chapter H images...
USER_FILES_DIR = MEGA/vasl-templates/examples/
 
Top