Creating a Battle Calculator

I’m working on a little project that has vexed me, and I wonder if anyone has some advice on how to solve my problem. I have done similar things in the past, but this one is beating me.

I have created a “battle calculator.” See the mockup image below. A player presses a “calculator” button on the toolbar. This toggles the battle calculator’s (BC) appearance, either on screen where it was before or to off-screen.

The player clicks on the attacker or defender arrow and punches in the combat points. They then press “Roll!” to get a result. (I would probably change “roll” to “show odds,” and the red die would become a button itself.) The die would change color when rolled to show feedback. When done, they dismiss the BC.

battle

The BC is not a window; it’s a single piece. The trouble with a single piece is that it is difficult to manage the little components on it. I have to create action buttons for each button, which means I must define the button areas. The real headache though is the text areas–here the 15, 6, and DR1. I have had little success in creating or positioning multiple text fields on a single piece.

Ideally, and what would make this a breeze, is if I could make the mini-components into individual pieces that are placed on a bigger piece. I call this a compound piece. I’ve done this in the past with everything isimmobile, but I can’t fix the BC to one location by its nature. People need to move it.

I had hope the mat and cargo traits would solve my problem. It’s close, but no cigar. Players can start pulling off buttons, and the BC disintegrates. I wondered if maybe I made the components immobile (via “does not stack”), then it would work. Dragging the mat around moved the immobile components too (yay!), but I could still drag “immobile” cargo off the mat–and THEN the pieces became immobile. Nuts.

In short, I wish there was a way I could glue (lock) cargo to a mat so I could treat it as one unit. I’m now stuck, and perhaps it’s impossible. Too bad if true. If anyone has any ideas, please share them, and thanks for reading my long message.

Can you explain what’s wrong with just making this a small map window with multiple immobile pieces? Seems like you’re trying to do things the hard way to me…

While there may be an easier way to implement this via a separate window, I believe his point about the need to have “sticky” counters on a mat is valid as a feature request.

I was playing around with this concept for a future module and the inability to lock a status counter to mat would be a problem…

You are absolutely correct. A map window is the way to do this, and I am an idiot. What happened is I came at it in a roundabout way and overlooked the obvious. Earlier I had solved a problem A with a solution like this, which led to a similar B, then to C, and now this. I get fixated on an approach and missed the obvious. I needed someone to press my reset button. And thanks Korval for your words because they eased the sting of my foolishness.

So yes, in this example, a window is a way to go. The trouble with it though is I become bound to a window’s rules. For example, I can’t stop a user from dismissing a window with that little x in the top corner. I can’t stop them from moving the window off the map, and I don’t know where it is relative to the map in any case. With my composite piece that looks like a window but isn’t, I control everything. I agree with Korval; it would be nice if we could lock pieces onto a mat.

And just fyi, what happens if I put a does-not-stack-immobile cargo on a mat? Does it pin the mat to the map?

It depends on trait order. If the does-not-stack trait is lower than cargo, then the cargo is frozen in place, but the mat can move away. If it’s the other way around, moving the mat also moves the immobile cargo, but if I move the cargo off the map, then it freezes itself to the map.

For a window-based solution, consider using a Map display/hide global hotkey with automation to open/close the window, so that the user is less inclined close the window themselves. Similarly, a combat calculator map button on the toolbar might be enabled / disabled automatically if that helps draw the user’s attention to the fact that the calculator is active/available.

I’m not familiar with using Cargo/Mats but in similar situations I’d consider a movement trigger that validates the move and, if invalid, initiates a “go back” send to location (to OldMap, OldX, OldY).

What sort of problems? I have done this before and while it is finicky to adjust the offsets to get the text exactly where you want it, I don’t remember any real problems.

Well, finicky then. Maybe too finicky for me. Actually, there’s another minor problem that made me uncertain it would work. I’m not sure if Vassal is meant to support multiple text label traits in the same piece, and how does Vassal tries to position text labels in this case? What’s its strategy?

In fact, I wonder about this for other traits. Do they somehow stack, or do they override each other? Defining the same property name in multiple instances of marker, dynamic property, etc I believe overrides, but I’m never sure which has precedence unless I test it.

Right now I’m fooling with restrict-command, and I have multiple instances of using it to restrict ^T (for example) in multiple restrict command instances. Do they stack or do they override each other. I don’t know yet.

Hi there,

(post edited to not hijack the thread)

TL;DR: Let pieces and module calculate odds and resolve combats automatically.

Edit: From a users perspective: Select attacking and defending pieces (Ctrl-click) and then press Ctrl-X - places battle marker (number) and odds marker. Select odds marker and then Ctrl-Y to resolve the battle - replaces odds marker with result marker. Users implement result. If you want to see it in action, I suggest you take BattleForMoscow-ch-1.0.vmod and try it out - perhaps via the tutorial.

For some of the modules I did, I chose a somewhat different strategy for battle resolutions. See

The first two has tutorials that show the usage. I plan to add a tutorial to D-Day - Smithsonian Edition soon.

The strategy is to have the module calculate odds and combat results automatically while taking the rules of the game into account.

