Repository: MegaMek/mekhq
Pull request #6730: Added Option to Disable ATOW Attribute Scores
Author: login: IllianiBird
Labels: name: Personnel
description: Personnel-related Issues
name: Campaign Options
description: Relates to, or includes, campaign option changes
Created: 2025-04-22T17:09:10Z | Merged: 2025-04-23T17:10:00Z

- Added campaign option to disable ATOW Attribute scores. The tooltip includes information on how to handle ATOW Attribute score resetting in an ongoing campaign.


Diff:
diff --git a/MekHQ/data/campaignPresets/1 - New Player Preset.xml b/MekHQ/data/campaignPresets/1 - New Player Preset.xml
index f50a6264066..2a8df2949e7 100644
--- a/MekHQ/data/campaignPresets/1 - New Player Preset.xml	
+++ b/MekHQ/data/campaignPresets/1 - New Player Preset.xml	
@@ -642,6 +642,7 @@
         <commandSkillsModifier>-12,-11,-10,-9,-8</commandSkillsModifier>
         <roleplaySkillsModifier>-12,-11,-10,-9,-8</roleplaySkillsModifier>
         <randomizeSkill>true</randomizeSkill>
+        <useAttributes>true</useAttributes>
         <randomizeAttributes>true</randomizeAttributes>
         <randomizeTraits>true</randomizeTraits>
         <useClanBonuses>true</useClanBonuses>
diff --git a/MekHQ/data/campaignPresets/2 - Veteran Experience Preset.xml b/MekHQ/data/campaignPresets/2 - Veteran Experience Preset.xml
index 3ab04818a87..d2ab8154319 100644
--- a/MekHQ/data/campaignPresets/2 - Veteran Experience Preset.xml	
+++ b/MekHQ/data/campaignPresets/2 - Veteran Experience Preset.xml	
@@ -620,6 +620,7 @@
         <commandSkillsModifier>-12,-11,-10,-9,-8</commandSkillsModifier>
         <roleplaySkillsModifier>-12,-11,-10,-9,-8</roleplaySkillsModifier>
         <randomizeSkill>true</randomizeSkill>
+        <useAttributes>true</useAttributes>
         <randomizeAttributes>true</randomizeAttributes>
         <randomizeTraits>true</randomizeTraits>
         <useClanBonuses>true</useClanBonuses>
diff --git a/MekHQ/resources/mekhq/resources/CampaignOptionsDialog.properties b/MekHQ/resources/mekhq/resources/CampaignOptionsDialog.properties
index 3e46cbaf51e..26937d06449 100644
--- a/MekHQ/resources/mekhq/resources/CampaignOptionsDialog.properties
+++ b/MekHQ/resources/mekhq/resources/CampaignOptionsDialog.properties
@@ -1814,6 +1814,18 @@ lblExtraRandomness.tooltip=If checked, an additional 1d6 will be rolled per skil
   <br>\
   <br><b>Warning:</b> Due to the way experience levels are calculated, enabling this option will\
   \ more frequently have characters created with slightly lower than normal experience levels.
+lblComingOfAgeAbilities.text=Award Coming of Age SPAs \u2714 \uD83C\uDF1F
+lblComingOfAgeAbilities.tooltip=If checked, all characters will be awarded a single SPA when they turn 16.\
+  <br>\
+  <br><b>Recommendation:</b> This was balanced around the pool of SPAs being rather large, due to the addition of ATOW\
+  \ SPAs. If you are working with a smaller SPA pool, perhaps due to disabling those SPAs, you might want to leave\
+  \ this off.
+lblATOWAttributesPanel.text=A Time of War Traits
+lblUseAttributes.text=Use Attributes \u26A0 \uD83C\uDF1F
+lblUseAttributes.tooltip=If checked, characters will be generated with <i>A Time of War</i> Attribute scores.\
+  <br>\
+  <br><b>Warning:</b> If enabled (or disabled) mid-campaign, you need to navigate to the personnel tab, and (while in\
+  \ GM Mode) you should use the right-click menu to reset attribute scores for all personnel.
 lblRandomizeAttributes.text=Extra Random Attributes \uD83C\uDF1F
 lblRandomizeAttributes.tooltip=If checked, an extra d6 is rolled for each of the character's ATOW Attributes.\
   <br>\
@@ -1822,7 +1834,7 @@ lblRandomizeAttributes.tooltip=If checked, an extra d6 is rolled for each of the
   <br>\
   <br>On a roll of a 6 the Attribute is decreased by 1, and a second d6 is rolled. If that is also a 1, the Attribute is\
   \ decreased by 1 again; and so on, until 1s stop being rolled.
