Supporter Club Tiers

The Supporter Club is a tiered loyalty / membership system that grants passive bonuses to player progression and economy. Three states exist: none, free, and paid. Members in either active tier receive a daily Credits bonus and a permanent XP multiplier; paid doubles down on both.

Tier table

Values sourced from stores/supporterStore.ts (getDailyBonusCredits, getXpMultiplier) and data/economy.ts (SUPPORTER_CLUB_PAID_COST_USD).

TierCostDaily CreditsXP MultiplierStatus enum
None01.00×none
FreeFree to join (no charge)2001.10× (+10% XP)free
Paid$2.99 / month5001.20× (+20% XP)paid

At launch (beta), the paid tier does not require real payment — upgradeSupporterPaid() in services/shopService.ts simply flips the state, mirroring the “betaTopUp” behavior used for gem packs.

Membership lifecycle

  • Joining (free): joinFree() sets status = 'free' and stamps activatedAt = Date.now(). Reachable from the shop via joinSupporterFree() in services/shopService.ts; rejects if the player is already any kind of supporter.
  • Upgrading (paid): upgradePaid() sets status = 'paid' and re-stamps activatedAt. Reachable via upgradeSupporterPaid(); rejects if the player is already paid.
  • Reset: reset() returns the player to status: 'none' with activatedAt: null. Used by account-reset flows.

The store also exposes two convenience predicates that gameplay systems read from:

  • isSupporter() — true when status !== 'none' (either active tier).
  • isPaid() — true when status === 'paid' (paid tier only).

Perks in detail

Daily Credits grant

getDailyBonusCredits() returns the per-day Credits payout for a player’s current tier. Non-supporters get 0; free supporters get 200; paid supporters get 500. The daily-claim cadence is enforced at the consumer layer (see services/dailyService.ts or equivalent claim handler).

XP multiplier

getXpMultiplier() returns a flat multiplier applied to XP gains. Non-supporters get 1.00× (no effect); free supporters get 1.10× (+10%); paid supporters get 1.20× (+20%). The multiplier is meant to be read once at XP-grant time, not stacked with itself.

Future / cosmetic perks

Cosmetic perks (badges, banners, profile flair) are not currently wired into the store — the store only models economic perks (Credits, XP). When cosmetic perks ship, expect them to be gated on isSupporter() for free-tier-included perks and isPaid() for paid-exclusive perks.

Persistence

  • Local state: Zustand store useSupporterStore (stores/supporterStore.ts) holds status and activatedAt in memory.
  • Cloud: Synced to Supabase table player_supporter (per the store’s header comment). The loadStatus(status, activatedAt) action rehydrates from cloud on session bootstrap.
  • Reset: Account reset clears the row via reset().
  • SUPPORTER_CLUB_PAID_COST_USD = 2.99 — display price for paid upgrade (data/economy.ts).
  • Paid tier is presented alongside GEM_PACKS and SPECIAL_OFFERS in the shop surface.

Source map

  • src/starship-survivors/stores/supporterStore.ts — store definition, tier table for Credits + XP, predicates, persistence hooks.
  • src/starship-survivors/data/economy.tsSUPPORTER_CLUB_PAID_COST_USD (line 189).
  • src/starship-survivors/services/shopService.tsjoinSupporterFree() / upgradeSupporterPaid() shop actions.