Enemy archetypes

The enemy roster is built from two disjoint sets:

  1. 16 base archetypes in BASE_ARCHETYPES (data/enemies/index.ts). Each is crossed against the 5-tier rarity ladder (common / uncommon / rare / epic / legendary) to generate 16 × 5 = 80 stat-scaled enemy types in ENEMY_TYPES. Stat scaling lives in RARITY_MULTS (hp / xp / speed / radius / damage), tint comes from RARITY_TINTS, and per-archetype tuning (AoE radius, blast radius, sniper charge, gunner burst, field duration, etc.) is recomputed per rarity inside buildEnemyTypes().
  2. 18 hand-authored boss-roster bodies in BOSS_ENEMY_TYPES (same file). These bypass rarity multipliers — hp / speed / radius / xp are written directly so each named encounter character (Killer Croc, Hauler, the four Prism gems, etc.) reads as a distinct body. All 18 carry the boss_roster tag.

Total identifiable enemy types at boot: 80 + 18 = 98. The renderer routes each one to a polygon silhouette via HULL_SHAPE_MAP, with boss-roster ids keeping their own id as the sprite key so the v4 sticker pipeline can bake one atlas region per boss.

The 16 base archetypes

The first 8 are the original archetypes (file order: orb, charger, shooter, mortar, gunner, field, sniper, racer). The next 4 were added in Slice 2 (brute, wisp, lurker, bombardier — t25/t26) and the final 4 in Slice 3 (sprinter, spitter, burner, suppressor — t48/t50/t51/t52). The Slice 2/3 archetypes all reuse an existing behavior string so they inherit AI from the original 8; only their stat block and rarity-tuning fields differ.

Originals (8)

ArchetypeBehaviorHPSpeedRadiusXPWeaponRole
orborb19293.7515Swarming AoE pulse; the basic bug. aoeRadius 32, aoeCooldown 0.8s, aoeDamage 10.
chargercharger441101012enemy_chargerMid-tier melee chase. The leader/elite slot in bugs pools.
shootershooter211055.518enemy_shooterOrbiting ranged projectile (orbit 130).
mortarmortar151248.7525enemy_mortarSlow lobber with telegraphed AoE. blastRadius 28, fuseTime 6.6s.
gunnergunner3633.7515enemy_gunnerFragile close-range hitscan burst. hitscanRange 65, burstCount 3, burstCooldown 2.5s. The basic for the city set.
fieldfield12069722enemy_fieldDrops a wide electric zone. fieldRadius 250, fieldFadeIn 1.0s, fieldDuration 3.0s, fieldDamage 15.
snipersniper72315.530enemy_sniperLong-range charged beam from orbit 200. sniperChargeTime 2.5s, sniperBeamDamage 5.
racerracer48313620Very fast melee dart. The basic for bugs_racer rare slots.

Slice 2 expansion (4)

These cover roles the original 8 left empty (tanky-slow melee, tiny-fast chip, longer-telegraph sniper, bigger-blast mortar).

ArchetypeReusesHPSpeedRadiusXPWeaponNotes
brutecharger100601425Tanky slow melee (~2.3× charger HP, ~60% speed, ~1.6× radius). Tags: slow, tanky.
wisporb62202.58Tiny, fast, low-HP chip-damage orb (~7× orb speed). aoeRadius 18, aoeCooldown 1.5s, aoeDamage 4.
lurkersniper6022635enemy_sniperLong-charge sniper (sniperChargeTime 4.0s) with 2× beam damage (10). Orbit 240.
bombardiermortar14018930enemy_mortarWider blast (blastRadius 42), longer fuse (fuseTime 9.0s).

Slice 3 expansion (4)

Fast, slow-tanky, lingering-hazard, and long-range-suppression variants — each pairs with its parent in the per-planet rare slots.

ArchetypeReusesHPSpeedRadiusXPWeaponNotes
sprinterracer28460516Supersonic frail racer (~1.47× racer speed, ~58% HP). Tag fast. Threads into bugs_racer (Delphi) rare slots.
spittershooter3870728enemy_shooterSlow tanky standoff shooter (orbit 200, ~1.8× HP, ~0.67× speed). Threads into bugs_shooter (Speedway).
burnerfield8050626enemy_field”Lava patch” — smaller hot zone (fieldRadius 140), 2× duration (fieldDuration 6.0s), 1.9× tick (fieldDamage 28). Threads into bugs_field (Network Station).
suppressorgunner12425.528enemy_gunnerLong-range wall-of-fire (2× hitscanRange 130, burstCount 7, burstCooldown 4.5s, 4× HP). Threads into city mid bands.

Rarity multiplication

Each of the 16 archetypes is expanded across 5 rarities. RARITY_MULTS applies multiplicative scaling to base stats:

