---
id: wiki-2026-0508-staircase-monetization-model
title: Staircase Monetization Model
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [staircase-pack, ascending-offer, escalating-iap, value-ladder]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [monetization, mobile-game, f2p, iap, pricing]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
  language: csharp
  framework: unity-firebase
---

# Staircase Monetization Model

## 매 한 줄
> **"매 each pack purchased unlocks the next bigger one"**. Staircase monetization 은 매 mobile F2P game 의 ascending IAP offer sequence — 매 user 가 $0.99 → $4.99 → $19.99 → $99.99 의 step 을 sequentially 만 unlock. 매 commitment-and-consistency 심리, anchoring, sunk cost 의 활용 — 매 Coin Master, Royal Match, Monopoly Go 의 standard.

## 매 핵심

### 매 메커니즘
- **Locked staircase**: 매 step N 은 step N-1 구매 후 만 visible.
- **Increasing value (face)**: 매 step 마다 gem/coin 양 의 % 가 증가 (e.g. +20% better deal).
- **Time gate**: 매 24h cooldown 으로 urgency 생성.
- **Reset trigger**: 매 step 8~10 도달 시 staircase 의 reset (or branch).
- **Personalization**: 매 LiveOps 의 player segment 별 pack value tuning.

### 매 심리 leverage
- **Commitment & consistency** (Cialdini): $0.99 결제 후 매 다음 의 escalation 의 "이미 의 spent" mindset.
- **Anchoring**: 매 작은 첫 step 이 reference price.
- **Loss aversion**: "이 deal 의 24h 후 의 사라진다".
- **Variable reward**: 매 step 의 better-than-average value 가 dopamine hit.

### 매 응용
1. **Match-3** — 매 Royal Match, Candy Crush 의 starter pack ladder.
2. **Casual** — 매 Coin Master 의 spin pack staircase.
3. **Mid-core** — 매 Monopoly Go 의 sticker pack escalation.
4. **Card game** — 매 Marvel Snap 의 currency ladder.

## 💻 패턴

### State machine (Unity C#)
```csharp
public class StaircaseOffer : MonoBehaviour {
    [Serializable] public class Step { public int tierId; public string sku;
        public int gems; public float priceUsd; public string title; }
    public List<Step> ladder;
    int currentStep = 0;
    DateTime? lockedUntil;

    public Step GetVisibleOffer() {
        if (lockedUntil.HasValue && DateTime.UtcNow < lockedUntil.Value) return null;
        return currentStep < ladder.Count ? ladder[currentStep] : null;
    }

    public void OnPurchase(string sku) {
        var step = ladder[currentStep];
        if (step.sku != sku) return;
        Inventory.Add("gems", step.gems);
        currentStep++;
        lockedUntil = DateTime.UtcNow.AddHours(24);
        Analytics.Track("staircase_step_purchased", new {tier = step.tierId, currentStep});
        if (currentStep >= ladder.Count) ResetStaircase();
    }

    void ResetStaircase() { currentStep = 0; lockedUntil = DateTime.UtcNow.AddDays(7); }
}
```

### Server-side validation (Firebase Cloud Functions)
```typescript
export const purchaseStaircase = onCall(async (req) => {
  const { uid, sku, receipt } = req.data;
  const valid = await verifyReceipt(receipt);  // App Store / Play
  if (!valid) throw new HttpsError("permission-denied", "bad receipt");
  const ref = db.collection("users").doc(uid);
  await db.runTransaction(async (tx) => {
    const u = (await tx.get(ref)).data();
    if (u.staircase.expectedSku !== sku) throw new HttpsError("failed-precondition", "wrong step");
    const step = LADDER[u.staircase.currentStep];
    tx.update(ref, {
      gems: FieldValue.increment(step.gems),
      "staircase.currentStep": FieldValue.increment(1),
      "staircase.lockedUntil": Timestamp.fromMillis(Date.now() + 24*3600*1000),
    });
  });
  return { ok: true };
});
```

### Value curve (each step 20% better)
```python
import numpy as np
prices = np.array([0.99, 4.99, 9.99, 19.99, 49.99, 99.99])
base_gems_per_dollar = 100
step_bonus = np.array([1.0, 1.20, 1.44, 1.73, 2.07, 2.49])  # 20% compounding
gems = (prices * base_gems_per_dollar * step_bonus).astype(int)
# [99, 599, 1438, 3457, 10339, 24875]
```

### LiveOps personalization (segment-based)
```typescript
function pickLadder(player: Player) {
  if (player.spendTier === "whale") return LADDER_WHALE;       // higher caps
  if (player.spendTier === "minnow") return LADDER_MINNOW;     // smaller steps
  if (player.daysActive < 7) return LADDER_NEWBIE;             // gentle on-ramp
  return LADDER_DEFAULT;
}
```

### A/B test harness
```typescript
const variant = await abTest.assign(uid, "staircase_v3", ["control", "20pct", "30pct"]);
const ladder = LADDERS[variant];
analytics.track("staircase_assigned", { uid, variant });
```

### Anti-fraud (replay / receipt reuse)
```csharp
if (await db.usedReceipts.exists(receipt.transactionId))
    throw new Exception("receipt replay");
await db.usedReceipts.insert(receipt.transactionId);
```

## 매 결정 기준
| 상황 | Approach |
|---|---|
| 신규 game launch | 6-step ladder, $0.99 → $99.99, 20% compounding bonus |
| Mid-core (deeper meta) | 8-step ladder + branch (gems vs energy) |
| Whale segment | extended ladder with $499.99 cap |
| Conservative market (KR/JP) | smaller steps, less aggressive cooldown |
| LiveOps event | event-specific staircase (limited cosmetic) |

**기본값**: 6 step / 20% compounding value / 24h cooldown / 7-day reset / server-side validation. 매 personalization 의 LiveOps 적용 권장.

## 🔗 Graph
- 부모: [[Mobile-Game-Monetization]] · [[F2P-Design]]
- 변형: [[Battle-Pass]] · [[Subscription-Model]] · [[Gacha]] · [[Loot-Box]]
- 응용: [[Match-3-Games]] · [[Casual-Mobile]] · [[Mid-core-Mobile]]
- Adjacent: [[LiveOps]] · [[Player-Segmentation]] · [[Cialdini-Persuasion]] · [[IAP-Receipt-Validation]]

## 🤖 LLM 활용
**언제**: ladder value tuning simulation, copywriting (urgency / FOMO 문구), A/B variant generation, segment definition.
**언제 X**: predatory targeting (minor / addiction-prone) — 매 ethical / regulatory (EU Digital Fairness Act) 의 violation 위험.

## ❌ 안티패턴
- **No cooldown**: 매 instant 의 ladder rush → revenue spike 후 churn.
- **Client-side validation only**: 매 cheat tool 의 free unlock. 매 server-side mandatory.
- **Aggressive whale-targeting**: regulatory backlash (UK gambling commission, EU DFA, KR 게임법).
- **No reset / branching**: late-game player 의 의 ladder 소진 후 dead content.
- **Same ladder for everyone**: 매 segment-blind 은 LTV leave on table.
- **Hidden true price-per-gem**: 매 dark pattern 의 trust 파괴 + Apple/Google 의 reject 위험.

## 🧪 검증 / 중복
- Verified (Deconstructor of Fun analyses, GDC monetization talks 2024-2025, Adjust mobile economy reports, Sensor Tower top-grossing case studies).
- 신뢰도 A.

## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — staircase mechanic + Unity/Firebase implementation |
