9.2 首充、月卡、通行证

首充、月卡、通行证是 SLG 里最稳定的三类常规付费点,共同点是「高性价比换玩家行为」。本节用 config/pricing.json 的真实参数,逐个算清首充的双倍倍率、月卡的逐日累计与回本天数、通行证的双轨增量价值,并用 P 层 TypeScript 原型做跨语言对照。

9.1 的归一化把八个付费点分成三层,其中时长绑定层(首充 200%、月卡 300%、通行证 520%)是溢价最高的一层。这一层为什么值得给这么高的性价比?因为它们卖的不是即时价值,而是玩家的后续行为——首充换「第一次掏钱」,月卡换「30 天登录」,通行证换「一个赛季的活跃」。本节把这三个点逐个拆开,算清它们的价值结构。定价档位本身仍留第 10 章,本节只算「买到的价值」,不算「卖多少钱」。

三个点放在一起看,有一个共同的骨架:一次付费,换一段持续的行为。理解了这个骨架,就能理解为什么它们的性价比可以远高于直充——行为本身就是设计要买的东西,溢价是买行为的成本。

首充:一次性拉过第一道门槛

首充的参数在 config/pricing.json 的 firstCharge 里:售价 600 分(6 元),给 120 玉璧。对照基准档 t1(600 分给 60 玉璧),首充就是双倍:

首充每元玉璧 = 120 × 100 / 600 = 20
相对基准档倍率 = 120 × 1000 / 60 = 2000‰

2000‰ 这个数就是「拉门槛」的定价。首充的设计目标不是赚钱,是把非付费玩家推过从 0 到 1 的那道心理门槛。玩家第一次付费的心理阻力远大于第十次——一旦付过,后续付费的心理账户就打开了。所以首充给双倍,本质是买「第一次付费」这个行为,而不是买 120 玉璧。

首充的关键约束是一次性:只能买一次,且通常在「首次进入付费页」时强提示。如果首充可以反复买,它就退化成一个 200% 性价比的常规礼包,会击穿直充。一次性 + 双倍,缺一不可。

月卡:把一次付费换成 30 天登录

月卡的参数在 monthlyCard 里:售价 3000 分(30 元),立即到账 300 玉璧,之后 30 天每天可领 20 玉璧。总价值 = 300 + 20 × 30 = 900 玉璧,每元 900 × 100 / 3000 = 30 玉璧。

月卡最反直觉的地方是回本天数。售价折玉璧 = 3000 / 10 = 300 玉璧,而立即到账就是 300——第一天就回本。就算拿「直充 t2 档」(3000 分给 300 + 5% = 315 玉璧)当基准,累计到第 1 天是 300 + 20 = 320 ≥ 315,同样是第一天回本:

天数累计玉璧是否回本(对 315)
1320✅
2340✅
30900✅

第一天就回本,剩下 29 天每天 20 是净赚——这就是月卡让人「忍不住买」的数学。但它有个隐藏条件:你得每天登录来领。如果玩家买了月卡却不上线,那 20 玉璧/天就领不到。用登录天数 k 折算:

登录天数 k实得玉璧每元玉璧
3090030
2070023
1050016
540013
030010

这张表说明月卡的真实性价比取决于玩家的登录行为:全勤 30 玉璧/元,只登录 10 天就掉到 16,一天不登录则和直充持平(10)。月卡不是「送玉璧」,是「用玉璧买登录」——这也是它为什么被归到「进度 + 便利」两种动机:它既推进度,又天然绑定日常习惯。

月卡的设计纪律:每日领取的门槛要低(一键领取、进游戏即弹),否则玩家会因为「忘了领」而产生负面情绪,把月卡变成投诉源。绑定的目的是养成习惯,不是惩罚遗忘。

通行证:把付费和赛季活跃绑在一起

通行证(战斗通行证 / Battle Pass)的参数在 battlePass 里:售价 6800 分(68 元),赛季 60 天,免费轨奖励价值 1200 玉璧,付费轨奖励价值 3600 玉璧。这里要分清两个价值口径:

全额口径(含免费轨) = 3600 × 100 / 6800 = 52 玉璧/元
增量口径(付费轨 - 免费轨) = (3600 - 1200) × 100 / 6800 = 35 玉璧/元

通行证是双轨结构:免费轨 1200 玉璧人人可得(这是基础体验保护,见 9.3),付费轨额外给 2400 玉璧。所以衡量通行证「值不值」,应该用增量口径 35——玩家花 68 元,真正比免费玩家多拿的是 2400 玉璧的价值。用 52 去宣传是虚高,因为它把免费轨本来就能拿的部分也算进了付费价值。

通行证和月卡一样绑定行为,只是绑的是赛季活跃。如果通行证奖励随赛季活跃天数线性解锁(这是一个建模假设,真实规则由具体设计决定),折算如下:

赛季活跃天数累计价值每元玉璧
60360052
45300044
30240035
15180026