Rarityhp×xp×speed×radius×damage×Tint
common2.73.01.401.03.0#cccccc
uncommon4.956.01.471.154.5#33cc55
rare6.9312.01.571.36.6#3388ff
epic9.918.01.681.48.4#aa44ff
legendary11.8824.01.821.510.5#ff8800

Beyond stats, buildEnemyTypes() also tunes archetype-specific knobs per rarity:

  • orb / wisp: aoeRadius grows linearly (1.0 → 1.8×); aoeCooldown shrinks via [1.0, 0.85, 0.7, 0.35, 0.35]; aoeDamage = base × damage×.
  • mortar / bombardier: blastRadius grows linearly (1.0 → 1.6×); fuseTime is constant.
  • gunner / suppressor: hitscanRange constant; burstCount × [1.0, 1.0, 1.2, 1.4, 2.0]; burstCooldown × [1.0, 0.9, 0.8, 0.65, 0.5].
  • field / burner: fieldRadius grows linearly (1.0 → 1.6×); fieldFadeIn constant; fieldDuration x1.5 only at legendary; fieldDamage = base × damage×.
  • sniper / lurker: sniperChargeTime × [1.0, 0.9, 0.8, 0.7, 0.5]; sniperBeamDamage = base × damage×.

That gives the 80 generated entries (16 × 5).

The 18 boss-roster bodies

These are hand-authored named characters in BOSS_ENEMY_TYPES. They share a base archetype (for polygon shape, AI dispatch, and atlas fallback) but write their own hp / speed / radius / xp directly — rarity multipliers don’t apply. All carry the boss_roster tag, and at spawn the boss runtime overrides hp again from BossRosterEntry.hp, so these stat numbers only matter if a non-boss path spawns the type.

FactionIdNameBase archetypeRarityRole
Backwaterbackwater_killer_crocKiller CrocchargerlegendaryBoss body — gator-themed melee.
BackwatercaimanCaimanchargerrareOrbiting anchor + spawn-profile add.
Backwatercaiman_basicCaimanchargercommonWeaker variant for swarm fill.
Junkratsjunkrats_stingerStingerchargeruncommonFast melee swarm; Hive Queen anchor.
Junkratsjunkrats_orcaOrcamortarlegendaryHeavy queen body. blastRadius 180, fuseTime 2.4s.
Junkratsjunkrats_pierrePierremortarlegendaryCaptain heavy mortar. blastRadius 150, fuseTime 2.0s.
Junkratsjunkrats_marcoMarcogunnerrareCaptain support gunner. hitscanRange 320, burstCount 4, burstCooldown 1.6s.
Industriaindustria_loaderLoaderchargerepicAwakened Mech phase add.
Industriaindustria_drillbotDrillbotchargerlegendaryFast drilling melee add.
Industriaindustria_bigbotBigbotmortarlegendaryBig-blast mortar add. blastRadius 200, fuseTime 2.2s.
Industriaindustria_digbotDigbotorbcommonSingle small swarm body (100× per encounter).
Solarissolaris_haulerHaulermortarlegendaryReactor Core anchor — hp 0, speed 0, behavior static, untargetable.
Solarissolaris_valetValetshooterepicOrbiting body around the Hauler (orbit 240, behavior orbit).
Solarissolaris_oracleOracleshooterlegendaryDoomsayer’s prophet — speed 0, behavior static.
Prismprism_citrineCitrineorblegendaryCluster gem (orbit 240, behavior orbit, tint #f0c040).
Prismprism_rubyRubyorblegendaryCluster gem (tint #e02828).
Prismprism_jadeJadeorblegendaryCluster gem (tint #3aa860).
Prismprism_pearlPearlorblegendaryCluster gem (tint #f0f0f0).

Cross-reference

  • Personality profiles (PERSONALITY_PROFILES in index.ts) hold {c, t, s} triplets only for the original 8 archetypes. Slice 2/3 archetypes inherit personality through their behavior parent (sprinter → racer, spitter → shooter, etc.).
  • Polygon shapes route through HULL_SHAPE_MAP. Slice 2/3 archetypes explicitly point to a parent shape (sprinter_*racer, burner_*field, etc.) so the renderer doesn’t fall to the polygon default. Boss-roster ids map to themselves to claim atlas regions.
  • Spawn pools in SPAWN_POOLS / CITY_SPAWN_POOLS / per-planet BUGS_*_POOLS decide which archetype-rarity strings actually appear in-run. The 80 generated types are not all “live” in every world — most worlds run mostly orb_* or gunner_* with a thin rare-slot mix.
  • Source file: starship-survivors/src/starship-survivors/data/enemies/index.ts (registry) and starship-survivors/src/starship-survivors/data/enemies/<archetype>.ts (one file per base).