Add a Synergy

In short

A synergy is a SynergyDefinition: a tag, a requiredCount and a list of bonus StatModifiers. When the player owns at least that many upgrades carrying the tag, the bonus is added to their stats. Add one Synergy(...) line in DefaultContent and tag the upgrades that should feed it.

Steps

  1. Add the line in Assets/_Project/Scripts/Data/DefaultContent.cs, block // ---------- Synergies ----------. The helper is Synergy(id, name, tag, count, params bonus):
    db.synergies.Add(Synergy("slugger", "Slugger", "Power", 3, StatModifier.Percent(StatType.HomeRunMultiplier, 0.5f)));
    The helper writes the description for you: 3+ "Power" items.
  2. Tag the upgrades that feed it: add the tag string to their tags array (see Add an Upgrade). A new tag with no upgrades carrying it can never switch on.
  3. Nothing else: RunState.RecalculateStats asks SynergyResolver.GetActive for the active synergies after every purchase and adds each one’s bonus to the stats.

How it is counted

  • SynergyResolver.CountTag counts owned upgrades whose tags list contains the tag (exact, case-sensitive match).
  • Charms stack, so two copies of the same charm count twice. Example: two Lucky Pennies ("Greed") switch on High Roller ("Greed", 2).
  • Each synergy is simply on or off. There are no tiers, but two synergies on the same tag with different counts would both work independently.

Check it works

  • Press Play, start a run, then F1 → GIVE AN UPGRADE until you own enough tagged items. The build panel on the map and shop screens lists it under active synergies with its bonus (UI/BuildPanel), and F1 → ATTRIBUTES shows the changed stat in yellow.

Gotchas

  • A typo in the tag ("power" vs "Power") means the synergy never triggers and nothing warns you.
  • Synergy ids are not saved anywhere (active synergies are recomputed), so renaming one is safe.
  • Synergies apply in co-op per player, from that player’s own upgrades. No protocol bump needed.
  • Active synergies also appear on each player’s card in the match intro (Intro/MatchIntroCard, by displayName), with nothing to register. The INDEX has no synergies tab.