只有打满整个赛季,通行证才值 52 玉璧/元;活跃 30 天掉到 35,15 天掉到 26。通行证的设计目标就是把「买了通行证」的玩家变成一个赛季都泡在游戏里的人——它是三者里行为绑定最重、周期最长的一个。

P 层原型:三类付费点的估值

下面这段是 P 层 TypeScript 原型。它和 9.1 的 S 层脚本消费同一份 config/pricing.json,用整数运算复刻首充倍率、月卡累计与回本天数、通行证增量价值,供跨语言对照:

// file: proto/src/n09_payment.ts
// tier: P
// verify: node --test proto/test/n09.test.ts
// 首充 / 月卡 / 通行证估值原型:与 sim/n09_payment_value.py 消费同一份 config/pricing.json,
// 全程整数运算(Math.floor 地板除),跨语言逐位一致,用于月卡逐日累计与回本天数对照。

import { loadConfig } from "./core.ts";

export interface Tier { id: string; priceCents: number; jade: number; bonusPct: number }
export interface Pricing {
  currency: { id: string; name: string; perYuan: number };
  tiers: Tier[];
  firstCharge: { priceCents: number; jade: number };
  monthlyCard: { priceCents: number; days: number; immediateJade: number; dailyJade: number };
  battlePass: { priceCents: number; seasonDays: number; freeRewardValue: number; paidRewardValue: number };
}

export function loadPricing(): Pricing {
  return loadConfig<Pricing>("pricing");
}

export function jadePerYuan(valueJade: number, priceCents: number): number {
  return Math.floor((valueJade * 100) / priceCents);
}

export interface FirstChargeValue {
  jade: number; priceCents: number; jadePerYuan: number; multipleVsT1Permille: number;
}
export function firstChargeValue(p: Pricing): FirstChargeValue {
  const fc = p.firstCharge;
  return {
    jade: fc.jade, priceCents: fc.priceCents,
    jadePerYuan: jadePerYuan(fc.jade, fc.priceCents),
    multipleVsT1Permille: Math.floor((fc.jade * 1000) / p.tiers[0].jade),
  };
}

export interface MonthlyCardValue {
  priceCents: number; days: number; immediateJade: number; dailyJade: number;
  totalJade: number; jadePerYuan: number; priceJade: number;
  breakevenVsPriceDay: number; directT2Jade: number; breakevenVsDirectDay: number;
  cumulative: number[];
}
export function monthlyCardValue(p: Pricing): MonthlyCardValue {
  const mc = p.monthlyCard;
  const centsPerJade = Math.floor(100 / p.currency.perYuan);
  const totalJade = mc.immediateJade + mc.dailyJade * mc.days;
  const priceJade = Math.floor(mc.priceCents / centsPerJade);
  const t2 = p.tiers[1];
  const directT2Jade = Math.floor((t2.jade * (100 + t2.bonusPct)) / 100);
  const cumulative: number[] = [];
  let run = 0, bePrice = 0, beDirect = 0;
  for (let d = 1; d <= mc.days; d++) {
    run += mc.dailyJade;
    const c = mc.immediateJade + run;
    cumulative.push(c);
    if (bePrice === 0 && c >= priceJade) bePrice = d;
    if (beDirect === 0 && c >= directT2Jade) beDirect = d;
  }
  return {
    priceCents: mc.priceCents, days: mc.days, immediateJade: mc.immediateJade, dailyJade: mc.dailyJade,
    totalJade, jadePerYuan: jadePerYuan(totalJade, mc.priceCents), priceJade,
    breakevenVsPriceDay: bePrice, directT2Jade, breakevenVsDirectDay: beDirect, cumulative,
  };
}

export interface BattlePassValue {
  priceCents: number; seasonDays: number; freeRewardValue: number; paidRewardValue: number;
  incrementalValue: number; jadePerYuanFull: number; jadePerYuanIncremental: number;
}
export function battlePassValue(p: Pricing): BattlePassValue {
  const bp = p.battlePass;
  const incremental = bp.paidRewardValue - bp.freeRewardValue;
  return {
    priceCents: bp.priceCents, seasonDays: bp.seasonDays,
    freeRewardValue: bp.freeRewardValue, paidRewardValue: bp.paidRewardValue, incrementalValue: incremental,
    jadePerYuanFull: jadePerYuan(bp.paidRewardValue, bp.priceCents),
    jadePerYuanIncremental: jadePerYuan(incremental, bp.priceCents),
  };
}

对应的 P 层测试断言 Python 侧跑出的同一组数(node --test proto/test/n09.test.ts):

// file: proto/test/n09.test.ts
// tier: P
// verify: node --test proto/test/n09.test.ts
// 跨语言对照:TS 侧与 Python 侧(sim/n09_payment_value.py)用同一份 config/pricing.json,
// 断言首充倍率、月卡累计与回本天数、通行证增量价值逐位一致。

import { test } from "node:test";
import assert from "node:assert/strict";
import { loadPricing, firstChargeValue, monthlyCardValue, battlePassValue } from "../src/n09_payment.ts";