-lblRandomizeTraits.text=Randomize Traits \u26A0 \uD83C\uDF1F
+lblRandomizeTraits.text=Randomize Traits \uD83C\uDF1F
 lblRandomizeTraits.tooltip=If checked, a newly created character's Connections, Wealth, Reputation, and Unlucky scores\
   \ are randomized.\
   <br>\
@@ -1833,12 +1845,6 @@ lblRandomizeTraits.tooltip=If checked, a newly created character's Connections,
   <br>\
   <br>For <b>Unlucky</b> a d20 is rolled, on a roll of 1 the character's score becomes 1. A high Unlucky score is a bad\
   \ thing.
-lblComingOfAgeAbilities.text=Award Coming of Age SPAs \u2714 \uD83C\uDF1F
-lblComingOfAgeAbilities.tooltip=If checked, all characters will be awarded a single SPA when they turn 16.\
-  <br>\
-  <br><b>Recommendation:</b> This was balanced around the pool of SPAs being rather large, due to the addition of ATOW\
-  \ SPAs. If you are working with a smaller SPA pool, perhaps due to disabling those SPAs, you might want to leave\
-  \ this off.
 lblPhenotypesPanel.text=Clan Trueborn Percentages
 lblMekWarrior.text=MekWarrior
 lblMekWarrior.tooltip=What percentage of Clan MekWarriors should have a Trueborn phenotype?
diff --git a/MekHQ/src/mekhq/campaign/personnel/generator/DefaultSkillGenerator.java b/MekHQ/src/mekhq/campaign/personnel/generator/DefaultSkillGenerator.java
index 94d9e5a0a9c..09bcc9ada9f 100644
--- a/MekHQ/src/mekhq/campaign/personnel/generator/DefaultSkillGenerator.java
+++ b/MekHQ/src/mekhq/campaign/personnel/generator/DefaultSkillGenerator.java
@@ -29,6 +29,7 @@
 
 import static megamek.common.Compute.d6;
 import static megamek.common.Compute.randomInt;
+import static mekhq.campaign.personnel.skills.Attributes.DEFAULT_ATTRIBUTE_SCORE;
 import static mekhq.campaign.personnel.skills.Attributes.MINIMUM_ATTRIBUTE_SCORE;
 import static mekhq.campaign.personnel.skills.SkillDeprecationTool.DEPRECATED_SKILLS;
 import static mekhq.campaign.personnel.skills.enums.SkillSubType.SUPPORT_COMMAND;
