Class MutualSupportPathRanker
- All Implemented Interfaces:
IPathRanker
Four changes relative to BasicPathRanker:
- Supporting-range cohesion replaces herding: instead of a pull toward the (historical)
friendly center of mass, the unit is penalized only for ending BEYOND the effective weapons envelope
of its nearest friendly element. Inside the envelope, spacing is free - normal combat spread and
flanking cost nothing, so the force cannot collapse into a blob. The envelope is derived per friend
from its
DamageProfile, so staying supported by a short-range brawler means staying closer than staying supported by a fire-support platform. - Set-friend cover bonus: inside the threat envelope, destinations covered by the engagement envelope of a friend that has already moved (a set base of fire) rank above uncovered ones, so the covered advance is the best advance and a lone splinter push is the worst one - but still an advance.
- Uniform closing tempo: the aggression term scores the remaining gap to the unit's own peak engagement range in TURNS AT ITS OWN SPEED rather than raw hexes, so a 3/5 assault and a 6/9 medium share one commit tempo (a full move closes one turn's worth for either), and each unit closes to its own band - brawlers to knife range, fire-support to its optimum - not blindly to contact.
- Combat posture at water: a defending force does not cross the water it is defending behind -
any water, fords included, since a fordable river is one the enemy can cross anywhere. Whether the
force is attacking or defending is set explicitly in
BehaviorSettings, or read each round from the mission and the enemy's movement (PostureResolver); a defender's crossing paths are charged a full turn of advance, so it holds its bank and fights the enemy in the water instead of wading into the same trap (seecalculatePosturePenalty).
The rule that must always hold: keeping formation never stops a unit closing with the enemy. Two things
enforce it. The cohesion term charges nothing for a path ending inside the force's formation, and the centre
travels with the force,
so advancing as a body is free however fast the body moves - what the term costs is leaving the force
behind. And the penalty is bounded: it can never exceed what a turn's advance is worth, however far out of position
a unit is (see maximumFormationPenalty). Cohesion therefore chooses between ways of closing.
Where "advance as a body" stops being possible, the doctrine gives way. Terrain that a force can only
pass a few units at a time - a river ford, a bridge, a city gate - makes someone go first, and going first means
leaving the formation. Two things keep that from stalling a crossing: the bound above, and FormationSide,
which stops a force split by deep water being measured against a centre sitting in the river. Measured on a river
crossing at default settings, one turn charged 13.7 against crossing where a whole turn of advance is worth 37.5 -
better than a third of a turn, given up to hold a formation - and companies hesitated at the bank a round at a
time. This does not make a crossing free: water entry piloting risk and wading cost are far larger than either
figure and still argue against it. It stops cohesion being the term that decides.
An earlier version instead exempted any closing path from cohesion entirely. That sounded like the same guarantee and was much weaker: during an approach nearly every path closes, so cohesion switched off for exactly the phase where formation matters. Measured, a company handed a formation 10.5 hexes tighter than its opponent's had given almost all of it back within four rounds.
-
Nested Class Summary
Nested classes/interfaces inherited from class megamek.client.bot.princess.BasicPathRanker
BasicPathRanker.FiringPhysicalDamageNested classes/interfaces inherited from class megamek.client.bot.princess.PathRanker
PathRanker.PathRankerType -
Field Summary
Fields inherited from class megamek.client.bot.princess.BasicPathRanker
bestDamageByEnemies, blackIce, ESTIMATE_NOISE_MARGIN, FACING_MOD_MULTIPLIER, HOLD_CREDIT_ATTACK_CAP_FACTOR, HOLD_CREDIT_DEFEND_CAP_FACTOR, LOG_DECIMAL, LOG_PERCENT, REPRESENTATIVE_TO_HIT, TEMPO_REFERENCE_MP, THREAT_CONTACT_RANGE -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionprotected doublecalculateAggressionMod(Entity movingUnit, MovePath path, Game game) Uniform closing tempo, replacing the raw-hex aggression scoring.protected doublecalculateMutualSupportMod(Coords friendsCoords, MovePath path) Mutual-support modifier, replacing the herding pull toward a center-of-mass point.Records why the doctrine scored this path the way it did, as extra TSV columns.protected intformationRadius(Game game) How far from its centre of mass the force may spread, in hexes.protected SupportEnvelopegetSupportEnvelope(Entity entity) Returns the given unit'sSupportEnvelope, cached for the round because computing one walks the unit's whole weapon list and a company turn asks about every unit repeatedly.Methods inherited from class megamek.client.bot.princess.BasicPathRanker
attackerMovementDamageDiscount, calcDamageToStrategicTargets, calculateAerospaceMod, calculateCloseRangeIncentive, calculateCrowdingTolerance, calculateFacingMod, calculateMovementMod, calculateOffBoardMod, calculatePositionHoldMod, calculateSelfPreservationMod, checkBlackIce, checkPathForHazards, distanceToClosestEnemy, evaluateAsMoved, getBraveryMod, getPSRList, hexProperties, incomingFireTerrainDiscount, initUnitTurn, isExtremeRange, isLosRange, isWithdrawing, rankPath, rankPaths, resolvedPostureFor, resolvePostureMethods inherited from class megamek.client.bot.princess.PathRanker
calcAllyCenter, calculateAlliesCenter, calculateMovePathPSRDamage, distanceToHomeEdge, findClosestEnemy, findClosestEnemy, getBestPath, getMovePathSuccessProbability, getOwner, getPathRankerStateMethods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface megamek.client.bot.princess.IPathRanker
findClosestEnemy
-
Constructor Details
-
MutualSupportPathRanker
-
-
Method Details
-
getSupportEnvelope
Returns the given unit'sSupportEnvelope, cached for the round because computing one walks the unit's whole weapon list and a company turn asks about every unit repeatedly. Overridable for tests.- Parameters:
entity- the unit whose envelope is wanted- Returns:
- the unit's engagement envelope; zero ranges for a weaponless unit
-
calculateMutualSupportMod
Mutual-support modifier, replacing the herding pull toward a center-of-mass point. Positive values (a penalty for ending outside the force's formation) are subtracted from the path utility like the stock cohesion modifier; negative values are the set-friend cover bonus.The rule: ending inside the formation costs nothing, and the formation travels with the force, so moving with your own force is always free - mutual support selects among advancing paths, it never vetoes the advance.
- Overrides:
calculateMutualSupportModin classBasicPathRanker- Parameters:
friendsCoords- the stock ally anchor; unused - the formation centre is computed from live positionspath- the movement path being evaluated- Returns:
- the mutual-support modifier (subtracted from utility; negative values are a bonus)
-
doctrineScores
Records why the doctrine scored this path the way it did, as extra TSV columns.The modifier totals alone cannot answer "why did the bot do this". These are the inputs behind them: where the force's formation actually was, how wide it was allowed to be, how far outside it this path ended, and how many friends covered the destination. Note that the stock
friendsCoordscolumns record the heat-map anchor, which this doctrine does not use -formationCentreis the point it actually measured against.- Overrides:
doctrineScoresin classBasicPathRanker- Returns:
- named values to record alongside the path's modifiers
-
formationRadius
How far from its centre of mass the force may spread, in hexes.Deliberately the same figure
MutualSupportDeploymentuses to place the force in the first place, so movement holds the formation deployment handed it rather than inventing its own idea of one. Cached per round: computing it walks every unit's weapons. Overridable for tests. -
calculateAggressionMod
Uniform closing tempo, replacing the raw-hex aggression scoring. The remaining gap to the unit's own peak engagement range is measured in turns of movement at the unit's own speed, so every element of the force shares one commit tempo: a full move closes one turn's worth whether the unit walks 3 or runs 9. Zero once inside the band - nothing pulls a fire-support unit past its optimum toward point-blank range.A laid defense does not pay tempo. Once the enemy is inside contact range and the force's posture is DEFEND, the enemy is coming to us: the closing charge that keeps an attack from dithering would here bleed the defender off its firing positions one hex at a time - measured as the biggest payer in 40% of the defender's remaining two-steps after the attacker-movement fix. Out of contact the charge stands, so a defending force still closes ranks toward its line instead of scattering. The gate reads the unit's CURRENT distance, not the path's, so every candidate path of the pass sees the same flat field.
- Overrides:
calculateAggressionModin classBasicPathRanker- Parameters:
movingUnit- the unit being movedpath- the path being evaluatedgame- the current game- Returns:
- the aggression modifier (subtracted from utility)
-