test("首充:120 玉璧 = 基准档 60 玉璧的 2000‰,每元 20 玉璧", () => {
  const fc = firstChargeValue(loadPricing());
  assert.equal(fc.jade, 120);
  assert.equal(fc.jadePerYuan, 20);
  assert.equal(fc.multipleVsT1Permille, 2000);
});

test("月卡:30 天累计 900 玉璧,第 1 天即回本", () => {
  const mc = monthlyCardValue(loadPricing());
  assert.equal(mc.totalJade, 900);
  assert.equal(mc.jadePerYuan, 30);
  assert.equal(mc.priceJade, 300);
  assert.equal(mc.breakevenVsPriceDay, 1);
  assert.equal(mc.directT2Jade, 315);
  assert.equal(mc.breakevenVsDirectDay, 1);
  assert.deepEqual(mc.cumulative.slice(0, 3), [320, 340, 360]);
  assert.equal(mc.cumulative.at(-1), 900);
});

test("通行证:付费轨 3600 玉璧,增量价值 2400,每元 52 / 35", () => {
  const bp = battlePassValue(loadPricing());
  assert.equal(bp.paidRewardValue, 3600);
  assert.equal(bp.freeRewardValue, 1200);
  assert.equal(bp.incrementalValue, 2400);
  assert.equal(bp.jadePerYuanFull, 52);
  assert.equal(bp.jadePerYuanIncremental, 35);
});

本机实跑(Node 26 原生 TS,node --test proto/test/n09.test.ts)3 项全过:

✔ 首充:120 玉璧 = 基准档 60 玉璧的 2000‰,每元 20 玉璧
✔ 月卡:30 天累计 900 玉璧,第 1 天即回本
✔ 通行证:付费轨 3600 玉璧,增量价值 2400,每元 52 / 35
ℹ tests 3  ℹ pass 3  ℹ fail 0

Python 侧 sim/n09_payment_value.py 用同一份 config 跑出 centsPerJade=10、firstCharge.multipleVsT1Permille=2000、monthlyCard.totalJade=900、breakevenVsPriceDay=1、battlePass.incrementalValue=2400——与 TS 侧逐位一致。这是本套「一份配置两处消费」在商业化章节的落地:定价参数改一处,两侧估值同时更新,不会漂移。

三类付费点对照

把三个点放进同一张表,结构差异立刻显现:

付费点售价(分)价值(玉璧)每元玉璧绑定行为绑定周期
首充60012020首次付费一次性
月卡300090030每日登录30 天
通行证68002400(增量)35赛季活跃60 天

一个清晰的规律:绑定周期越长、行为要求越重,每元玉璧越高。首充只要「付一次」(20),月卡要「登录 30 天」(30),通行证要「活跃一个赛季」(35)。溢价与行为门槛同向增长——这是三个点的定价逻辑,不是巧合。通行证给得最多,是因为它要求的承诺最长、最难反悔(一个赛季都走完了)。

三个常见错误

  • 把首充做成可反复购买。首充 200% 的性价比只在「一次性」约束下成立。可反复买,它就变成击穿直充的常规礼包。
  • 用通行证的全额口径宣传性价比。52 玉璧/元里含了免费轨本来就能拿的 1200。玩家不付费也有 1200,增量只有 35。宣传用 52、玩家算出来 35,会直接伤害信任。
  • 月卡只算「送多少」不算「领不领得到」。月卡的 900 玉璧是理想值,实际取决于登录。如果每日领取门槛高,月卡会从「福利」变成「投诉源」。设计月卡时要先设计领取体验。

边界照旧:本节的估值只算「内容价值」,不含真实付费转化率。一个付费点值多少是一回事,有多少人会买是另一回事——后者要真实投放数据,属于 X 层——需真实业务环境,命令行不可复现。本节能做的是:给定配置,算出三类付费点的价值结构;它做不了的是:告诉你哪一类转化率最高。

小结

首充、月卡、通行证共用一个骨架:高性价比换玩家行为。本节的 P 层原型用 config/pricing.json 跑出首充 2000‰、月卡第 1 天回本、通行证增量 2400 玉璧,并演示了「绑定周期越长、每元玉璧越高」的规律。三个常规付费点的价值结构,从今天起是能被脚本复算、且跨语言对得上的数。

一句话记住本节:首充买首次、月卡买登录、通行证买活跃。三者都在买行为,不是买内容。

回到这一章:9.1 铺布局、9.2 拆三类常规付费点、9.3 定节奏与保护线。下一节回答最后一个问题——这些付费点在什么时候出现,以及怎样不把免费玩家逼走。

阅读导航:上一节:9.1 付费动机与付费点布局 · 下一节:9.3 付费节奏与体验保护 。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「slg」更多文章

  1. 12.3 留存与付费的联合分析
  2. 12.2 流失预警与召回
  3. 附录 C:全书公式、参数与数据集索引