Artifact Flat-Bonus Passive

What it is

Every alien artifact carries a thematic passive stat boost that scales with the artifact’s runtime tier (common → legendary). The boost is on top of the artifact’s triggered ability — it pays out continuously while the artifact is equipped, regardless of whether the proc condition has fired.

The system is universal: every artifact in ARTIFACT_DEFS must have a flat-bonus entry. getArtifactFlatBonus(id) throws on a missing mapping.

Defined in data/artifacts/index.ts. Applied in engine/world/artifacts.ts via _applyFlatBonus.

Per-tier ramp

Linear, 10 percentage points per tier across the runtime 0-4 scale:

Runtime tierNameBonus value
0Common10
1Uncommon20
2Rare30
3Epic40
4Legendary50
export const FLAT_BONUS_PCT_BY_TIER = [10, 20, 30, 40, 50] as const;

Common (tier 0) is the in-run starting tier for every artifact. The data files store only four tiers (uncommon → legendary), so getTierValuesAt clamps the data index to max(0, min(3, runtimeTier - 1)) — meaning common and uncommon share the same per-tier values record. The differentiation between common and uncommon comes from the flat-bonus ramp (10 → 20), not from the ability’s tier values.

How the engine consumes it

When an artifact is equipped or levelled, equipArtifact (and the tier-up handler) calls _applyFlatBonus:

function _applyFlatBonus(inst: ArtifactInstance, sh: ShipState): void {
  const fb = getArtifactFlatBonus(inst.id);
  const value = getArtifactFlatBonusValueAt(inst.id, inst.tier);
  Modifiers.add(
    (sh as any).eid ?? 0,
    fb.stat,
    fb.mode,
    value,
    0, 0,
    `artifact:${inst.id}:flatbonus`,
  );
}
  • fb.stat — the ship-stat key (e.g. weaponDamagePct).
  • fb.mode'flat' adds +N points to the stat; 'percent' multiplies the base stat by (1 + N/100).
  • Source tag artifact:<id>:flatbonus lets _unapplyStatEffects strip the previous tier’s modifier with Modifiers.removeBySource before re-applying at the new tier.

On level-up the flow is: _unapplyStatEffects (which calls _removeFlatBonus) → bump tier → _applyFlatBonus. This guarantees only one flat-bonus modifier is live per artifact at any time.

Stat palette

The runtime stat pool is intentionally tiny — six ship percentage stats. Repeats across artifacts are deliberate, so artifacts in the same archetype share a passive identity:

StatModeLabel
weaponDamagePctflatWeapon Damage
fireRatePctflatFire Rate
magnetRangeflatMagnet Range
luckflatLuck
damageReductionpercentDamage Reduction
maxSpeedpercentTop Speed

'flat' stats (weapon damage, fire rate, magnet, luck) add a literal +N points. 'percent' stats (damage reduction, top speed) multiply the base stat by (1 + N/100) — at legendary that’s a ×1.50 baseline lift.

Per-artifact mapping

The full mapping table is in ARTIFACT_FLAT_BONUSES in data/artifacts/index.ts. Examples by archetype:

Weapon Damage (weaponDamagePct, flat)echo_generator, patient_fury, shieldless_fury, shield_break_nova, lingering_flames, chain_reaction, static_charge, armor_shred, overcharge_round, energy_kill_nova, hull_missiles, meltdown, sympathetic_resonance, killchain_coil, witness, overdrive, adept.

Fire Rate (fireRatePct, flat)trigger_happy, versatility, surge_coil, echo, frenzy.

Magnet Range (magnetRange, flat)companion_droid, vitality_surge, quartermaster, salvager, stockpile.

Luck (luck, flat)crate_buster, killstreak_rain, bloodlust, refresh, event_reward, caretaker, lodestone, hunter.

Damage Reduction (damageReduction, percent)event_healer, force_field, personal_space, reactive_plating, absorption_barrier, heat_tank, battery_shield, halo, heartstone, aegis.

Top Speed (maxSpeed, percent)tbone_shockwave, battering_ram, shieldburst, heat_racer, speed_demon, devourer, slipstream, wayfinder.

The mapping is set by the artifact’s primary archetype identity. When an artifact’s triggered ability already buffs one stat (e.g. Surge Coil’s burst is fireRate + magnet), the flat-bonus picks the primary one (fireRate) to reinforce the artifact’s identity rather than spread the boost.

Not damage-tag scoped

The flat-bonus system targets ship-wide percentage stats, not per-tag weapon damage. The weapon-damage entries all use weaponDamagePct, which lifts every weapon’s damage equally regardless of tag (bullet, energy, fire, bomb).

That makes flat-bonus distinct from the level-up modifier system (data/modifiers.ts), which has four tag-specific damage modifiers — damage_bullet, damage_energy, damage_fire, damage_bomb — chosen as horizontal upgrades during the in-run reward-card flow. Modifier picks let the player concentrate damage on the weapon tags they currently rely on; the artifact flat-bonus is the artifact’s always-on identity, decoupled from tag selection.

Tier mechanics

  • Artifacts start at common (tier 0) in every run; the artifact instance is upgraded in-run by reward cards.
  • ARTIFACT_TIER_MAX = 4 (legendary) is the runtime ceiling.
  • The ability’s per-tier values record is keyed off the data-file indices 0-3 (uncommon → legendary). Common reuses the uncommon record but pays the 10-point flat-bonus rather than 20.
  • Meta-progression (between-runs XP and tier unlocks) is tracked via gm.tracking.artifactBestTier_recordBestTier writes the highest in-run tier reached so the bridge can flush it to persistent unlocks at run end.