data/props.ts — World-Prop Catalog

Typed destructible catalog. Props share the crate idiom (off-screen spawn, ship-contact break, drop XP orbs) but vary by silhouette, drop richness, density, and break VFX. Per-planet density = crate density × densityMult.

Slay

  • Defines the seven prop tiers used by the prop-spawner + weighted-roll pipeline.
  • Single source of truth for HP, radius, sticker emoji, rim color, orb drops, density multiplier, and break VFX.
  • HP exists for a future Slice 2 (weapon-fire damage); Slice 1 always one-shots on ship contact.
  • Exports PROP_TYPES (readonly array) + getPropType(id) (throws on unknown).

Cross

PropTypeDef (interface)

FieldTypeMeaning
idstringStable id used by spawner + telemetry.
labelstringDebug-HUD label only — never user-facing.
hpnumberMax HP; Slice 1 always one-shots via ship contact.
radiusnumberVisible silhouette radius — spawn placement + collision.
emojistringBaked sticker sprite glyph.
rimColorstringInner-rim halo color (rarity ring around sticker).
orbCountnumberXP-orb pickups dropped on break.
orbXpFracPerOrbnumberXP per orb as a fraction of current level bar.
densityMultnumberMultiplier vs the crate density slider (0–1).
vfx.sparkRgb[r,g,b]Spark cloud color.
vfx.chunkRgb[r,g,b]Debris chunk color.
vfx.ringColorstringRing-flash color.
vfx.sparkCountnumberParticle count of the spark cloud.
vfx.ringBurstCountnumberExtra outward burst-ring particles.
edgeArrow?booleanHUD draws screen-edge directional arrow when off-screen. Rare-tier only.

Exports

  • PROP_TYPES: readonly PropTypeDef[] — seven-entry catalog (see Styx).
  • getPropType(id: string): PropTypeDef — linear scan; throws Unknown prop type id: <id> on miss. No silent fallback.

Styx

Tier table (catalog order)

idLabelHPRadiusEmojirimColororbCountorbXp/orbApprox. % level bardensityMultedgeArrow
scrap_pileScrap Pile1032🗑️#9aa3ad slate40.018~7.2%1.00
drone_wreckDrone Wreck1830🤖#5fc8ff cyan60.020~12%0.60
comet_fragmentComet Fragment826☄️#c8ddff ice70.015~10.5%0.40
mineral_veinMineral Vein4034🪨#5fe07a green100.024~24%0.25
volatile_crystalVolatile Crystal2530💎#ff5fcb magenta80.022~17.6%0.35
supply_podSupply Pod8040📦#ffaa44 amber120.035~42%0.15yes
magnetar_pulseMagnetar Pulse3532🌀#a050ff violet60.020~12%0.20yes

Break-VFX table

idsparkRgbchunkRgbringColorsparkCountringBurstCount
scrap_pile[220,220,220] dust-white[110,110,110] grey#cfd6df140
drone_wreck[120,220,255] electric blue[80,120,160] dark blue#7fd5ff180
comet_fragment[220,235,255] ice-white[150,180,220] pale blue#dfeaff208
mineral_vein[120,230,130] emerald[60,140,80] forest#7fe89a2410
volatile_crystal[255,100,220] hot magenta[180,60,180] deep magenta#ff3fb02218
supply_pod[255,200,100] amber[200,150,80] bronze#ffcc443014
magnetar_pulse[180,110,255] violet[110,50,200] deep purple#a060ff2616

Design intent (per tier)

  • Scrap Pile — workhorse common; HP-10 one-ram break; grey dust; no ring burst.
  • Drone Wreck — workhorse-alt; HP-18 reads as “metal carcass” (two rams or short burst); cyan circuitry palette.
  • Comet Fragment — light snack; HP-8 fragile; 7 orbs at lower XP for a “shooting-star streak” rhythm; small 8-particle ring burst.
  • Mineral Vein — sustained-DPS reward; HP-40 between Volatile (25) and Supply (80); rewards weapon-fire builds; ~24% level bar bundle.
  • Volatile Crystal — risk-reward; HP-25; magenta matches the volatile elite-affix palette; heavy 18-particle outward ring burst.
  • Supply Pod — rare iconic; HP-80 ≈ 3–4 s of base-DPS; biggest spark burst (30); ~42% level bar; edge-arrow telegraph.
  • Magnetar Pulse — rare field-control; HP-35; break grants a 1s gravity field (value is in the pull, not XP); 6 orbs × 0.020; edge-arrow second tier.

Density math

  • Per-planet density derives from the same destructibles slider crates use: propDensity = crateDensity × densityMult.
  • Weight distribution (relative): Scrap 1.00, Drone 0.60, Comet 0.40, Volatile 0.35, Mineral 0.25, Magnetar 0.20, Supply 0.15.
  • Comment-asserted: Supply Pods ≈ ~10% of total prop spawns; capped at ~1–2 active by shared MAX_DENSITY = 10. Magnetar pulses are roughly Supply-Pod frequency, ~1–2 active.

Edge-arrow tier

Reserved for high-value rare props that need a screen-edge directional arrow when off-screen (Survivor.io / Vampire Survivors loot-pointer telegraph). Currently supply_pod and magnetar_pulse. Field defaults to undefined/false; common props stay quiet.

Lookup

getPropType('scrap_pile') // => PropTypeDef
getPropType('unknown')    // throws Error('Unknown prop type id: unknown')

Linear scan over PROP_TYPES. Typo’d ids are bugs, not runtime fallbacks — crash on bad data, per project rule.


EXTRACT-CANDIDATE: The XP-yield-per-tier column (orbCount × orbXpFracPerOrb → “approx % level bar”) is derived in this doc only. If a balance/economy roll-up page wants this, extract to a shared constant or a propXpYield() helper rather than duplicating the arithmetic. The Magnetar Pulse “1s gravity field on break” effect is referenced in the description but not encoded as a field — it lives in the spawner/effect layer; if a designer-authoring guide extends PropTypeDef with an onBreakEffect field, fold the comment into a structured slot.