pull-config.ts

Pull system configuration. Banner definitions, pull costs, pity thresholds, and ship rarity rates for the gacha metagame. Ships-only pulls.

Contract

  • All rates in a rarity table sum to 1.0.
  • Pity counter is per-banner, persisted in the player_pity table.

Pull costs

ConstantValueMeaning
SINGLE_PULL_GEM_COST100Warp Crystals per single pull (V32)
TEN_PULL_GEM_COST1000Warp Crystals per 10-pull (V32)
SINGLE_PULL_TICKET_COST1Tickets per single pull
TEN_PULL_TICKET_COST10Tickets per 10-pull

No discount on 10-pull cost — pure 10× the single price. The 10-pull’s value comes from TEN_PULL_GUARANTEE_RARITY, not price.

Daily ad tickets

ConstantValueMeaning
DAILY_AD_TICKET_LIMIT5Max free tickets per day from ads

Pity system

ConstantValueMeaning
HARD_PITY_THRESHOLD50Pulls until guaranteed high-rarity
SOFT_PITY_START40High-rarity chance ramps linearly from here
TEN_PULL_GUARANTEE_RARITY'uncommon'Floor rarity for any 10-pull

Soft pity window: pulls 40–49 see linearly increasing high-rarity chance. Hard pity at pull 50 forces a guaranteed high-rarity drop. Counter resets on trigger and is stored per-banner.

Banners

BannerDef interface: id, name, emoji.

BANNERS record contains two entries:

KeyNameEmoji
sunSun☀️
moonMoon🌙

Ship rarity rates

SHIP_RARITY_RATES: Record<ShipRarity, number> — must sum to 1.0.

RarityWeight
common0.55
uncommon0.27
rare0.12
epic0.06
legendary0.00

Legendary is zero-weighted — currently unreachable through normal pulls. Sum: 0.55 + 0.27 + 0.12 + 0.06 + 0.00 = 1.00.

Pull result type

PullPullResult interface — what each pull resolves to:

FieldTypeMeaning
type'ship'Always 'ship'; pulls only produce ships
entityIdstringShip template ID (e.g. 'dart_common')
raritystringRarity of the pulled ship
isFeaturedbooleanUI highlight flag for featured entities
wasPitybooleanTrue if pity triggered this pull

Exports

  • SINGLE_PULL_GEM_COST, TEN_PULL_GEM_COST
  • SINGLE_PULL_TICKET_COST, TEN_PULL_TICKET_COST
  • DAILY_AD_TICKET_LIMIT
  • HARD_PITY_THRESHOLD, SOFT_PITY_START, TEN_PULL_GUARANTEE_RARITY
  • BannerDef (interface), BANNERS
  • SHIP_RARITY_RATES
  • PullPullResult (interface)

Dependencies

  • ./ships — imports ShipRarity type for keying rate table and the pity guarantee.

EXTRACT-CANDIDATE

  • The naming PullPullResult is a typo/stutter (likely intended PullResult). Rename candidate.
  • legendary: 0.00 is dead weight in the rate table — legendary ships can never drop here. Either remove the key or move legendary acquisition to a separate path (event banner, crafting, mission reward) and document it.
  • Pity thresholds (HARD_PITY_THRESHOLD, SOFT_PITY_START) are global, not per-banner — banner-specific tuning would require splitting these into a Record<BannerId, PityConfig>.
  • Banner emoji field hardcodes display detail in a data table — UI concern leaking into config. Move to a banner-presentation layer if banner art/icons expand.
  • SHIP_RARITY_RATES is single global table; no per-banner rate variation possible. If Sun/Moon need different drop weights (rate-up, featured ship boost), extract to Record<BannerId, RarityRates>.
  • “Ships only” assumption is encoded in PullPullResult.type = 'ship'. If pulls ever produce mods/artifacts/cosmetics, the type union and result shape need expansion.