Easy way to get Map numPieces property for trigger?

Is there any plan to implement a global calculated property or anything along those lines to allow for direct counting of pieces on a map as discussed up thread? My module has almost full rules enforcement and seems to be stable now that undo bugs have been fixed. The last hurdle is calculating area control, which I’ve been holding off on in hopes that a better solution emerges (either a feature gets added to Vassal or I came up with a creative solution). I’ve got about 200 areas, so I’m not keen on building a massive kluge of GKCs. I basically want to count how many pieces are in each LocationName by matching Properties (For instance Type==“Infantry”&&Power==“Britain”). Any possibility of an improved solution for this appearing in 2020?

Vassal 3.3.3, the one that has a few nifty feature adds around the edges, is nearing “final approach vector” and so if I suddenly showed up with a new “mini feature” PR that might be awkward. BUT, Mr. Programmer, it’s literally already sitting there in a Java variable in each Map! Custom Class, man! You gonna make me write it for you? ;)

Fine. I’ll write a Custom Class. What is the variable name though? I’ve avoided that side of things entirely.

If you look in the Map class (VASSAL.build.module.Map, so VASSAL/build/module/Map.java) you’ll find it has a method getPieces() which returns an array[] of GamePiece. So if you had your map you could reference e.g. map.getPieces().length

Flint1b put up some great stuff in the Wiki about how to get a dev environment IDE set up for Vassal (he recommends IntelliJ), and to use “git” to pull down the source, get it all building, and stuff. Once you accomplish that, adding a side project to your workspace to build a little mini-package shouldn’t be too hard (you’d just put a reference to the big Vassal project in your buildpath).

Strategies for custom-classing this… I guess you could make a new Trait that exposed the property. That’s probably the most closest to the “normal” custom class path - it just requires you learn the little “Decorator factory” pattern, though that’s at least documented in the old coding tutorial (just a little “poorly” documented IMHO - it’s kind of written for someone who has already mastered Java and knows all the famous pattern names and stuff). Or find some easy-to-override spot that has an entry in buildFile and sneak in some kind of listener that keeps a Global Property on the map updated with its current value? The one thing I don’t really recommend doing is overriding the Map class itself because it’s so big and monstrous. Or I suppose you could try overriding it just with an “almost-completely-passthrough” override… it just, you know, gives me the shakes :slight_smile:

Bang around and “drink from the firehose” for a while and then I can answer questions when you get stuck.

Heh heh heh…

Brian

Could someone who is proficient in building modules make a module that does this, and preferably only this, no huge map no nothing just this counting pieces and checking properties process? I would like to take a look at what happens inside.

For sure! I just built you two, depending on how literally you wanted me to take “preferably only this”.

(1) “Count Them Pieces” brianreynolds.com/files/Cou … ieces.vmod
This one takes you literally – it’s just a bunch of pieces and they count each other with GKC’s. Start “a game”, open the Piece Palette in the toolbar (it’s the button that says get-pieces-from-here). Drag a bunch of different-colored pieces on the map. Right click on any piece and select “Count 'em Up” from the menu, and it’ll do it. It’s a super-stripped module so it will run really fast in spite of GKC’s. I even tried putting the “Marker” traits in the hardest places for it to find but they’re just tiny little pieces on a tiny little map in a tiny little module :slight_smile:

Meanwhile, you can aspire to move up to:

(2) "For The Profile: brianreynolds.com/files/For … ofile.vmod
For this one I stripped down “For the People” – took out the map and cards and a bunch of the “fluff”, but left all the unit-related pieces in with their “real traits”. The best way to use it is… scroll a bit down and you’ll see some groups of Union and Confederate Units. Try moving them in and out of the same spaces with each other – you know, some Union in to fight the Confederates, then retreat, put a General in, etc, etc. So those are doing a lot of “real” counting (only two GKC’s per stack move though, I think) for the purpose of reorging those stacks. And they have an ass-ton of traits so they have a lot to grind through. So if you wanted to PROFILE something in a more realistic use-case situation, this is The Module For You!