The strategy is roughly as follows

  • Individual “battle pieces” have static properties (MarkTrait) CF and DF for Combat (or attack) and Defend factors.
  • They have the prototype BattleUnit.
    • This prototype has GlobalPropertiesTraits to add their CF or DF to the total CF or DF, respectively, via TriggerTraits.
    • The prototype has a DynamicPropertyTraits to set the current battle number
    • It can also place a Battle marker on the unit (PlaceTrait)
    • TriggerTrait to set global odds shift
    • and other infrastructure traits
  • Each “battle piece” can also calculate, via CalculatedPropertyTrait its effective CF and DF. For example, a unit in an escarpment in Afrika Korps has it’s DF doubled, or a reduced unit in Battle for Moscow has both its CF and DF halved.
  • Each unit can also determine if there’s an odds shift. For example, in Battle for Moscow if all attackers are attacking over a river hex-side, then the odds are reduced by one.
  • When a faction (player) selects attacking and defending units and trigger the GlobalKey “declare battle” - tied to the key Ctrl-X, then all selected units will get a battle marker (PlaceTrait which places a battle marker piece).
    • This then triggers each of the selected units to update the total CF and DF. Which one to update for a given piece is decided by comparing the pieces Faction property (MarkTrait) to the current phase name (via the TurnTracker). For example, in D-Day - Smithsonian Edition, Allied pieces are considered attackers if the phase name contains the (sub)string Allied, and German units are then considered defenders.
    • At the same time, any CF or DF modifiers are determined (CalculatedTrait). For example, in Afrika Korps if a defending piece is in an escarpment hex, its EffectiveDF is twice the base DF. To determine if a unit is in an escarpment, the modulle checks if the units current LocationName is in the GlobalProperty EscarpmentHexes (hex names in that string are separated by :, and the module checks if ":"+LocationName+":" appears in the GlobalProperty)
    • Odd shifts are also calculated. In Battle for Moscow, the current defending hex and current attacker hex is compared against a fixed list (GlobalProperty) of hex-to-hex edges that have a river. The module assumes an “across-river” attack, but if any attacking unit is not attacking across a river hex side, then the attack is no “across-river” (i.e., no odds shift).
    • At the end of this process, the odds are calculated and any odds shift applied. This is done by a “hidden” piece (a piece with size 1x1 with a transparent image placed at pixel coordinates (0,0)).
    • The first of the selected “battle units” then gets an odds marker added to it (PlaceTrait of an odds piece).
  • If the faction then selects the odds marker and trigger the Resolve action (tied to Ctrl-Y), then the battle marker rolls a die (or two for D-Day - Smithsonian Edition) via a GlobalKeyCommandTrait, takes the die roll and current odds and determines the combat result (CalculatedTrait).
  • The odds marker then replaces it self with a result marker

It is now up to the factions (players) to implement the result of the battle - the modules does not do that on its own.

If you want to see how the calculations goes, you can turn on Debug messages in the games preferences (FilePreferencesGame name). One can also turn off these features from the same place, in which case factions can place odds and result markers themselves.

With this strategy, the factions do not need to calculate total CF and DF themselves, and the battles results are resolved on request. The strategy can be somewhat generalised so that the underlying code can be reused across modules.

What it requires is that

  • units have proper CF and DF MarkTrait
  • Prototypes that can modify these according to the game rules. For example, in D-Day - Smithsonian Edition, the prototype armoured adjusts the CF by -1 if attacking a woods hex.
  • Global properties to look up hex features (terrain, etc.)
  • Judicial use of the the TurnTracker.

This can all be a bit challenging when using the VASSAL editor because one often needs somewhat complicated BeanShell expressions. I therefore use my Python module pywargame to do all this. In fact, since I have generally first made a Print’n’Play version of the game using LaTeX, I already have much of the information (Edit: in a machine readable format), such as unit CF and DF, unit types (infantry, armoured, artillery, etc), unit echelon (brigade, platoon, army,etc), and so on. If you want to see how I do that, you can find the sources at the below URLs

The order above is not only alphabetic but also reflects the complexity of the code (Afrika Korps is the least complicated, and D-Day - Smithsonian Edition the most. The latter has two kinds of attacks - strategic bombing, which directly effects the other kind of attack: land combat).

Sorry it got a bit long. The strategy is relatively straight forward, but the implementation does requires a bit of jumping through hoops. I’m not sure I entirely captured the thinking in the above. Anyways, take a look at one of the module above, and if you have questions, do not hesitate to ask :slight_smile:

Edit:

I have yet to play a wargame where I wasn’t able to calculate battle odds within about 3-5 seconds in my head

I’m sure people have made mistakes in calculating odds (I certainly have) giving themselves or the opponent a benefit at a crucial moment in the game. This minimizes the chance or risk of that. Also, I believe, it helps novice players get started since they need not remember all the various modifiers.

… or worth the effort to implement it.

As I say above, the whole thing can be generalised somewhat, and so the effort to implement it for a given game is really not that big - not least because I go via Python to generate the modules. However, some games (e.g., Port Stanley) has rather complex rules that will be a little more tricky to capture. But I guess if one is used to playing SPI mammoth games, calculating odds, etc. isn’t a big issue :slight_smile:

Yours,
Christian

1 Like

What’s unclear to me is what a player has to do to have this all happen. At a minimum they’d have to choose the units in a battle, but what else? What do they see, and what must they do?

1 Like

What’s unclear to me is why something like this is needed, or worth the effort to implement it.
I have yet to play a wargame where I wasn’t able to calculate battle odds within about 3-5 seconds in my head, at the longest. Seems counterproductive to expect players to click numbers into a program for something as simple as that.

I don’t know if it’s worth the effort because I don’t know what the user sees or must do. To be kind to him, RobS, I am not so much interested in what problem he is solving. I am more interested in the techniques he has developed, which I could use to solve an entirely different problem.

100% supported. Each label is drawn in order, based on the order of the traits (top to bottom in the piece definer). As long as you haven’t specified a Background color, then the labels should not interfere with each other as long as you have given them enough room.

You have complete control over where the text is placed, I still don’t understand the problem here. You can align them to the exact pixel using the Offset fields. Yes, I agree it is finicky as you need to adjust each one in it’s own trait editor without reference to the others, not sure what else we can do here given our editing structure.

I believe your original one-piece calculator should be achievable and would be a better solution that the additional window option.