Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated & Fixed Required Combat Team Calculations; Reworked Combat Team Requirement Contract Pay Modifiers; Added Contract Difficulty Modifier #5664

Merged
merged 8 commits into from
Jan 15, 2025

Conversation

IllianiCBT
Copy link
Collaborator

@IllianiCBT IllianiCBT commented Jan 6, 2025

Updated how we calculate the number of combat teams required by a contract.

  • Now, it is no longer possible for contracts to require more ComTs than the campaign commander can support.
  • Aerospace will not be ignored if the Legacy AtB option to not use ASF is disabled (this option doesn't impact StratCon, so ASF being ignored here was a legacy implementation no longer relevant).
  • Improved how we handle non-IS campaigns, so that we are no longer assume the campaign uses base-3 at the company-level. This will mainly benefit ComStar and WoB campaigns, as they're the only base-2 company-level factions I'm aware of.
  • Replaced all instances of "RequiredLances" with "RequiredCombatTeams" to improve clarity and consistency with current terminology.
  • Improved JavaDocs for updated methods.

Fix #5713, Fix #5737

Replaced all instances of "RequiredLances" with "RequiredCombatTeams" to improve clarity and consistency with terminology. Updated related calculations, method names, variables, and documentation to reflect the new naming convention, ensuring compatibility across the codebase.
@IllianiCBT IllianiCBT added AtB StratCon Bugs relating strictly to StratCon Legacy Improvement Improves a legacy setup's handling. labels Jan 6, 2025
@IllianiCBT IllianiCBT self-assigned this Jan 6, 2025
@codecov-commenter
Copy link

codecov-commenter commented Jan 6, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 10.20%. Comparing base (b754106) to head (073c9d1).
Report is 79 commits behind head on master.

Additional details and impacted files
@@             Coverage Diff              @@
##             master    #5664      +/-   ##
============================================
+ Coverage     10.19%   10.20%   +0.01%     
- Complexity     6066     6076      +10     
============================================
  Files          1010     1010              
  Lines        139356   139316      -40     
  Branches      20450    20450              
============================================
+ Hits          14207    14222      +15     
+ Misses       123773   123720      -53     
+ Partials       1376     1374       -2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Cleaned up a redundant HTML closing tag in the method documentation. This improves code clarity and adheres to proper formatting standards. No functional changes were made.
@Setsul
Copy link
Contributor

Setsul commented Jan 6, 2025

Code looks fine, though I'm not sure if some of the changes are good or even necessary, and at least doesn't do what you intended, if I'm not mistaken.

  • Now, it is no longer possible for contracts to require more ComTs than the campaign commander can support.

This has knock-on effects and means the "adjust contract payment for deployment limits" campaign option has no effect anymore.
It was intentionally possible for the theoretically required Lances, now ComTs, to exceed the deployable number. The number actually required by the contract was still capped at the deployment limit, with payment proportionally reduced if the deployment limit was lower and the option for it was enabled.
Hard-capping even the theoretically required number at the deployment limit would remove the (optional) penalty for vastly exceeding what the campaign commander can support.

This is not a fix or an update, it's an actual rule change and should be discussed further before merging.
If the rule change is confirmed, the campaign option made inoperaple by this change and its associated code should be removed in the same PR.

  • Improved how we handle non-IS campaigns, so that we are no longer assume the campaign uses base-3 at the company-level. This will mainly benefit ComStar and WoB campaigns, as they're the only base-2 company-level factions I'm aware of.

I can see the theoretical argument for not requiring a company-size (12 units) ComStar/WoB force to keep 2 ComTs deployed at all times, since unlike an IS-based company with three 4 unit Lances they'd have to keep their two 6 unit Level IIs in the field 24/7, but once again this has further effects and is effectively a rule change.
By requiring C*/WoB forces to only deploy half (+-variance) of their units instead of two thirds, they gain an advantage that isn't really supported by the lore or rules.
A Clan Binary would run into the same problem, and the fix for that is "don't do that" since a Trinary handles the 2/3 deployment requirement just fine.
Since C*/WoB do not officially use 12 unit companies and Level IIIs consisting of six Level IIs can handle the 2/3 requirement just fine, this seems like a solution in search of a problem.

Also, while you'd expect Level IIIs to be on par with battalions because they're the same size, as far as I can tell MHQ considers them to be a company equivalent.
So C*/WoB are base-6 "company"-level factions and this code will actually require those factions to deploy 5/6 of their units, which I don't think was what you had intended.

This method iterates through all combat teams in the specified campaign, ignoring combat teams with auxiliary or training roles.

Last but not least, this also has some unintended consequences.
Since the number of required ComTs is set at the start of the contract and static for its whole duration, this will let player (possibly unintentionally) change the deployment requirements and the number and size of the sectors.
What comes to mind is taking a new contract after a lot of ComTs were set to Training during a Cadre contract.

@IllianiCBT
Copy link
Collaborator Author

It was intentionally possible for the required Lances, now ComTs, to exceed the theoretically required number. The number actually required by the contract was still capped at the deployment limit, with payment proportionally reduced if the deployment limit was lower and the option for it was enabled.
Hard-capping even the theoretically required number at the deployment limit would remove the (optional) penalty for vastly exceeding what the campaign commander can support.

While true, users physically cannot assign more ComTs than the allowance determined by their campaign commander's strategy. So having contracts require more forces than this hard limit risks putting the player in a situation where they accept a contract and, without any warning, suddenly find themselves unable to actually perform the requirements of that contract.

@IllianiCBT
Copy link
Collaborator Author

IllianiCBT commented Jan 6, 2025

Since C*/WoB do not officially use 12 unit companies and Level IIIs consisting of six Level IIs can handle the 2/3 requirement just fine, this seems like a solution in search of a problem.

This is a good point. For some reason my brain was certain C* 'companies' were two Level IIs.

Removed redundant "company-level formation size" calculations and replaced them with a fixed divisor for variance and bypass logic. Simplified the calculation logic in `calculateVarianceFactor` and `calculateBypassVarianceReduction` methods to improve clarity and maintainability. Adjusted auxiliary role check in `getEffectiveNumUnits` for consistency.
@IllianiCBT
Copy link
Collaborator Author

  • Moved back to a divider of 3, instead of basing it on company-level formation sizes.
  • Removed the 'training' role exclusion from available forces. Kept the 'auxiliary' exclusion, as auxiliary roles are more likely to be static between contracts and the auxiliary exclusion was specifically requested.

The hard limit of whatever the user has set up for maximum formations per Strategy is retained, because this is necessitated by the inclusion of that campaign option. Whether that campaign option should be removed is a discussion for another day and not within the scope of this PR.

@Setsul
Copy link
Contributor

Setsul commented Jan 6, 2025

It was intentionally possible for the required Lances, now ComTs, to exceed the theoretically required number. The number actually required by the contract was still capped at the deployment limit, with payment proportionally reduced if the deployment limit was lower and the option for it was enabled.
Hard-capping even the theoretically required number at the deployment limit would remove the (optional) penalty for vastly exceeding what the campaign commander can support.

While true, users physically cannot assign more ComTs than the allowance determined by their campaign commander's strategy. So having contracts require more forces than this hard limit risks putting the player in a situation where they accept a contract and, without any warning, suddenly find themselves unable to actually perform the requirements of that contract.

Yes, the AtB rules already prevent that.
If the deployment limit was 3 and a contract theoretically required 6, the contract would show as requiring 3.
With the option to reduce payment enabled, the payment would be reduce by 50%.

If you broke that by changing the rules and are now introducing a fix for it that changes the rules further and renders a campaign option inoperable, it should be split off and discussed instead of just plowing ahead.
In Saturday's Nightly the contract requirements actually seem to be capped at 2/3 of the deployment limit, which is already not good, so please take a moment to consider all of these changes before making it worse.
As it is, you are orphaning this code in AtbMonthlyContractMarket.java

        if (requiredLances > maxDeployedLances && campaign.getCampaignOptions().isAdjustPaymentForStrategy()) {
            multiplier *= (double) maxDeployedLances / (double) requiredLances;
        }

The hard limit of whatever the user has set up for maximum formations per Strategy is retained, because this is necessitated by the inclusion of that campaign option. Whether that campaign option should be removed is a discussion for another day and not within the scope of this PR.

That is an different campaign option and not what I was talking about.

  • Removed the 'training' role exclusion from available forces. Kept the 'auxiliary' exclusion, as auxiliary roles are more likely to be static between contracts and the auxiliary exclusion was specifically requested.

I'm not entirely up-to-date, but I think roles are reset to Reserve upon accepting a contract, so there's still some suboptimal interactions here.
It might be worth considering to treat auxiliaries like convoys instead, with the "role" set in the TO&E. If they do not factor into deployment requirements and already can't be deployed like other ComTs, they probably shouldn't be handled in the same way as normal ComTs.

@IllianiCBT
Copy link
Collaborator Author

IllianiCBT commented Jan 6, 2025

That is an different campaign option and not what I was talking about.

Would you be able to clarify what campaign option you're referring to, I think that's a point of confusion.

@Setsul
Copy link
Contributor

Setsul commented Jan 6, 2025

That is an different campaign option and not what I was talking about.

Would you be able to clarify what campaign option you're referring to, I think that's a point of confusion.

"Adjust contract payment for deployment limits" as checked by isAdjustPaymentForStrategy().
I have quoted the exact name, explained what it does, and shown you the code that implements it. I can not clarify any further than this.

@IllianiCBT
Copy link
Collaborator Author

IllianiCBT commented Jan 6, 2025

Sorry, the way you presented things made it seem like you were still discussing the cap on deployable ComTs based on Strategy. Or, at least, that's how I read it, leading to the confusion.

@Setsul
Copy link
Contributor

Setsul commented Jan 6, 2025

I was not "still discussing the cap on deployable ComTs base on Strategy" because I never even started discussing that.
And I just noticed I actually swapped a word, which didn't helped. Edited now.

This has knock-on effects and means the "adjust contract payment for deployment limits" campaign option has no effect anymore.
It was intentionally possible for the theoretically required Lances, now ComTs, to exceed the deployable number. The number actually required by the contract was still capped at the deployment limit, with payment proportionally reduced if the deployment limit was lower and the option for it was enabled.

To clarify this: It was always possible for requiredLances to be larger than maxDeployedLances without causing an issues because the number of "lances" required by the contract to be deployed was always capped at maxDeployedLances.
Yes, I do blame the variable naming here.

@IllianiCBT
Copy link
Collaborator Author

Closing pending rethink

@IllianiCBT IllianiCBT closed this Jan 6, 2025
@Setsul
Copy link
Contributor

Setsul commented Jan 6, 2025

Sorry about the confusion, I really bungled the first explanation, and I have to apologize for attributing a bug to you that has actually been around for months.

For what it's worth, I do completely agree with the goals.
It must be possible to actually fulfill the contract with the TO&E and commander you had when the contract was generated.

Capping the number of ComTs required to be deployed by the player at the maximum that can actually be deployed is entirely correct.
It seems that the bug I complained was actually introduced in 50.01 and predates this PR. calculateRequiredCombatTeams should calculate the requirement only based on the TO&E, the clamping to the maximum deployable number happens later.
My best guess is that it was introduced here d478f7c

As far as I can tell, and I've not had the time to go through all of the code, what is happening is that there's 3 different levels of required ComTs.

  1. Theoretically required only due to the size of the TO&E, as calculated by calculateRequiredCombatTeams without variance.
  2. Required by the contract, as calculated by calculateRequiredCombatTeams with variance.
  3. Actually required of the player, the minimum of 2. and the number that can actually be deployed.

It is important that 1 and 2 can actually be different, because this affects the payment multiplier. Contracts with higher than average deployment requirements pay better than average.
3 only comes into play if the optional setting to restrict the maximum number of deployed ComTs based on the commander's strategy skill is active and automatically clamps the requirements that are shown and used to prevent impossible contract. This does not affect what is internally saved in a contract as the required number. This is also important because it means if the commander's strategy skill is increased before the contract is accepted, the shown requirement will rise to the new deployment maximum.
With yet another optional setting, the payment is further adjusted just like with 1 and 2, if the clamping is actually necessary.

The payment adjustment for being unable to deploy as many ComTs as the employer would like, and the required number automatically rising to the new deployment cap as the strategy skill is increased (or settings are changed) were broken by commit d478f7c and have not been working since 50.01, if I'm not mistaken.
Additionally this also means that the required number of ComTs won't rise to their uncapped limit anymore if that setting is disabled.
Either way, it should be fixed. It's technically unrelated to this PR, but this PR does touch those methods so in the interest of not forcing a merge conflict, it should probably be bundle into one PR or at least coordinated.

Back to the actual PR:
-Contract requirements must be achievable.
-ASF should indeed be counted.
-Auxiliary units probably shouldn't be counted, to avoid unrealistic deployment requirements. E.g. a standard 3 lance mek platoon with an attached lance of artillery, 4 units of infantry, and 4 conventional fighters can not realistically be expected to have 4 ComTs of 4 units each in the field at all times, since 12 out of 24 units are only meant to be used as reinforcements.
BUT
Contract requirements and payments should preferably be based purely on TO&E (and commander strategy skill) and not change based on something the player can, accidentally or not, change at any time at no cost.

Hence my initial idea of flagging auxiliary forces in the TO&E like support forces and convoys. If we don't want to change or add rules we shouldn't make things too complicated like counting the a different percentage of equipment value for auxiliary vs main combat forces, but I'm still leaning towards counting for contract payment purposes.
Yes, that means players could still artifically lower the contractual deployment requirements by declaring all of their forces to be auxiliary before a contract and then reverting after accepting one, but at least it won't happen accidentally.

There is however an argument to be made for not counting auxiliary forces for payment because they already offer an advantage: Making it easier to win scenarios.
If auxiliary forces do not count towards deployment requirements, why would an employer be willing to pay more for a company that won't fight any more battles than one without those auxiliary forces? In gameplay terms, why would we offer a way to make things easier while at the same time increasing the reward in form of the contract payment, with no downsides? The increased payment from non-auxiliary forces is earned by having to actually field more at any given them. Auxiliaries that don't count towards deployment requirements but count towards contract payment would provide almost the same benefits without the additional obligations.

@IllianiCBT
Copy link
Collaborator Author

I do think moving auxiliary to a special TO&E status, like Convoys, is absolutely the right move. I think the whole process of determining required ComTs is actually a bit of a problem. Because it's being touched upon by so many different things, resulting in hard to understand code. That's something we should take a look at tightening up, because being frank I know the mhq codebase better than most and even I got confused several times. I dread to imagine how someone would manage if they were just reviewing a PR or taking a cursory glance. That's just asking for trouble.

@Setsul
Copy link
Contributor

Setsul commented Jan 6, 2025

I do think moving auxiliary to a special TO&E status, like Convoys, is absolutely the right move.

Yeah, I do feel strongly about contract requirements being only based on the TO&E.
Which does leave the question of whether auxiliary should count towards TO&E value for contract purposes like "normal" combat forces or not, like "other" support forces.
There's also a bit of a QoL improvement to be had, with auxiliaries that won't ever change roles gone from the assignment table in the Briefing Room.

I think the whole process of determining required ComTs is actually a bit of a problem. Because it's being touched upon by so many different things, resulting in hard to understand code. That's something we should take a look at tightening up, because being frank I know the mhq codebase better than most and even I got confused several times

To be fair, the multiple values do have a use. But they should really use more distinct variable names and the transition to the abstract market has spread them out even further so it's become way too easy to think that something with "required" in the name is an actual requirement instead of a base value that'll still be modified up to twice.

I dread to imagine how someone would manage if they were just reviewing a PR or taking a cursory glance. That's just asking for trouble.

Case in point. I thought you were going to break something, but it was already broken and no one noticed.

# Conflicts:
#	MekHQ/src/mekhq/gui/dialog/NewAtBContractDialog.java
Simplified combat team utilization calculations to directly use proportion of required to total combat teams. Removed the unused 'adjustPaymentForStrategy' option and associated logic, streamlining campaign options and related UI elements.
@IllianiCBT IllianiCBT reopened this Jan 9, 2025
Previously, the multiplier calculation did not account for cases where totalCombatTeams was zero, which could result in a division by zero error. Added a check to ensure the calculation only proceeds when totalCombatTeams is greater than zero. This improves the stability and reliability of the contract market logic.
@IllianiCBT IllianiCBT closed this Jan 9, 2025
@IllianiCBT IllianiCBT reopened this Jan 9, 2025
@IllianiCBT IllianiCBT marked this pull request as draft January 9, 2025 21:48
@IllianiCBT
Copy link
Collaborator Author

IllianiCBT commented Jan 9, 2025

Updated and Reopened PR

  • Removed check for whether a ComT is set to the Auxiliary or Training roles
  • Corrected final required ComT count to use the smallest of Max ComT and Calculated ComTs, not the highest
  • Added check to ensure a contract always has a minimum of 1 required ComT
  • Removed 'strategy affects pay' campaign option as this is now effectively included by default
  • Adjusted contract pay so that it is always based on the percentage of ComTs required by the contract. This means that pushing for more difficult contracts (i.e contracts with fewer reserves) will see increased pay. Users, on average, will see no difference in contract pay.
  • Adjusted contract pay based on the difficulty (skulls) of the contract when FG3 is enabled. For each half-skull below 2.5 (force parity) the player will see a 5% reduction in pay. Each half-skull above 2.5 will see a 5% increase in pay. This means a player facing a 5 Skull OpFor will be paid 25% better than normal.

Fix #5713

Replaced hardcoded constants with COMBAT_FORCE_DIVIDER for clarity and consistency across methods. Enhanced pay multiplier logic by incorporating contract difficulty adjustments when FG3 is enabled. Simplified and standardized variance factor calculations for better maintainability.
@IllianiCBT IllianiCBT marked this pull request as ready for review January 9, 2025 22:19
@IllianiCBT IllianiCBT changed the title Updated & Fixed Required Combat Team Calculations Updated & Fixed Required Combat Team Calculations; Reworked Combat Team Requirement Contract Pay Modifiers; Added Contract Difficulty Modifier Jan 9, 2025
Copy link
Member

@HammerGS HammerGS left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed with Co-Pilot and IDEA AI

@HammerGS HammerGS merged commit 4d9c830 into MegaMek:master Jan 15, 2025
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
AtB Legacy Improvement Improves a legacy setup's handling. StratCon Bugs relating strictly to StratCon
Projects
None yet
4 participants