Skip to content

POC: Modular config-driven rebel loadout system - #1964

Closed
ToallaNova-O2D wants to merge 1 commit into
long-war-2:masterfrom
ToallaNova-O2D:feature/modular-rebel-loadouts-v2
Closed

POC: Modular config-driven rebel loadout system#1964
ToallaNova-O2D wants to merge 1 commit into
long-war-2:masterfrom
ToallaNova-O2D:feature/modular-rebel-loadouts-v2

Conversation

@ToallaNova-O2D

@ToallaNova-O2D ToallaNova-O2D commented May 29, 2026

Copy link
Copy Markdown

Un-hardcode Rebel Soldier Loadouts for Rendezvous / Rebel Raid Missions

Summary

This PR makes rebel soldier loadouts in Rendezvous and Rebel Raid missions configurable via .ini instead of hardcoded template name strings. Modders can now add or change rebel weapons and utility items without touching UnrealScript.

Scope: Only affects rebel soldiers spawned by CreateRebelSoldier() in Utilities_LW.uc.


Problem

CreateRebelSoldier() had weapon and item template names hardcoded directly in the function body. If a mod wanted rebels to carry different weapons or items, it required editing the source .uc file — creating merge conflicts and making the change invisible to other mods.

Solution

Replace the hardcoded strings with config arrays read from XComLW_Overhaul.ini. The rewritten CreateRebelSoldier() picks weapons and items from these arrays at runtime, so any mod can append or override entries via standard .ini patching.


Changes

Modified: LW_Overhaul/Classes/Utilities_LW.uc

New structs:

  • RebelWeaponCategoryEntry — pairs a weapon template name with a tier (conventional / laser / magnetic / beam)
  • RebelUtilityArchetype — defines a utility role (offensive, defensive, utility) with a list of candidate item template names

New config arrays:

  • REBEL_WEAPON_CATEGORIES — weapon pool, grouped by tier
  • REBEL_UTILITY_ARCHETYPES — utility item archetypes with candidate items per role
  • REBEL_OFFENSIVE_ITEMS — flat list of offensive item template names
  • REBEL_DEFENSIVE_ITEMS — flat list of defensive item template names
  • REBEL_UTILITY_ITEMS — flat list of general utility item template names
  • REBEL_FIXED_ITEMS — items every rebel always receives

Rewritten function:

  • CreateRebelSoldier() — now reads from the config arrays above instead of hardcoded strings. Rolls a weapon tier based on researched techs, picks a random weapon from that tier, then assigns utility items by archetype.

