Decompose a unit's flat loadout into per-model-type groups (e.g. "1x Blood Herald:
…" + "6x Goremongers: …" + "1x Goremongers: …"). The composition's
assignRowCounts fixes how many models each row fields; solveAssignment
then searches, completely and deterministically, for an assignment of each row's
models to legal per-model loadouts (enumerateRowCandidates) whose weapons sum
to counts exactly while respecting every option's optionCap. Returns null
only when no such exact partition exists (a single model, no recorded per-model
defaults, or a genuinely indivisible bag) — callers then omit loadout_groups and
renderers fall back to their unit-wide rendering unchanged. Mirror of
crates/wh40kdc/src/data/loadout.rs.
Decompose a unit's flat loadout into per-model-type groups (e.g. "1x Blood Herald: …" + "6x Goremongers: …" + "1x Goremongers: …"). The composition's assignRowCounts fixes how many models each row fields; solveAssignment then searches, completely and deterministically, for an assignment of each row's models to legal per-model loadouts (enumerateRowCandidates) whose weapons sum to
countsexactly while respecting every option's optionCap. Returnsnullonly when no such exact partition exists (a single model, no recorded per-model defaults, or a genuinely indivisible bag) — callers then omitloadout_groupsand renderers fall back to their unit-wide rendering unchanged. Mirror ofcrates/wh40kdc/src/data/loadout.rs.