Enemy archetypes
The enemy roster is built from two disjoint sets:
- 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 generate16 × 5 = 80stat-scaled enemy types inENEMY_TYPES. Stat scaling lives inRARITY_MULTS(hp / xp / speed / radius / damage), tint comes fromRARITY_TINTS, and per-archetype tuning (AoE radius, blast radius, sniper charge, gunner burst, field duration, etc.) is recomputed per rarity insidebuildEnemyTypes(). - 18 hand-authored boss-roster bodies in
BOSS_ENEMY_TYPES(same file). These bypass rarity multipliers —hp/speed/radius/xpare written directly so each named encounter character (Killer Croc, Hauler, the four Prism gems, etc.) reads as a distinct body. All 18 carry theboss_rostertag.
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)
| Archetype | Behavior | HP | Speed | Radius | XP | Weapon | Role |
|---|---|---|---|---|---|---|---|
| orb | orb | 19 | 29 | 3.75 | 15 | — | Swarming AoE pulse; the basic bug. aoeRadius 32, aoeCooldown 0.8s, aoeDamage 10. |
| charger | charger | 44 | 110 | 10 | 12 | enemy_charger | Mid-tier melee chase. The leader/elite slot in bugs pools. |
| shooter | shooter | 21 | 105 | 5.5 | 18 | enemy_shooter | Orbiting ranged projectile (orbit 130). |
| mortar | mortar | 151 | 24 | 8.75 | 25 | enemy_mortar | Slow lobber with telegraphed AoE. blastRadius 28, fuseTime 6.6s. |
| gunner | gunner | 3 | 63 | 3.75 | 15 | enemy_gunner | Fragile close-range hitscan burst. hitscanRange 65, burstCount 3, burstCooldown 2.5s. The basic for the city set. |
| field | field | 120 | 69 | 7 | 22 | enemy_field | Drops a wide electric zone. fieldRadius 250, fieldFadeIn 1.0s, fieldDuration 3.0s, fieldDamage 15. |
| sniper | sniper | 72 | 31 | 5.5 | 30 | enemy_sniper | Long-range charged beam from orbit 200. sniperChargeTime 2.5s, sniperBeamDamage 5. |
| racer | racer | 48 | 313 | 6 | 20 | — | Very 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).
| Archetype | Reuses | HP | Speed | Radius | XP | Weapon | Notes |
|---|---|---|---|---|---|---|---|
| brute | charger | 100 | 60 | 14 | 25 | — | Tanky slow melee (~2.3× charger HP, ~60% speed, ~1.6× radius). Tags: slow, tanky. |
| wisp | orb | 6 | 220 | 2.5 | 8 | — | Tiny, fast, low-HP chip-damage orb (~7× orb speed). aoeRadius 18, aoeCooldown 1.5s, aoeDamage 4. |
| lurker | sniper | 60 | 22 | 6 | 35 | enemy_sniper | Long-charge sniper (sniperChargeTime 4.0s) with 2× beam damage (10). Orbit 240. |
| bombardier | mortar | 140 | 18 | 9 | 30 | enemy_mortar | Wider 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.
| Archetype | Reuses | HP | Speed | Radius | XP | Weapon | Notes |
|---|---|---|---|---|---|---|---|
| sprinter | racer | 28 | 460 | 5 | 16 | — | Supersonic frail racer (~1.47× racer speed, ~58% HP). Tag fast. Threads into bugs_racer (Delphi) rare slots. |
| spitter | shooter | 38 | 70 | 7 | 28 | enemy_shooter | Slow tanky standoff shooter (orbit 200, ~1.8× HP, ~0.67× speed). Threads into bugs_shooter (Speedway). |
| burner | field | 80 | 50 | 6 | 26 | enemy_field | ”Lava patch” — smaller hot zone (fieldRadius 140), 2× duration (fieldDuration 6.0s), 1.9× tick (fieldDamage 28). Threads into bugs_field (Network Station). |
| suppressor | gunner | 12 | 42 | 5.5 | 28 | enemy_gunner | Long-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:
| Rarity | hp× | xp× | speed× | radius× | damage× | Tint |
|---|---|---|---|---|---|---|
| common | 2.7 | 3.0 | 1.40 | 1.0 | 3.0 | #cccccc |
| uncommon | 4.95 | 6.0 | 1.47 | 1.15 | 4.5 | #33cc55 |
| rare | 6.93 | 12.0 | 1.57 | 1.3 | 6.6 | #3388ff |
| epic | 9.9 | 18.0 | 1.68 | 1.4 | 8.4 | #aa44ff |
| legendary | 11.88 | 24.0 | 1.82 | 1.5 | 10.5 | #ff8800 |
Beyond stats, buildEnemyTypes() also tunes archetype-specific knobs per rarity:
- orb / wisp:
aoeRadiusgrows linearly (1.0 → 1.8×);aoeCooldownshrinks via[1.0, 0.85, 0.7, 0.35, 0.35];aoeDamage = base × damage×. - mortar / bombardier:
blastRadiusgrows linearly (1.0 → 1.6×);fuseTimeis constant. - gunner / suppressor:
hitscanRangeconstant;burstCount × [1.0, 1.0, 1.2, 1.4, 2.0];burstCooldown × [1.0, 0.9, 0.8, 0.65, 0.5]. - field / burner:
fieldRadiusgrows linearly (1.0 → 1.6×);fieldFadeInconstant;fieldDurationx1.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.
| Faction | Id | Name | Base archetype | Rarity | Role |
|---|---|---|---|---|---|
| Backwater | backwater_killer_croc | Killer Croc | charger | legendary | Boss body — gator-themed melee. |
| Backwater | caiman | Caiman | charger | rare | Orbiting anchor + spawn-profile add. |
| Backwater | caiman_basic | Caiman | charger | common | Weaker variant for swarm fill. |
| Junkrats | junkrats_stinger | Stinger | charger | uncommon | Fast melee swarm; Hive Queen anchor. |
| Junkrats | junkrats_orca | Orca | mortar | legendary | Heavy queen body. blastRadius 180, fuseTime 2.4s. |
| Junkrats | junkrats_pierre | Pierre | mortar | legendary | Captain heavy mortar. blastRadius 150, fuseTime 2.0s. |
| Junkrats | junkrats_marco | Marco | gunner | rare | Captain support gunner. hitscanRange 320, burstCount 4, burstCooldown 1.6s. |
| Industria | industria_loader | Loader | charger | epic | Awakened Mech phase add. |
| Industria | industria_drillbot | Drillbot | charger | legendary | Fast drilling melee add. |
| Industria | industria_bigbot | Bigbot | mortar | legendary | Big-blast mortar add. blastRadius 200, fuseTime 2.2s. |
| Industria | industria_digbot | Digbot | orb | common | Single small swarm body (100× per encounter). |
| Solaris | solaris_hauler | Hauler | mortar | legendary | Reactor Core anchor — hp 0, speed 0, behavior static, untargetable. |
| Solaris | solaris_valet | Valet | shooter | epic | Orbiting body around the Hauler (orbit 240, behavior orbit). |
| Solaris | solaris_oracle | Oracle | shooter | legendary | Doomsayer’s prophet — speed 0, behavior static. |
| Prism | prism_citrine | Citrine | orb | legendary | Cluster gem (orbit 240, behavior orbit, tint #f0c040). |
| Prism | prism_ruby | Ruby | orb | legendary | Cluster gem (tint #e02828). |
| Prism | prism_jade | Jade | orb | legendary | Cluster gem (tint #3aa860). |
| Prism | prism_pearl | Pearl | orb | legendary | Cluster gem (tint #f0f0f0). |
Cross-reference
- Personality profiles (
PERSONALITY_PROFILESinindex.ts) hold{c, t, s}triplets only for the original 8 archetypes. Slice 2/3 archetypes inherit personality through theirbehaviorparent (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-planetBUGS_*_POOLSdecide which archetype-rarity strings actually appear in-run. The 80 generated types are not all “live” in every world — most worlds run mostlyorb_*orgunner_*with a thin rare-slot mix. - Source file:
starship-survivors/src/starship-survivors/data/enemies/index.ts(registry) andstarship-survivors/src/starship-survivors/data/enemies/<archetype>.ts(one file per base).