Force Generator data: faction formation naming and bloodname houses - #534
Merged
Conversation
Add the infantry-style carrier units the MekHQ Force Generator uses to place generated support staff into the TOE: Inner Sphere and Clan Support Person, Support Squad, and Support Platoon / Point. The generator looks these up by their <Name> and crews them with the generated support personnel. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add combat engineer formations to the generic IS and Periphery rulesets, rooted at Infantry with the engineer role so every faction inherits them via the parent-ruleset fallback. - Engineer Battalion (4 companies) -> Engineer Company -> named specialized lances: Fieldworks Lance, Bridging Engineer Lance, and Demolition Lance. Each lance is themed by one engineer facet (fieldworks/bridge_layer/demolition), with slots that roll their own units by facet, padded with fieldworks engineer infantry so thin facets still fill. Bridging is date-gated to when bridge-layer equipment exists (2470+); earlier eras get a second fieldworks lance instead. - Replace the previous thin engineer company (three infantry platoons plus a tank lance) with the specialized structure above. - Move the misplaced engineer support off the aerospace wing: in IS it is relocated to the Mek regiment's ground support; in Periphery it is removed from the wing (its Mek regiment attachment is structured differently). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a combined-arms engineer Star (five Points: three infantry, one vehicle, one Mek) and an engineer Binary (two Stars) to the generic Clan ruleset, attached as support at Cluster (Star) and Galaxy (Binary) level. Uses the umbrella engineer role, since Clan engineer-tagged units are too sparse to split by specialization. Engineers are attached support only, reflecting that the Clans do not field dedicated combat engineer formations. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add three Mixed (Clan Chassis) combat engineer Points that fill the infantry Points of the Clan Engineer Star, with era-gated Clan availability reflecting Clan doctrine (general engineers were retired around 2840 in favor of demolition and minesweeping training): - Clan Engineer Point (Fieldworks): vibro-shovel, available 2810-2839 - Clan Engineer Point (Demolition): demolition charge, available 2840+ - Clan Engineer Point (Minesweeper): minesweeper, available 2840+ Each is a 20-trooper platoon (the Combat Engineer specialization caps a platoon at two squads / twenty troopers) and passes the infantry construction verifier. The engineer mission role is derived from the carried equipment. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A generic Inner Sphere Mek regiment previously attached a full infantry regiment as support, which in turn attached its own nested air, cavalry and armor support, ballooning the force. Downsize each attachment by one echelon: aerospace wing -> squadron, armor battalion -> company, infantry regiment -> battalion, and the optional engineer company -> platoon. Faction rulesets that define their own regiment support (Federated Suns RCTs, SLDF, etc.) are unaffected. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Generate the Castillian Principalities' four canonical Brigadas (per Sarna) with distinct character: 1st fields the heaviest Meks in defense of the capital, 2nd is a lighter assault force, and 3rd/4th are garrisons. One Brigada is chosen at random and given its characteristic weight class; each still builds the six combined-arms regiments plus two aerospace wings it did before. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…iphery The generic IS ruleset attached a bare %PLATOON% of engineers to Mek regiments, which the RAT handed in as a single loose infantry leaf - the "orphan Engineer under Infantry Support" seen in 3151 Merc regiments. Regiment support is now a proper Engineer Company (%COMPANY%), and a new Engineer Platoon rule (four combined-arms subunits: fieldworks squad, earthmoving vehicle, bridge-layer vehicle 2470+, engineer IndustrialMek 2520+) is attached to standalone battalions (ifTopLevel), so neither is a loose single-unit leaf. Both generic rulesets stay in lockstep: - IS.xml: regiment Engineers %PLATOON% -> %COMPANY%; add Engineer Platoon rule; add ifTopLevel battalion Engineer Platoon attachment; drop the dead duplicate Engineer Company rule. - Periphery.xml: add matching Engineer Platoon rule and the standalone battalion Engineer Platoon attachment. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The schema had drifted until 54 of the 63 faction rulesets failed validation, making it useless as a reference (nothing validates against it at load, so the drift was latent). Verified with lxml before/after: 54/63 failing -> 0/63. - eschelonDefinition now collapses whitespace so formatted (indented) subforce content validates - this alone accounted for ~830 errors - and its suffix character class is corrected from [+-^] (an accidental +..^ range matching digits and capitals) to [+\-^]. - The force content model is now an unordered repeated choice, matching the loader (megamek Ruleset/ForceNode reads children by tag name with no ordering requirement): shipped files interleave weightTarget/co/rule elements freely, and a force without a co is legal. - predicateAttributeGroup now matches the predicate vocabulary implemented in megamek RulesetNode.matches(): added the missing ifEschelon (previously declared only on toc options), removed the phantom ifFormation that neither the code nor any file uses. - Removed the dead generate="unit" enum value (the engine implements only model/chassis/group/empty; no file uses it). - subforceType now allows the eschName attribute FID.xml uses. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
CC.WHO was the only ruleset offering TOC ratings without declaring a default - previously masked by the rating picker's legacy null "Random" entry, which is being removed in megamek. Defaults to C, matching the parent CC ruleset; adjust if the Warrior Houses should default higher-grade. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The Periphery March Guard (FS.PMG), Periphery March Militia (FS.PMM), and Robinson March Brigade (FS.RMB) are active from 3080 per their command data, but each had a <faction> tech-mix node in 3078.xml, two years before founding. Those nodes were also inert (a single scalar tech value queried at an out-of-range rating index, so it fell through to parent FS). Removing them aligns the era data with the factions' active dates; their 3082-3160 nodes are unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Uncomment the dormant capitalType planetary event field across 182 systems (312 occurrences: National/Region/District Capital) so MekHQ can read a system's administrative capital status per era. Data only; the paired administration blocks are left commented. Every touched file was re-validated as parseable YAML. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add tags: [MILITIA] to the 16 commands named 'Planetary Militia' so the force generator can recognize them for planetary garrison generation. The regional and March militias (rated C/D commands that field regular line formations) are intentionally left untagged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ignators
Companies become "1/A Company" and lances "A-1 Battle Lance" so multiple
companies in one generated force no longer produce identical child names.
Root-level generation degrades cleanly ("A Company", "Company") via the
matching parseName cleanup in MegaMek. CLAN.xml is left as-is: its star rows
already use {name:parent} tags and its Mek trinaries are unnamed, so parent
tokens cannot resolve there; MekHQ's FormationNamer covers Clan TO&Es.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A combined-arms Planetary Militia force rule at the brigade echelon in the two generic roots. Because <force> lookup walks parent factions, it is the universal fallback for any MILITIA faction whose own ruleset defines no garrison. Infantry-heavy with armor support and a small (often zero) Mek contingent, approximating the Random Garrisons Table; each contingent delegates to the standard regiment/battalion rules. The toc exposes it via the combined (null) unit type at the brigade echelon. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adding the combined (null) unit type to the IS and Periphery toc changed the Force Generator defaults: refreshUnitTypes treats a fresh descriptor's null unit type as matching the combined entry, so Unit Type selected Combined instead of falling through to the Mek default, and Formation then offered only Planetary Militia instead of Regiment. Planetary militia are chosen as a subfaction (for example FS.pm), not as a formation, so the toc entries are removed. The Planetary Militia force rule stays in both rulesets: rule lookup walks parent factions without consulting the toc, so the garrison generator still resolves it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ulesets
Supplies the data half of the Formation Naming Method, whose code side already
landed in megamek and MekHQ. The <name> elements on <force> give a formation its
flavour name ("Battle Lance", "IV-alpha"); <formationNaming> supplies the
positional designator, which differs by faction and is inherited per echelon
through the parent chain, so a faction can override one echelon without
restating the rest.
- formationRulesetSchema.xsd: define <formationNaming>, namingTierType and
designatorStyleType, the latter matching the values of
FormationNamingConvention.DesignatorStyle in megamek
- IS and Periphery: alphabet designators from lance through army, including the
naval hierarchy so naval formations follow the force-wide scheme instead of
the hardcoded phonetic they carried before
- CLAN: greek Galaxy, numeric-ordinal Cluster, engine-named Trinary and Binary,
alphabet Star
- CS: ordinal Level VI and V, engine-named Level IV and III, alphabet Level II
- Replace the hardcoded attached-force names ("Aerospace Support", "Armor
Support") with the {echelon} token across the remaining faction rulesets, so
the positional part of those names comes from the convention as well
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The Aurora (Tanker) carries 546 tons of liquid cargo across four bays plus a 140 ton dry hold, but was tagged 'support' only. Its direct sibling, the Aurora (Cargo), carries 740 tons of dry cargo and is tagged 'cargo'. Because MissionRole.CARGO is a hard filter that excludes every model without the role, the tanker could never be drawn from a cargo query despite being a purpose-built hauler. Pairs the roles as 'cargo,support', matching how the Jumbo is already tagged. Applied to the eleven era files that carry the model, 3060 through 3160. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A CARGO mission role query against DropShips could previously draw from only 15 models, and the highest-capacity haulers in the game were not among them because they had no era entries at all. This adds six absent chassis and six missing variants, all verified against the unit files so every entry resolves. New chassis: - Mule C: the Clan-built Mule (2842, 8,294 tons of cargo). CLAN:4:2842 at introduction, plateauing at CLAN:5,BAN:2. Clan cargo hauling is scarce next to Inner Sphere commercial traffic, so it sits well below the Union C military transport rather than tracking it. The Inner Sphere Mule keeps its own CLAN:5, so Exodus-inherited hulls still appear alongside Clan production. - Behemoth C: the Clan version of the largest DropShip ever built (2848, 75,773 tons). CLAN:1:2848 rising to CLAN:2 - it cannot land, so it depends on orbital transfer, which keeps it just above the Inner Sphere Behemoth's IS:1 floor. - Aqueduct Liquid Carrier: a genuine long-lived production class (2638), and the only hull in the data with liquid cargo bays - 26,000 tons of liquid plus a 2,850 ton dry hold. Ramps from SL:2:2638 to the Mammoth's profile, which it is the direct ancestor of; from 2807 it takes the Mammoth's own per-era string so successor-state keys track automatically. - Mingo: Boeing Interstellar's 2315 colonial hauler, predating the earliest era file. Dominant at IS:7,Periphery:8 through 2520, declining in the 2571 file as obsolescence lands in 2600, then Periphery.Deep only thereafter. - Cargo King and Cargomaster: neither entered service. The Cargomaster never left prototype and its production line was scrapped; only two Cargokings were built, one lost in testing and the survivor vanishing in the Kesai system in 2825. Both carry the floor availability in the 2780-2823 files and are absent everywhere else. New variants, at half their sibling's weight (General:6 against General:8) so the established model stays the common draw: - Behemoth (2782), Mammoth (2808), Buccaneer (2792), Buccaneer Rezak, Rose (Bara no Ryu) (Hive) - Behemoth C (Arcship) at General:4, lower again because converting half the hold to habitation makes it a different ship rather than a near-duplicate Buccaneer (2709) (Vehicle) is deliberately excluded: it is a vehicle carrier with 529 tons of incidental hold, not a cargo variant. No existing entries were modified; all 39 changed files are pure insertions. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The folder held six units: a single support person, one squad and one formation each for the Inner Sphere and the Clans. That covered neither ComStar nor any squad size other than the one each tradition happens to field, so a campaign needing a four-person team or a Com Guards detachment had nothing to draw on. Adds eighteen units, mirroring the existing six exactly - same field order, same Leg movement, same unarmed non-combatant loadout of fatigues and a blade, and the same squad_size x squadn idiom the Platoon and Point already use to express their organisation. Only names, tech base, year and trooper counts differ. - Squads of two through seven for all three traditions. Inner Sphere seven and Clan five are omitted because the existing unnumbered Support Squad and Clan Support Squad already cover those sizes; adding them would have produced two units with identical stats. - ComStar Support Person, which had no equivalent at all. - ComStar Support Level I at six squads of six. A Level I is the smallest Com Guards formation, a thirty-six-man infantry platoon, so it stands alongside the Inner Sphere Support Platoon (7x4, 28) and the Clan Support Point (5x5, 25) as that tradition's equivalent formation. ComStar entries use the Inner Sphere tech base, which the Com Guards field, and year 2825, already the year carried by the bulk of the early ComStar infantry elsewhere in the repository. Also adds the CC BY-NC-SA licence header to the six pre-existing files, which were missing it. Those changes are header insertions only; no unit data was touched. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Every squad size was its own named unit - "Support Squad 3", "Support Squad 4" - except the two full-size ones, which kept the older un-numbered names. Code picking a squad by size therefore had to build a name for most sizes and special-case the other two. Each size is now a model of one chassis: "Support Squad" plus "(3 person)". MekSummary composes a unit's name as chassis plus model, so the full names come out as "Support Squad (3 person)" and a caller can name the carrier for a given headcount directly. The count is visible wherever the unit is listed, which was the other reason for doing it this way. Applies to all three traditions, and to the person, platoon, Point and Level I units so the whole folder reads consistently. Tech Team.blk becomes Support Squad 7.blk, matching the unit it holds; the two Clan files still have filenames that predate their contents. Note MekHQ's support TOE code expects these names - the matching change is on the same branch there. Data has to be staged into the build before either takes effect. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Filenames in this folder had drifted from their contents. Clan Tech Point.blk held the Clan Support Point, Clan Tech Squad.blk held the Clan Support Squad, and the rest carried the old numbered names that the model change replaced. Each file is now named for the unit inside it - "Support Squad (3 person).blk" - matching the chassis and model the file declares. MekSummaryCache falls back to the filename when a name lookup misses, so having the two agree removes a way for a lookup to half-work. Content is unchanged; these are renames only. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Every support column in the Clan rank system was a redirect - TECH pointed at the MekWarrior column, MEDICAL and ADMINISTRATOR pointed at TECH - so a Clan technician, doctor or administrator rendered a warrior rank. At the index the Force Generator assigns them, that rank is literally "Warrior", a term that in Clan society denotes warrior caste specifically. Names the three columns directly instead. Technicians hold Technician, medics hold Doctor and administrators hold Administrator, with a single rung above for the one who heads each department: Head Technician and Head Administrator. Medicine has no second rank. Research turns up nothing above Doctor, so a chief medical officer is a Doctor who holds a post rather than one who outranks the other doctors; Doctor is named on both rungs so a promoted chief medical officer keeps the title instead of borrowing a technician's through the column redirect. Placed at rows 4 and 5, which the Clan system leaves free, so nothing existing moves and no warrior rank changes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Fifteen Bloodnames were spelled in ways that match no real surname, in a pattern characteristic of a scanning error - M for H, K for N, M for N: Makkinen -> Hakkinen Mavas -> Navas Kikishina -> Nikishina Mygren -> Nygren Kipchage -> Kipchoge Kochkova -> Klochkova Greehalgh -> Greenhalgh Oldebrect -> Oldebrecht Albery -> Alberty Barhart -> Barnhart Bourthiax -> Bouthiaux Fisher -> Fischer Lloyed -> Lloyd Zukauskas -> Zukauskas (with a caron) Budolin -> Budolin (macron corrected to a tilde) Each was confirmed against the Sarna article for the same Bloodname before being changed: both sources name the same Clan, so the two spellings describe one Bloodname rather than two, and the corrected form is a real surname where the current one is not. Hoskins carried a bare <CSA /> element where a second post-Reaving Clan was meant. postReavingClans is a List and already supports several, but the loader ignores an unrecognised element, so Clan Star Adder silently never inherited the legacy. It is now a proper <postReaving> entry alongside CGS. A further eleven names differ between the two sources and are deliberately left alone. Unlike the above, those are cases where the current spelling is the plausible one - Dibaba, Kinnison, Kirketerp, Halkia are all real surnames while the wiki's forms repeat or drop a letter - or where neither can be shown wrong. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The collection held no Clan Field Manuals at all, which are precisely what Bloodname articles cite: Field Manual: Warden Clans is referenced 252 times across them and Crusader Clans 198, with the Wolf Clan, Jade Falcon and Invading Clans sourcebooks behind those. Publication details are taken from Sarna. id, image, url and mul_url are left off because those come from the Master Unit List and the Catalyst store, and these are FASA-era books not carried there. Note Wars of Reaving already existed as WoR.yaml - the Bloodname articles cite it as "The Wars of Reaving", which is why it first appeared to be missing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adds a bloodnames block to each of the twenty-one Clan faction files, carrying 805 houses - every entry in bloodnames.xml - under the Clan that founded them. Each house merges what the two available sources each know. The mechanical fields mirror bloodnames.xml, so nothing the generator relies on is lost: phenotype, exclusive, limited, shared, abjured, dormant, reaved, reactivated, created, postReaving, and the dated absorbed and acquired records. The descriptive fields come from the Sarna articles: the founder's full name, rank and affiliation, a one-line summary, the notable holders with their ranks, and the sources each is attested in. Sources carry a sourcebook abbrev where one resolves and a bare title where it does not. A Bloodname can have more than one house - sixteen do - so houses is a list keyed on founder rather than a single record. bloodnames.xml has always modelled this as repeated name entries; this makes the structure explicit. The join is on Bloodname plus the founder's given name, the only key the two sources share, and matches 804 of 805 houses. The exception is the Clan Ghost Bear pair Cook and Cote: both exist, and the two sources disagree over which founder belongs to which, so neither is linked to an article rather than risk attaching one house's history to the other. Both keep their mechanical data. history is left null throughout, pending the house histories being written. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Per developer preference, the Bloodname data no longer rides inside the Clan faction files. It now lives under data/universe/bloodnames, a folder per Clan and a file per Bloodname within it - 800 files across 21 Clans, carrying the same 805 Houses. Each file names its founding Clan, so a Bloodname is self-describing rather than taking meaning from the folder it happens to sit in. Eleven names are filed under two Clans, being shared legacies, and the loader merges their Houses rather than letting whichever file loads last win. This also keeps the faction files to a readable size: Clan Wolf alone carried over four hundred lines of Bloodname data. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The Word of Blake's table of contents offered the full A to F range to every command under it, so a Shadow Division could be generated at any standard down to F. They were the Word of Blake's elite and equipped accordingly, and are not raised at a lesser standard. The rating list now answers A for WOB.SD and the full range for everyone else, using the same ifFaction predicate the echelon list above it already uses. The Militia proper is unchanged. Left the command's own ratingLevels alone. Those five levels are what the rating index is counted against, and cutting them to one would renumber A from index four to index zero, which is what unit availability is looked up by.
A Choir pairs a BattleMech Level II with a battle armor Level II into one formation, so it puts twelve units on the field. The ruleset counted it as a single subforce, so a Shadow Division Level III carrying one generated forty-two units and one carrying two generated forty-eight, against the thirty-six a Level III is. A Level IV built from them ran to as many as 240 units where ComStar's structure gives 216. Reduces the other subforces by the number of Choirs, across thirty-four subforce groups. What is dropped is the most infantry-heavy Level II available: the Choir already supplies six BattleMechs in place of the Level II it nominally replaced, so its six battle armor should displace infantry rather than Mechs. Headcount is now right at every designation. Composition improves but does not fully reach the Level IV table - a Choir's six battle armor is more than the whole infantry allowance of a Mech-heavy Level III, so Choirs and the Mech-heavy end of the table cannot both be satisfied. That is left as it stands rather than resolved by removing Choirs from those designations, since they are what distinguishes a Shadow Division. Measured at 3067 over six Level IVs per designation, before and after: alpha 220 units -> 215 zeta 236 -> 216 mu 240 units -> 216 sigma 223 -> 215 Infantry falls toward the table as well, mu from 78 to 60 against a canon 56, and zeta from 51 to 46 against 30. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ComStar's Level IV table gives, per Greek designation, how many BattleMechs, armor, infantry and aerospace a Division of 216 holds, from alpha at 164 Mechs down to omega at 15. A Level IV is six Level IIIs and its constituents are picked symmetrically around its own designation, so the target for a Level III of designation Y is one sixth of row Y. Measured against that, every Level III ran light on BattleMechs - about two at the Mech-heavy end, tapering to half a unit at omega - with the shortfall showing up as armor and infantry. Over six Level IIIs that is the fourteen to sixteen Mech gap a generated Level IV showed. Forty subforce groups each swap one composition code for another with the same aerospace digit. Aerospace already landed on the table's thirty-nine, so it is held fixed and only the Mech, armor and infantry columns move. Only codes the Level II node already offers are used, so no new composition appears. Measured at 3067 over six Level IVs per designation, Mechs against canon: alpha 147.5 -> 159.7 of 164 eta 112.8 -> 120.7 of 125 epsilon 124.5 -> 133.5 of 138 mu 82.1 -> 92.3 of 93 sigma 47.0 -> 51.0 of 54 omega 12.6 -> 14.2 of 15 Armor and infantry follow: gamma now 9.7 armor against 9, mu 52.7 infantry against 56. Aerospace holds between 39 and 41 throughout. One designation is left imperfect. Alpha's armor allowance is four out of 216, and the swaps that fix its Mech count take it to zero. Trading three Mechs back for four armor is the wrong way round for the Mech-heaviest formation in the table, so it stands. The Word of Blake inherits these Level IIIs and moves with them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The Shadow Divisions declare their own Level III nodes rather than using
the Com Guard ones, so they did not benefit from the previous commit and
still ran the same BattleMech shortfall. They also carry Choirs, and a
Choir is a fixed twelve units - six augmented BattleMechs and six battle
armor, with no aerospace at all. Seven groups held two of them, which is
twenty-four of a Level III's thirty-six units spoken for before anything
else is chosen. That is where the Shadow Divisions' aerospace fell to
thirty-four against the table's thirty-nine, and where their infantry ran
well past what the Mech-heavy designations allow.
The composition table is defined at Level IV, so that is where a Choir has
to be paid for. One in the command Level III of a Level IV costs six
battle armor out of two hundred and sixteen, which even alpha's allowance
of nine absorbs. One in each of the six Level IIIs costs thirty-six, which
alpha cannot absorb at all. So a command group keeps a Choir at any
designation and every Shadow Division still has its Manei Domini
contingent, while a line group keeps one only where the designation's own
infantry allowance covers it, which is from theta onward.
Where a Choir is dropped the twelve units it held are refilled with the
two Level IIs that best fit what the designation still wants, and every
group is then offered the same single aero-neutral swap the Com Guard
nodes were given. Fifty-seven groups change.
Measured at 3067 over six Level IVs per designation:
BattleMechs aerospace
alpha 144.5 -> 158.0 164 40.5 -> 38.3 39
beta 125.0 -> 153.8 158 33.7 -> 38.2 39
zeta 111.8 -> 127.2 132 36.2 -> 41.2 39
mu 83.8 -> 92.8 93 33.7 -> 35.3 39
omega 12.5 -> 14.8 15 39.5 -> 39.0 39
Infantry at the Mech-heavy end is still over - eighteen at alpha against
nine - because the surviving command Choir cannot be made smaller than six
battle armor. Dropping it would put the numbers on the table exactly and
leave a Shadow Division with no Manei Domini in it, which is the wrong
trade.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The designation list was already offered to the player, but every entry rendered as its raw lowercase key - alpha, beta, gamma - which says nothing about what picking it does. The dialog already supports a "key:label" form for these lists and falls back to the key when no label is given, so this needs no code change. Each designation now carries the composition it stands for, taken from the Level IV table the Com Guard and Blakist rulesets were just fitted to: Alpha (164 Mek / 4 Veh / 9 Inf / 39 Aero) Omega (15 Mek / 54 Veh / 108 Inf / 39 Aero) Labels use slashes rather than commas or colons because the dialog splits the list on both. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The table taken from FM: ComStar has no column that divides into the
organisation it describes. A Level IV is six Level IIIs of six Level IIs
of six units, so every column should land on a multiple of six, and not
one of the twenty-four rows does.
Aerospace was the worst of them. Thirty-nine in every row is six Level IIs
plus an odd three, and the only way to spend that three was a Level II of
three BattleMechs and three fighters. That is the odd aerospace contingent
a player raised: a single composition code, 3003, used thirty-six times,
once in every Level III, carrying the whole remainder of the table. It was
the only code in the ruleset with an odd aerospace digit.
The table keeps the canon proportions and rounds each row onto the grid by
largest remainder, holding aerospace at thirty-six so every Level III gets
one Level II of fighters. All twenty-four designations stay distinct,
BattleMechs still fall and infantry still rises from alpha to omega, and
no column moves more than five units from canon.
alpha 168/ 6/ 6/ 36 canon 164/ 4/ 9/ 39
mu 96/ 30/ 54/ 36 canon 93/ 28/ 56/ 39
omega 18/ 54/108/ 36 canon 15/ 54/108/ 39
Rounding at the Level III instead - every column even there - was tried
and does not work. Two units per Level III is twelve per Level IV, which
is coarser than the gap between neighbouring designations: it collapses
the twenty-four into sixteen distinct forces and inverts the infantry
slide, with beta ending up with more BattleMechs than alpha and no
infantry at all.
The two rules reconcile because the six Level IIIs of a Level IV need not
match each other. Alpha wants six vehicles, which is three Level IIIs
carrying two and three carrying none, so every composition code can be
even and the four odd ones - 3003, 0330, 3030 and 3300 - are retired from
the vocabulary, from the guard that lists it, and from all 132 groups that
used them.
Measured at 3067 over six Level IVs per designation, against the new
table:
Com Guard Shadow Divisions
alpha 166.2/ 6.3/ 5.7/37.7 165.5/ 6.0/ 7.3/36.7
mu 94.8/30.0/54.0/37.2 94.5/28.7/56.0/36.8
omega 16.8/57.0/106.0/36.2 23.8/50.0/106.0/36.2
Two things fall out of this. Alpha gets its vehicles back - the previous
table's four were below what the grid could express and generation had
driven them to zero. And the Shadow Divisions' infantry at the Mech-heavy
end drops from eighteen against nine to seven against six, because a
command Choir's six battle armor is now exactly what alpha's infantry
allowance is.
The dropdown is corrected in the same change, since it reads from this
table. It labelled each designation with its Level IV strength whatever
echelon was being generated, so a player asking for a Level III was shown
six times the force they would get. The table of contents node takes
ifEschelon predicates, so this needs no code change: the designations are
listed twice, once with Level IV figures and once with the same table
divided by six. That division is exact now, which it could not have been
before.
Level IV Alpha (168 Mek / 6 Veh / 6 Inf / 36 Aero)
Level III Alpha (28 Mek / 1 Veh / 1 Inf / 6 Aero)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Retiring 3003, 0330, 3030 and 3300 from the composition vocabulary left four subforce blocks in the Com Guard Level II that are gated entirely on those codes. No Level II can be assigned one any more, so the blocks can never match. The same four are in the Explorer Corps restatement of that node. Generation is unchanged - measured at 3067 the Level IV figures are the same within run-to-run variation. This does not touch the blocks that name 0420 or 2220. Those codes were never in the vocabulary either, so those references were already dead before the retirement and are left as they were found. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The schema sequences a ruleset as defaults, customRanks, toc, formationNaming, then forces. This file had formationNaming ahead of toc, so it was the one ruleset in the directory that failed validation. Only the order changes. The naming block keeps the comment explaining why it exists, and generation is unaffected - a Division at 3070 still comes out at 62 to 65 units with BattleMechs at 26 percent, inside the one-third the Militia is held to. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The two fighters of a Level II are drawn independently, so a pair could come out as two different variants. They are already matched on weight by the ruleset - the options pair H with H, M with M - and canonically a flight was equipped as a matched pair so both could fly the same profile. The engine gained a per-block generate rule, so the aerospace block can now ask for a shared model while the BattleMechs in the same Level II carry on generating independently. This is only partly effective today, and deliberately committed anyway. Where the Level II carries no formation type the block is honoured and the pair is identical every time - measured 25 out of 25 on composition 0042. Where a formation type is assigned - 4002, 0402 and 2202 - generation takes the formation path, which still reads a single rule off the force node and never consults the per-block one, so those pairs stay as they were. The declaration is correct either way and becomes fully effective once the formation path reads the same tags. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The Warrior House Orders were a single command covering every House, so a force could be generated for the Orders but not for Imarra or Hiritsu, and the Houses' service dates - which differ by centuries at both ends - could not be expressed at all. Each of the eleven Houses now has its own record falling back on the Orders, which still fall back on the Confederation. Dates and rating spreads follow each House's own record of service. Lu Sann ends in 3074 on Herotitus, Fujita and Ma-Tsu Kai at the end of the Jihad, Hiritsu in 3152. Ijori carries two periods of service, since it was destroyed in the Republic era assault on Liao and raised again in 3134 out of the Ijori De Guang. The two Thuggee Houses are set apart from the rest. Kali Liao raised White Tiger and Rakshasa in secret with Precentor Martial Cameron St. Jamais in 3071 and both were destroyed on Sian in January 3074, White Tiger having turned on its sister House at her order. She held no authority to raise a Warrior House, so neither falls back on the Orders. Their record of service gives the Capellan Confederation and the Shadow Divisions as the two tables their equipment is drawn from, which is what the pair of fallback factions reproduces - the generator averages them, so the Houses draw on both rather than either. Generated at 3072 a White Tiger battalion fields Lao Hu, Men Shen and Vindicator alongside Phoenix Hawk PXH-7CS, Initiate and Blue Flame, which is the intended blend. Both were Capellan formations using lances, companies and battalions rather than the Word of Blake's base-six organisation, so both declare Inner Sphere sizes and the Confederation rank system rather than inheriting anything from the Blakist side. No source gives a strength for either House - both records state the size is unknown - so none is asserted here. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The sub-faction list is a list of commands - the Death Commandos, McCarron's Armored Cavalry, the Confederation Reserve Cavalry - and the Warrior House Orders were already there as one entry covering every House. The Thuggee Houses do not belong under them. Kali Liao raised White Tiger and Rakshasa in secret in 3071 with the Word of Blake's Precentor Martial Cameron St. Jamais, out of her Thuggee cult and the Manei Domini. She held no authority to raise a Warrior House, so they answer to her rather than to the Orders and do not fall back on them. Both were destroyed on Sian in January 3074, White Tiger having turned on its sister House at her order. They are one command rather than two because nothing separating them reaches unit generation. Both were raised in 3071 and died together, both are rated A, and both drew on the same two tables. What differs is who filled them - White Tiger from Thuggee cultists Kali Liao picked herself, Rakshasa from Blakist Manei Domini - and their battlefield abilities, neither of which changes what rolls off the table. Which of the two is being generated belongs in the ruleset, where it can decide organisation and naming. Their record of service names the Capellan Confederation and the Shadow Divisions as the two tables their equipment comes from, which is what the pair of fallback factions reproduces - the generator averages them, so the Houses draw on both rather than either. Generated at 3072 they field Tessen and Dragon Fire alongside Grand Titan, Thorn and Battle Cobra, which is the intended blend. Both were Capellan formations using lances, companies and battalions rather than the Word of Blake's base-six organisation, so they declare Inner Sphere sizes and the Confederation rank system. No source gives a strength for either House - both records state the size is unknown - so none is asserted here. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A Point of fighters is two aircraft flown as a pair so both pilots share one profile, but the Point node drew its two elements independently and the pair came out mismatched more often than not - between thirteen and thirty percent identical depending on the Clan. The Point generated fighters through the same block as vehicles, so it could not ask for one without the other. Aerospace now has its own block asking for a shared model while vehicle Points carry on generating independently. The two blocks are gated on unit type and so are mutually exclusive - only one is ever live for a given Point - which is why this works without waiting on the formation path to honour per-block rules. No Clan overrides the aerospace Point, so this reaches all of them. The four Clan rulesets that declare their own Point - Hell's Horses, Ice Hellion, Steel Lion and the Goliath Scorpion Grand Council - all cover vehicles only, gated on their cavalry and flurry flags. Measured at 3067 over a Cluster, pairs of identical model: Jade Falcon 13% -> 88% Hell's Horses ? -> 77% Ghost Bear 30% -> 83% Ice Hellion ? -> 89% Wolf 21% -> 73% Diamond Shark ? -> 71% The remainder are Points that carry a formation type, which routes generation down a path still reading a single rule off the force node rather than the per-block one. Those will follow once that path is fixed. The Society keeps generating independently and is deliberately untouched. Its Un is not a fighter pair - it groups infantry, ProtoMeks and fighters in one node of three or more - so a shared model would make the wrong things identical. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The augmented aerospace Nova asked its Points for ground_assault, which is not a mission role. Every one of the sixteen options failed to parse, the generator logged that it could not read the role and carried on with none applied, so the Points have been rolling as generic fighters since the node was written. The node is an Aero Nova and its Points are aerospace fighters, and the role for aircraft attacking ground targets is ground_support, which the parser accepts and which is allowed for conventional fighters, aerospace fighters and small craft. That is what was meant. The Free Worlds League support infantry option asked for "field gun" with a space. That one works, because the assertion path lowercases the value and treats underscores as spaces before matching, but it was the only role in more than twelve hundred written that way. It now reads field_gun like the rest. Worth recording why the second one is only a tidy-up and the first was a real fault: the two role paths do not accept the same spellings. An assertion goes through MissionRole.parseRole, which lowercases and treats underscores as spaces, so "field gun", "FIELD_GUN" and "field_gun" are all read alike. A predicate is compared against MissionRole.toString, which is the enum name lowercased, using an exact match - so ifRole only ever matches lowercase with underscores. Every predicate in the rulesets is already written that way. Checked afterwards that every role in every ruleset parses on the path it sits on, assertions and predicates both. These two were the only ones. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
An echelon value is a number or a %CONSTANT%, optionally suffixed. The type carried a whiteSpace facet to let indented element content match the pattern, but the facet was not being applied to element content by the validator that flagged it, so every formatted <subforce>%CONSTANT%</subforce> failed. Deriving from xs:token instead collapses whitespace as a property of the type, which validators apply before matching the pattern. The reader trims the value in any case, in ValueNode.loadFromXml, so this brings the schema into line with what the rulesets already accept. Written while chasing the Protectorate Militia schema failure, which turned out to be a separate fault - that file had its table of contents and naming block in the wrong order, fixed separately. Verified before committing that all sixty-five rulesets validate under both the old and the new definition, so nothing that passed before stops passing. The failure this corrects did not reproduce under libxml2, which does apply the facet to element content; it is a difference between validators rather than something every toolchain sees. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Merged
5 tasks
Contributor
There was a problem hiding this comment.
Pull request overview
Adds/adjusts universe and Force Generator data to support faction-specific formation naming conventions and expanded Clan bloodname “houses” data, alongside some related command metadata and availability updates.
Changes:
- Uncomments/adds
capitalTypeentries across many canonical planetary-system YAML history records. - Updates multiple Force Generator faction rules to use
{echelon}-based attached-force naming, and adds Castillian Brigada naming/flagging logic. - Adds/updates command definitions (militia tagging, WoB Protectorate Militia start year/structure/ranks) and expands bloodname datasets; updates DropShip chassis availability in several era lists.
Reviewed changes
Copilot reviewed 223 out of 1095 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| data/universe/planetary_systems/canon_systems/*.yml (many files) | Uncomments/adds capitalType in dated administration/history entries. |
| data/universe/commands/WOB.PM.yml | Adjusts active start year; adds formation sizing/grouping and rank system metadata. |
| data/universe/commands/CC.pm.yml | Adds MILITIA tag. |
| data/universe/commands/DC.pm.yml | Adds MILITIA tag. |
| data/universe/commands/DA.pm.yml | Adds MILITIA tag. |
| data/universe/commands/DTA.pm.yml | Adds MILITIA tag. |
| data/universe/commands/FC.pm.yml | Adds MILITIA tag. |
| data/universe/commands/FS.pm.yml | Adds MILITIA tag. |
| data/universe/commands/FWL.pm.yml | Adds MILITIA tag. |
| data/universe/commands/IS.pm.yml | Adds MILITIA tag. |
| data/universe/commands/LA.pm.yml | Adds MILITIA tag. |
| data/universe/commands/MOC.pm.yml | Adds MILITIA tag. |
| data/universe/commands/MSC.pm.yml | Adds MILITIA tag. |
| data/universe/commands/RCM.pm.yml | Adds MILITIA tag. |
| data/universe/commands/RF.pm.yml | Adds MILITIA tag. |
| data/universe/commands/ROS.pm.yml | Adds MILITIA tag. |
| data/universe/commands/TC.pm.yml | Adds MILITIA tag. |
| data/universe/commands/TH.pm.yml | Adds MILITIA tag. |
| data/forcegenerator/factions.xml | Updates WOB.PM active years to match command data. |
| data/forcegenerator/faction_rules/TH.xml | Renames attached-force subforces to use {echelon} placeholder. |
| data/forcegenerator/faction_rules/SL.xml | Renames attached-force subforces to use {echelon} placeholder. |
| data/forcegenerator/faction_rules/RWR.xml | Renames attached-force subforces to use {echelon} placeholder. |
| data/forcegenerator/faction_rules/OA.xml | Renames engineer subforce naming to Engineering {echelon}. |
| data/forcegenerator/faction_rules/FS.CH.xml | Renames artillery support options to Artillery {echelon}. |
| data/forcegenerator/faction_rules/FRR.xml | Renames attached-force subforces to use {echelon} placeholder. |
| data/forcegenerator/faction_rules/CCC.xml | Renames Solahma infantry attached-force names to use {echelon} placeholder. |
| data/forcegenerator/faction_rules/CC.SIJ.xml | Renames attached-force subforces to use {echelon} placeholder. |
| data/forcegenerator/faction_rules/NC.xml | Adds Brigada naming and flag selection logic for Nueva Castile formations. |
| data/forcegenerator/2398.xml | Adds Mingo DropShip chassis availability entry. |
| data/forcegenerator/2440.xml | Adds Mingo DropShip chassis availability entry. |
| data/forcegenerator/2460.xml | Adds Mingo DropShip chassis availability entry. |
| data/forcegenerator/2470.xml | Adds Mingo DropShip chassis availability entry. |
| data/forcegenerator/2490.xml | Adds Mingo DropShip chassis availability entry. |
| data/forcegenerator/2520.xml | Adds Mingo DropShip chassis availability entry. |
| data/forcegenerator/2650.xml | Adds Aqueduct Liquid Carrier and Mingo DropShip chassis availability entries. |
| data/forcegenerator/2700.xml | Adds Aqueduct Liquid Carrier and Mingo DropShip chassis availability entries. |
| data/forcegenerator/2765.xml | Adds Aqueduct Liquid Carrier and Mingo DropShip chassis availability entries. |
| data/universe/bloodnames//.yml (many new files) | Adds/restructures bloodname data into per-bloodname house-based YAML entries. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
The bloodname data carried the trademarked spelling in its rank fields, which the ForbiddenWords check rejects. MekHQ already shows the profession as MekWarrior everywhere else. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Dibaba's founder carried the affiliation in the name and the summary misspelt the Bloodname; Romero was missing the founder affiliation its own summary states. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
HammerGS
marked this pull request as ready for review
August 27, 2026 02:15
5 tasks
The ForbiddenWords check rejected 104 citation lines in the bloodname data such as "MechWarrior: Dark Age - Dossiers and Pilot Cards". A cited work has to keep its published name, so a cited title is now exempt from the rule, the same nominative-use allowance the copyright lines already have. Two ranks in the same data still carried the trademark spelling; they read MekWarrior now like the rest. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
HammerGS
added a commit
to MegaMek/megamek
that referenced
this pull request
Aug 27, 2026
…er of battle (#8820) **Depends on:** MegaMek/mm-data#534 (merge first). MegaMek/mekhq#9830 depends on this one. All three share the branch name `Implement-Force-Generator-in-MekHQ`. ## Note for reviewers The formation-naming tests read faction data that exists only on the mm-data branch of the same name (`Implement-Force-Generator-in-MekHQ`). MegaMek's CI checks that branch out by name and falls back to mm-data `main` if it is missing, so mm-data #534 needs to merge first, and its branch should stay until this PR has merged. MekHQ #9830 depends on this branch the same way. ## What this changes The Force Generator builds a table of organisation the way a faction actually organises it, and lets you edit the result directly. Generate a Draconis Combine regiment and its formations are named as the Combine names them. Pick a formation type from the palette, right-click a node in the tree to re-roll it as that type, or add a lance, company or battalion under it - and the palette only appears once there is a force to edit. If a faction and year cannot field the formation you asked for, the dialog now says so and why, instead of quietly building an ordinary lance. The tab is laid out as describe, generate, review, refine: the description form (with the transport settings as a row of it), then the Composition Summary across the full width with a Total column and row, then the palette. Also on this branch: Clan bloodname descent (a warrior belongs to a Bloodhouse, not just a name), Manei Domini and Clan Enhanced Imaging augmentation, and C3 network wiring for a generated force. ## Testing - 18 new test classes: formation naming, the budget allocator, C3 wiring, the augmentors, the mission-role filter panel and the bloodname structures. The filter panel test asserts that every filter shown for a unit type is read back, which caught a Conventional Fighter case Copilot flagged. - Full `:megamek:test` green, checkstyle and javadoc clean. `test` now depends on `stageDataFiles`, so CI and a local run see the same data. - Playtested in MekHQ's Command Designer: generation, re-rolling and adding formations, and the formation-dropped message. ## What is not proven yet - The Random Army dialog (this view's other host) has not been exercised by hand since the layout re-flow; the mission-role filters it keeps are hidden in MekHQ. - The paired MekHQ and mm-data branches must land with this one; none of the three works alone. --- - [ ] This PR is focused on one issue or RFE. Large refactoring or accessibility work is in its own PR - [x] Every file in the diff has a deliberate change (no stray formatting, no unrelated files) - [x] Tests added or updated, if this implements a rule or changes game state - [x] Javadoc literals use `{@code true}` / `{@code null}` rather than bare or quoted text - [x] Dev team only: if AI tools were used, the **AI Assisted Development** label is applied, and I can explain and have verified the result The first box is left unticked deliberately: 72 files across the ratgenerator engine, the randomArmy UI and the bloodname/augmentation structures under `common/universe`. Happy to split it if that would help review.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Depends on: nothing. MegaMek/megamek#8820 and MegaMek/mekhq#9830 depend on this branch; all three share the name
Implement-Force-Generator-in-MekHQand should merge together, this one first.What this changes
Adds the data the Force Generator work needs: a
formationNamingblock per faction, so a generated formation is named the way that faction names its own (a Star, a Level II, a Lance), and a restructured bloodname set that records which House a Clan warrior descends from rather than only the name they carry.Data only. Nothing here changes behaviour on its own; the code that reads it is in the two PRs above.
Testing
FormationNamingConventionTestreads these files directly and passes against them; MegaMek'stesttask now stages this data first, so CI and a local run see the same files.What is not proven yet
ForbiddenWordscheckstyle rule rejected the 104 bloodname source citations that name real products ("MechWarrior: Dark Age - Dossiers and Pilot Cards"). Renaming a citation would falsify it, soconfig/checkstyle/checkstyle.xmlnow exempts a citedtitle:the same way it exempts the copyright lines. That is a shared-config change, made here because it is the data that needs it; happy to move it to its own PR if preferred.{@code true}/{@code null}rather than bare or quoted textThe first box is left unticked deliberately: this is one data set, not one issue.