Brian

Thanks! I’ll take a look.

Yeah heheheheee…

I stepped through the code and I have absolutely no idea what happens there I’ve just seen a whole lot of recursion, then I saw my old friend the PieceCloner.clone() being called to save a SNAPSHOT of a piece, then these SNAPSHOTs being evaluated, then I tried this with the version from github.com/vassalengine/vassal/pull/75 where Brent had a good idea how to improve performance and I implemented it.

Go on and try it, I think any doubts about whether this new way is more performant will be gone after you do. No technical profiling will be even needed, any human will see the difference :smiley:

Well I got as far as installing IntelliJ then starting flowcharting out exactly what needed to be done for this and I realized that a Calculated Property is probably not the best solution for this. Brian, as you previously mentioned, there are really only 2 bottlenecks for piece movement: 1) Drag 'n drop - which is already tracked at the map level and 2) Send To Location / Return to Deck. Calculated Property has the potential to be recalculated even as players just scroll and “do nothing” whereas a GKC for this would only fire when a player moves a piece. For almost all games, this is either one stack at a time or even just a single piece. I don’t see it ever being processor intensive unless a game has some sort of end of turn quartering.

For each area, I’ll potentially need 8 Global Properties (1 to track control, 1 to count units of minor powers, and 6 to count units for each player power). With 200 areas, that’s 1600 GPs. Yuck! A custom Class that calculates the equivalent of _ at the Location level would be very useful here. But then it occurred to me that if Beanshell supports Java Math, which after a little experimentation, it turns out it does… I could use the remainder and modulus operations to reduce the GP count to 1 per area by incrementing the GP by piece movement as follows (by power):

Neutrals ±1
Britian ±10
France ±100
USA ±1000
Germany ±10000
Italy ±100000
Russia ±1000000

So if Warsaw contained 3 Neutral pieces, 4 German pieces, and 1 Russian piece, its GP <Warsaw_NumPieces> would report 1040003. This of course assumes I never need to count more than 9 pieces per power per area (which I don’t). For a typical 2-player hex and counter game I’d just go with double digit counting for 2-sides, thus a range of 0000-9999 supports 99 units per hex.

From there I thought I was going to have to create a ton of inequality expressions to determine when areas are controlled or contested but it turns out Beanshell also supports String functions and someone documented it:
vassalengine.org/wiki/How_to … _in_VASSAL

This means I can parse a single GP <LocationName_NumPieces> very efficiently to determine whether an area is contested or controlled and by whom. I don’t really need to evaluate area control in real-time, only for income and building units, so I may have solved my problem. Brian - the lengths I’ll go to avoid my first class ;-)

Flint1b – I did those two git commands down there to try your PR and I couldn’t tell any difference, so I think I must have built it wrong or be on the wrong branch or something? Brian

git fetch upstream pull/75/head:Try75
git checkout Try75

Haha m3tan you are a basket case!

Had a glance at the thread. So basically a piece is unnecessarily cloned when? Every time a property is changed? Checked? If it’s the latter, that’s almost every operation in Vassal. I could see this dramatically improving Vassal performance - though I’ve been lucky to avoid any lag with Calculated Properties. The only time I see a noticeable lag is my end of turn cleanup and capitulation action (power is defeated and all pieces are removed) which both use a ton of GKCs.

One of the old Vassal multiplayer-implementation shortcuts is basically to save a copy of your piece, do some stuff to it, and then kind of “diff” the changes to send over the wire (or write in the log). So more related to changing than checking, but let’s just say there’s a lot of that.

I don’t even know, It has to do with the ReportState thing but no idea when this is used, I just found out that there was a lot of cloning when I started up a certain module, and Brent came up with the idea to not clone at all just save the piece properties for when we need to compare a piece to it’s old state.