@@ -159,6 +160,19 @@ public void generateSkills(final Campaign campaign, final Person person, final i
     @Override
     public void generateAttributes(Person person) {
         RandomSkillPreferences skillPreferences = getSkillPreferences();
+
+        if (!skillPreferences.isUseAttributes()) {
+            for (SkillAttribute attribute : SkillAttribute.values()) {
+                if (attribute.isNone()) {
+                    continue;
+                }
+
+                person.setAttributeScore(attribute, DEFAULT_ATTRIBUTE_SCORE);
+            }
+
+            return;
+        }
+
         boolean extraRandomAttributes = skillPreferences.isRandomizeAttributes();
 
         PersonnelRole profession = person.getPrimaryRole();
diff --git a/MekHQ/src/mekhq/campaign/personnel/skills/RandomSkillPreferences.java b/MekHQ/src/mekhq/campaign/personnel/skills/RandomSkillPreferences.java
index 1a686669243..54dd3fa1d3c 100644
--- a/MekHQ/src/mekhq/campaign/personnel/skills/RandomSkillPreferences.java
+++ b/MekHQ/src/mekhq/campaign/personnel/skills/RandomSkillPreferences.java
@@ -53,6 +53,7 @@ public class RandomSkillPreferences {
     private int overallRecruitBonus;
     Map<PersonnelRole, Integer> recruitmentBonuses;
     private boolean randomizeSkill;
+    private boolean useAttributes;
     private boolean randomizeAttributes;
     private boolean randomizeTraits;
     private boolean useClanBonuses;
@@ -71,6 +72,7 @@ public RandomSkillPreferences() {
         overallRecruitBonus = 0;
         recruitmentBonuses = new HashMap<>();
         randomizeSkill = true;
+        useAttributes = false;
         randomizeAttributes = false;
         randomizeTraits = false;
         useClanBonuses = true;
@@ -178,6 +180,14 @@ public void setRandomizeSkill(boolean b) {
         this.randomizeSkill = b;
     }
 
+    public boolean isUseAttributes() {
+        return useAttributes;
+    }
+
+    public void setUseAttributes(boolean useAttributes) {
+        this.useAttributes = useAttributes;
+    }
+
     public boolean isRandomizeAttributes() {
         return randomizeAttributes;
     }
@@ -186,10 +196,6 @@ public void setRandomizeAttributes(boolean isRandomizeAttributes) {
         this.randomizeAttributes = isRandomizeAttributes;
     }
 
-    /**
-     * @deprecated not in use.
-     */
-    @Deprecated(since = "0.50.05", forRemoval = true)
     public boolean isRandomizeTraits() {
         return randomizeTraits;
     }
@@ -198,6 +204,10 @@ public void setRandomizeTraits(boolean randomizeTraits) {
         this.randomizeTraits = randomizeTraits;
     }
 
+    /**
+     * @deprecated not in use.
+     */
+    @Deprecated(since = "0.50.05", forRemoval = true)
     public void setUseClanBonuses(boolean b) {
         this.useClanBonuses = b;
     }
@@ -298,6 +308,7 @@ public void writeToXML(final PrintWriter pw, int indent) {
         MHQXMLUtility.writeSimpleXMLTag(pw, indent, "commandSkillsModifier", commandSkillsModifier);
         MHQXMLUtility.writeSimpleXMLTag(pw, indent, "roleplaySkillsModifier", roleplaySkillsModifier);
         MHQXMLUtility.writeSimpleXMLTag(pw, indent, "randomizeSkill", randomizeSkill);
+        MHQXMLUtility.writeSimpleXMLTag(pw, indent, "useAttributes", useAttributes);
         MHQXMLUtility.writeSimpleXMLTag(pw, indent, "randomizeAttributes", randomizeAttributes);
         MHQXMLUtility.writeSimpleXMLTag(pw, indent, "randomizeTraits", randomizeTraits);
         MHQXMLUtility.writeSimpleXMLTag(pw, indent, "useClanBonuses", useClanBonuses);
@@ -334,6 +345,8 @@ public static RandomSkillPreferences generateRandomSkillPreferencesFromXml(Node
                     retVal.overallRecruitBonus = Integer.parseInt(wn2.getTextContent().trim());
                 } else if (wn2.getNodeName().equalsIgnoreCase("randomizeSkill")) {
                     retVal.randomizeSkill = wn2.getTextContent().equalsIgnoreCase("true");
+                } else if (wn2.getNodeName().equalsIgnoreCase("useAttributes")) {
+                    retVal.useAttributes = wn2.getTextContent().equalsIgnoreCase("true");
                 } else if (wn2.getNodeName().equalsIgnoreCase("randomizeAttributes")) {
                     retVal.randomizeAttributes = wn2.getTextContent().equalsIgnoreCase("true");
                 } else if (wn2.getNodeName().equalsIgnoreCase("randomizeTraits")) {
diff --git a/MekHQ/src/mekhq/gui/campaignOptions/contents/AdvancementTab.java b/MekHQ/src/mekhq/gui/campaignOptions/contents/AdvancementTab.java
index 97030148c64..2a9f028c194 100644
--- a/MekHQ/src/mekhq/gui/campaignOptions/contents/AdvancementTab.java
+++ b/MekHQ/src/mekhq/gui/campaignOptions/contents/AdvancementTab.java
@@ -113,8 +113,6 @@ public class AdvancementTab {
 
     //start Skill Randomization Tab
     private JCheckBox chkExtraRandomness;
-    private JCheckBox chkRandomizeAttributes;
-    private JCheckBox chkRandomizeTraits;
     private JCheckBox chkComingOfAgeSPAs;
 
     private JPanel pnlPhenotype;
@@ -176,6 +174,11 @@ public class AdvancementTab {
     private JSpinner spnRoleplaySkillsVet;
     private JLabel lblRoleplaySkillsElite;
     private JSpinner spnRoleplaySkillsElite;
+
+    private JPanel pnlATOWAttributes;
+    private JCheckBox chkUseAttributes;
+    private JCheckBox chkRandomizeAttributes;
+    private JCheckBox chkRandomizeTraits;
     //end Skill Randomization Tab
 
     //start Recruitment Bonus Tab
@@ -522,7 +525,10 @@ private JPanel createAdministratorsPanel() {
      */
     private void initializeSkillRandomizationTab() {
         chkExtraRandomness = new JCheckBox();
+        chkUseAttributes = new JCheckBox();
         chkRandomizeAttributes = new JCheckBox();
+
+        pnlATOWAttributes = new JPanel();
         chkRandomizeTraits = new JCheckBox();
         chkComingOfAgeSPAs = new JCheckBox();
 
@@ -609,8 +615,6 @@ public JPanel skillRandomizationTab() {
 
         // Contents
         chkExtraRandomness = new CampaignOptionsCheckBox("ExtraRandomness");
-        chkRandomizeAttributes = new CampaignOptionsCheckBox("RandomizeAttributes");
-        chkRandomizeTraits = new CampaignOptionsCheckBox("RandomizeTraits");
         chkComingOfAgeSPAs = new CampaignOptionsCheckBox("ComingOfAgeAbilities");
 
         pnlPhenotype = createPhenotypePanel();
@@ -629,12 +633,6 @@ public JPanel skillRandomizationTab() {
         layout.gridwidth = 1;
         panel.add(chkExtraRandomness, layout);
 
-        layout.gridy++;
-        panel.add(chkRandomizeAttributes, layout);
-
-        layout.gridy++;
-        panel.add(chkRandomizeTraits, layout);
-
         layout.gridy++;
         panel.add(chkComingOfAgeSPAs, layout);
 
@@ -653,6 +651,37 @@ public JPanel skillRandomizationTab() {
         return createParentPanel(panel, "XpAwardsTab");
     }
 
+    /**
+     * Creates and returns the ATOW panel, which allows users to configure settings for attribute and traits
+     * probabilities.
+     *
+     * @return A {@code JPanel} containing configuration options for phenotype probabilities.
+     */
+    private JPanel createATOWAttributesPanel() {
+        // Contents
+        chkUseAttributes = new CampaignOptionsCheckBox("UseAttributes");
+        chkRandomizeAttributes = new CampaignOptionsCheckBox("RandomizeAttributes");
+        chkRandomizeTraits = new CampaignOptionsCheckBox("RandomizeTraits");
+
+        final JPanel panel = new CampaignOptionsStandardPanel("ATOWAttributesPanel", true, "ATOWAttributesPanel");
+        final GridBagConstraints layout = new CampaignOptionsGridBagConstraints(panel);
+        layout.gridwidth = 1;
+        layout.gridx = 0;
+        layout.gridy = 0;
+
+        layout.gridy++;
+        panel.add(chkRandomizeAttributes, layout);
+
+        layout.gridx++;
+        panel.add(chkRandomizeTraits, layout);
+
+        layout.gridx = 0;
+        layout.gridy++;
+        panel.add(chkUseAttributes, layout);
+
+        return panel;
+    }
+
     /**
      * Creates and returns the Phenotype panel, which allows users to configure settings for phenotype probabilities in
      * the campaign. Each phenotype is assigned a spinner to adjust its probability.
@@ -672,8 +701,8 @@ private JPanel createPhenotypePanel() {
         layout.gridy = 0;
 
         for (int i = 0; i < phenotypes.size(); i++) {
-            phenotypeLabels[i] = new CampaignOptionsLabel(phenotypes.get(i).getName());
-            phenotypeSpinners[i] = new CampaignOptionsSpinner(phenotypes.get(i).getName(), 0, 0, 100, 1);
+            phenotypeLabels[i] = new CampaignOptionsLabel(phenotypes.get(i).getLabel());
+            phenotypeSpinners[i] = new CampaignOptionsSpinner(phenotypes.get(i).getLabel(), 0, 0, 100, 1);
 
             layout.gridx++;
             panel.add(phenotypeLabels[i], layout);
@@ -748,6 +777,7 @@ private JPanel createSkillGroupPanel() {
         pnlArtillery = createArtilleryPanel();
         pnlSmallArms = createSmallArmsPanel();
         pnlSecondarySkills = createSecondarySkillPanel();
+        pnlATOWAttributes = createATOWAttributesPanel();
 
         // Layout the Panel
         final JPanel panel = new CampaignOptionsStandardPanel("SkillGroupsPanel");
@@ -768,6 +798,8 @@ private JPanel createSkillGroupPanel() {
         layout.gridx = 0;
         layout.gridy++;
         panel.add(pnlSecondarySkills, layout);
+        layout.gridx++;
+        panel.add(pnlATOWAttributes, layout);
 
         return panel;
     }
@@ -1149,6 +1181,7 @@ public void loadValuesFromCampaignOptions(@Nullable CampaignOptions presetCampai
 
         //start Skill Randomization Tab
         chkExtraRandomness.setSelected(skillPreferences.randomizeSkill());
+        chkUseAttributes.setSelected(skillPreferences.isUseAttributes());
         chkRandomizeAttributes.setSelected(skillPreferences.isRandomizeAttributes());
         chkRandomizeTraits.setSelected(skillPreferences.isRandomizeTraits());
         chkComingOfAgeSPAs.setSelected(options.isRewardComingOfAgeAbilities());
@@ -1237,6 +1270,7 @@ public void applyCampaignOptionsToCampaign(@Nullable CampaignOptions presetCampa
 
         //start Skill Randomization Tab
         skillPreferences.setRandomizeSkill(chkExtraRandomness.isSelected());
+        skillPreferences.setUseAttributes(chkUseAttributes.isSelected());
         skillPreferences.setRandomizeAttributes(chkRandomizeAttributes.isSelected());
         skillPreferences.setRandomizeTraits(chkRandomizeTraits.isSelected());
         for (int i = 0; i < phenotypeSpinners.length; i++) {


Reviews:
user: login: copilot-pull-request-reviewer[bot]
body: ## Pull Request Overview

This PR adds a new campaign option to disable ATOW Attribute scores and refines the UI for skill randomization by relocating related checkboxes into a dedicated ATOW Attributes panel.  
- Removed the old randomization checkboxes from the main skill randomization tab.  
- Introduced a new ATOW Attributes panel with its own checkboxes.  
- Updated the RandomSkillPreferences and DefaultSkillGenerator logic to support the new disable option.

### Reviewed Changes

Copilot reviewed 3 out of 6 changed files in this pull request and generated 1 comment.

| File | Description |
| ---- | ----------- |
| MekHQ/src/mekhq/gui/campaignOptions/contents/AdvancementTab.java | Moved ATOW attribute-related components to their own panel and updated their initialization and layout. |
| MekHQ/src/mekhq/campaign/personnel/skills/RandomSkillPreferences.java | Added a new property (useAttributes) with corresponding XML read/write support. |
| MekHQ/src/mekhq/campaign/personnel/generator/DefaultSkillGenerator.java | Added logic to reset attribute scores when the useAttributes option is disabled. |

<details>
<summary>Files not reviewed (3)</summary>

* **MekHQ/data/campaignPresets/1 - New Player Preset.xml**: Language not supported
* **MekHQ/data/campaignPresets/2 - Veteran Experience Preset.xml**: Language not supported
* **MekHQ/resources/mekhq/resources/CampaignOptionsDialog.properties**: Language not supported
</details>



state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-23T02:16:59Z
user: login: IllianiBird
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-23T17:07:09Z

Review comments:
diff_hunk: @@ -522,7 +525,10 @@ private JPanel createAdministratorsPanel() {
      */
     private void initializeSkillRandomizationTab() {
         chkExtraRandomness = new JCheckBox();
+        chkUseAttributes = new JCheckBox();
path: MekHQ/src/mekhq/gui/campaignOptions/contents/AdvancementTab.java
user: login: Copilot
body: The checkbox variables for ATOW attributes (chkUseAttributes, chkRandomizeAttributes, chkRandomizeTraits) are instantiated in initializeSkillRandomizationTab and then re-instantiated in createATOWAttributesPanel, which may lead to inconsistent state between the panels. Consider initializing these components only once and reusing the instance to ensure state consistency.
created_at: 2025-04-23T02:16:59Z
author_association: CONTRIBUTOR
diff_hunk: @@ -522,7 +525,10 @@ private JPanel createAdministratorsPanel() {
      */
     private void initializeSkillRandomizationTab() {
         chkExtraRandomness = new JCheckBox();
+        chkUseAttributes = new JCheckBox();
path: MekHQ/src/mekhq/gui/campaignOptions/contents/AdvancementTab.java
user: login: IllianiBird
body: So this comment is fair, but outside the scope of this PR
created_at: 2025-04-23T17:07:09Z
author_association: COLLABORATOR

PR comments:
user: login: codecov[bot]
created_at: 2025-04-22T17:16:13Z
body: ## [Codecov](https://app.codecov.io/gh/MegaMek/mekhq/pull/6730?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=MegaMek) Report
Attention: Patch coverage is `2.63158%` with `37 lines` in your changes missing coverage. Please review.
> Project coverage is 11.41%. Comparing base [(`94dec6d`)](https://app.codecov.io/gh/MegaMek/mekhq/commit/94dec6d06ae1959e47afb81bec42d5b068be01cf?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=MegaMek) to head [(`dea7571`)](https://app.codecov.io/gh/MegaMek/mekhq/commit/dea7571fa66509377653614ae81432ddd40248d4?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=MegaMek).
> Report is 39 commits behind head on master.

| [Files with missing lines](https://app.codecov.io/gh/MegaMek/mekhq/pull/6730?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=MegaMek) | Patch % | Lines |
|---|---|---|
| [...q/gui/campaignOptions/contents/AdvancementTab.java](https://app.codecov.io/gh/MegaMek/mekhq/pull/6730?src=pr&el=tree&filepath=MekHQ%2Fsrc%2Fmekhq%2Fgui%2FcampaignOptions%2Fcontents%2FAdvancementTab.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=MegaMek#diff-TWVrSFEvc3JjL21la2hxL2d1aS9jYW1wYWlnbk9wdGlvbnMvY29udGVudHMvQWR2YW5jZW1lbnRUYWIuamF2YQ==) | 0.00% | [25 Missing :warning: ](https://app.codecov.io/gh/MegaMek/mekhq/pull/6730?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=MegaMek) |
| [...ign/personnel/generator/DefaultSkillGenerator.java](https://app.codecov.io/gh/MegaMek/mekhq/pull/6730?src=pr&el=tree&filepath=MekHQ%2Fsrc%2Fmekhq%2Fcampaign%2Fpersonnel%2Fgenerator%2FDefaultSkillGenerator.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=MegaMek#diff-TWVrSFEvc3JjL21la2hxL2NhbXBhaWduL3BlcnNvbm5lbC9nZW5lcmF0b3IvRGVmYXVsdFNraWxsR2VuZXJhdG9yLmphdmE=) | 0.00% | [6 Missing :warning: ](https://app.codecov.io/gh/MegaMek/mekhq/pull/6730?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=MegaMek) |
| [...paign/personnel/skills/RandomSkillPreferences.java](https://app.codecov.io/gh/MegaMek/mekhq/pull/6730?src=pr&el=tree&filepath=MekHQ%2Fsrc%2Fmekhq%2Fcampaign%2Fpersonnel%2Fskills%2FRandomSkillPreferences.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=MegaMek#diff-TWVrSFEvc3JjL21la2hxL2NhbXBhaWduL3BlcnNvbm5lbC9za2lsbHMvUmFuZG9tU2tpbGxQcmVmZXJlbmNlcy5qYXZh) | 14.28% | [6 Missing :warning: ](https://app.codecov.io/gh/MegaMek/mekhq/pull/6730?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=MegaMek) |

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff            @@
##             master    #6730   +/-   ##
=========================================
  Coverage     11.41%   11.41%           
- Complexity     6477     6478    +1     
=========================================
  Files          1095     1095           
  Lines        140803   140832   +29     
  Branches      21813    21815    +2     
=========================================
+ Hits          16069    16079   +10     
- Misses       123075   123091   +16     
- Partials       1659     1662    +3     
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/MegaMek/mekhq/pull/6730?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=MegaMek).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=MegaMek).

<details><summary> :rocket: New features to boost your workflow: </summary>

- :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
</details>
author_association: NONE
user: login: HammerGS
created_at: 2025-04-23T02:35:30Z
body: @IllianiBird 
author_association: MEMBER