New helper functions:

  • RollRebelWeaponTier() — determines the highest weapon tier available based on current tech research (uses the upstream TechResearchedOrHasHQInventoryItem() pattern from PR Reduce hardcoding in rebel/VIP scaling techs #1959)
  • GetItemForUtilityType() — given a utility archetype, picks a random item from the matching pool
  • EquipItemOnUnit() — creates an item from a template name and adds it to a unit's inventory

Legacy fallback:

  • The original implementation is preserved as CreateRebelSoldier_Legacy() so it can be called if the config arrays are empty or missing.

Modified: LW_Overhaul/Config/XComLW_Overhaul.ini

Added a config section with default entries that reproduce the original hardcoded behavior:

  • Default weapon categories across all four tiers (conventional, laser, magnetic, beam)
  • Default utility archetypes (offensive, defensive, utility)
  • Default item pools for each archetype
  • Default fixed items

Upstream Compatibility

PR #1959 — Un-hardcode Rebel Scaling Techs (copyrite)

Fully compatible. RollRebelWeaponTier() uses the configurable tech name variables and TechResearchedOrHasHQInventoryItem() pattern introduced in that PR.


Size

~450 lines total across both files.


Status: Proof-of-Concept / RFC

This is a working prototype submitted for feedback. The default config values reproduce the original hardcoded behavior, so there should be no gameplay change out of the box.

Looking for feedback on:

  • Does the struct/config layout make sense for LWOTC's conventions?
  • Are the config array names clear and consistent with the rest of the codebase?
  • Any edge cases in weapon tier rolling or item assignment we should handle?
  • Preferred approach for the legacy fallback (keep it, remove it, gate it behind a config flag?)

Testing

  • Fresh campaign: rebels in Rendezvous missions spawn with correct default loadouts (same as before this change)
  • Fresh campaign: rebels in Rebel Raid missions spawn with correct default loadouts
  • Add a custom weapon to REBEL_WEAPON_CATEGORIES via .ini patch; verify rebels can spawn with it
  • Remove all config entries; verify CreateRebelSoldier_Legacy() fallback activates cleanly
  • Verify compatibility with PR Reduce hardcoding in rebel/VIP scaling techs #1959 tech name changes
  • Mid-campaign save/load: no errors related to rebel loadouts

@ToallaNova-O2D
ToallaNova-O2D force-pushed the feature/modular-rebel-loadouts-v2 branch from 3699b8a to 72a02b8 Compare May 29, 2026 04:05
Config-driven weapon categories, utility archetypes, and item pools
replace hardcoded rebel soldier loadout logic. New helper functions
(GetUtilityPool, GetWeaponForTier, EquipItemOnUnit, RollRebelWeaponTier,
RollLegacyLoadout, RollRebelCharacterTemplate) provide clean separation
of concerns.

Character template configurability enables species mod integration
(PlayableAdvent, PlayableAliens) via soft dependency — templates are
validated at runtime, missing mods fall back silently.

Uses SYNC_RAND_STATIC for all random rolls (network sync).
Uses TechResearchedOrHasHQInventoryItem pattern (upstream PR long-war-2#1959).
Legacy loadout system preserved as automatic fallback when config is empty.
@ToallaNova-O2D
ToallaNova-O2D force-pushed the feature/modular-rebel-loadouts-v2 branch from 0f4cb05 to 6353d38 Compare May 29, 2026 06:00
@DaloLorn

Copy link
Copy Markdown
Contributor

Two things I feel I should call out:

  • While I don't recognize the exact harness and model, it's pretty clear this was vibe-coded. That doesn't necessarily make it nonfunctional - at a glance I see nothing immediately broken in your diff - but you may encounter resistance from some of the community, and perhaps doubly so for not openly acknowledging the fact.
  • As a general rule, the onus is on the PR submitter (i.e. you) to check and prove that the PR builds and works. (This is perhaps doubly the case for a vibe-coded PR, since the potential volume of submissions would otherwise quickly overwhelm whatever might pass for a QA team around here.) Those test cases look decent enough, but I don't think anyone else will run through them for you. As examples, you can look at POC: Make the first three pistol perks (Magnum, Clutch Shot, and Quickdraw) purchasable without TC #1911, Prevent Julian's units from receiving ADVENT tech upgrades #1910, or Cleaned out unnecessary state function overrides from X2Action_TemplarShield_ApplyWeaponDamageToUnit #1926... or you can look at other people's PRs and see how they did it. 😂
    • It's been my impression that one should hold a PR in draft status until it has passed all tests, possibly to make it easier for Ted to tell which ones are ready for review and merging.
    • (Sidenote: I'm not sure you need a fresh campaign to run some of these tests. IIRC, the rebel loadouts aren't static, and the same rebel can spawn with two different loadouts in two different missions.)

@copyrite
copyrite marked this pull request as draft May 29, 2026 09:15
@copyrite

Copy link
Copy Markdown
Collaborator

If you haven't tested this, this is a draft.

@copyrite copyrite changed the title Status: Proof-of-Concept: Modular config-driven rebel loadout system POC: Modular config-driven rebel loadout system May 29, 2026
@M3r1st

M3r1st commented May 29, 2026

Copy link
Copy Markdown
Contributor

This was not written by a human being.

  1. Configs reference non-existent names.
  2. It is completetly wrong about modded content.
  3. Inconsistent handling.
  4. The structs are nonsensical, considering the goal.
    Edit:
  5. There seems to be a complete lack of understanding why specific character template use only specific items.

@ToallaNova-O2D

Copy link
Copy Markdown
Author

I'll review it more and come up with something more tested.

@ToallaNova-O2D
ToallaNova-O2D deleted the feature/modular-rebel-loadouts-v2 branch May 30, 2026 17:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants