全程用 AI 做一款商业级手游 · EP6 留存系统:让玩家明天还回来
EP4/EP5 把变现做出来了。但变现有个前提——得有人来玩。一款 F2P 游戏的引擎是两个齿轮咬合:留存供给流量,变现把流量变成钱。这一集(EP6)做留存这半边,三件套:离线收益、每日连签、主题皮肤。
这一集的三件套接上 UI 后,真机里长这样(Unity 实拍)——每日登录的 7 天连签阶梯(D7 金色大奖)+ 皮肤面板(4 套皮肤各带配色预览):


皮肤不是摆设——点"霓虹"装备后,棋盘上的方块配色实时切换(同一局,左前面是经典配色,这里换成霓虹):

下面讲实现。我想先重点讲一个看似不起眼、却决定了"这套逻辑能不能被验证"的工程决定——怎么处理"今天"。
工程关键:把"今天"做成可注入的参数
连签系统天生难测:它依赖"日期变化"。如果代码里直接写 DateTime.Now,那测试就得改系统时钟、或等到明天——根本没法在一次 execute_code 里跑完"首登→次日→断签"。
解法是把时间从逻辑里抽出来:留存账本只认一个 long todayDay(UTC 天序号),由调用方传入。真机用 DayOf(现在的 unix 秒),测试直接传 100, 101, 103。
public class RetentionModel : Singleton<RetentionModel>
{
public readonly Property<long> lastLoginDay = new("ret.lastLoginDay", 0L);
public readonly Property<int> loginStreak = new("ret.loginStreak", 0);
public readonly Property<int> totalLoginDays = new("ret.totalLoginDays", 0);
public CheckInResult CheckIn(long todayDay)
{
if (lastLoginDay.Value == todayDay && totalLoginDays.Value > 0)
return CheckInResult.AlreadyToday; // 同日重复
bool consecutive = lastLoginDay.Value != 0 && todayDay == lastLoginDay.Value + 1;
loginStreak.Value = consecutive ? loginStreak.Value + 1 : 1; // 接上昨天→+1,否则归1
lastLoginDay.Value = todayDay;
totalLoginDays.Value += 1;
return CheckInResult.NewLogin;
}
public static long DayOf(long unixSeconds) => unixSeconds / 86400L;
}
把不确定性(时钟)挡在边界上,核心逻辑就变成纯函数式的——给定 todayDay,输出确定。这一条让连签的 8 个断言能在一秒内跑完。
三件套都复用同一条经济曲线
留存奖励发的也是金币,所以它们全部复用 EP4 的 EconomyConfig——奖励金额跟着玩家进度(最高分)缩放。每日奖励表只配 coef:
public int ClaimDaily(long todayDay)
{
if (Model.CheckIn(todayDay) == CheckInResult.AlreadyToday) return 0;
int streak = Model.loginStreak.Value;
var day = Daily.ForStreak(streak); // 7 天循环
int coins = Econ.CoinsFor(day.coinCoef, UserDataModel.Instance.curLevel.Value);
CoinModel.Instance.ChangeCoin(coins, "daily:d" + streak);
// ...发道具、广播 DailyRewardClaimedMsg
return coins;
}
离线收益同理——按离开时长(封顶 8 小时)折算成一个 coef,再走经济曲线:
public int PreviewOffline(long lastQuitUnix, long nowUnix)
{
if (lastQuitUnix <= 0 || nowUnix <= lastQuitUnix) return 0;
float hours = (nowUnix - lastQuitUnix) / 3600f;
if (hours > OfflineCapHours) hours = OfflineCapHours; // 8h 封顶
return Econ.CoinsFor(OfflineCoefPerHour * hours, UserDataModel.Instance.curLevel.Value);
}
画出来是这样——左边 7 天连签阶梯(D7 是大奖,最高分 30 整体比最高分 1 高,因为随进度缩放),右边离线收益涨到 8 小时后封顶:

封顶是关键设计:没有它,玩家放一周回来一次性领走天量金币,经济就崩了;有它,最优策略变成"每 8 小时回来一次"——这正是离线收益想培养的回流习惯。
主题皮肤:三种解锁规则,数据化
皮肤是消耗变现之外的另一种付费/留存抓手。三种解锁规则(免费 / 金币 / 最高分),全在数据资产里配,加皮肤不改代码:
public UnlockResult TryUnlock(string id)
{
if (!Cfg.TryGet(id, out var t)) return UnlockResult.NoSuchTheme;
if (IsOwned(id)) return UnlockResult.Owned;
switch (t.unlock)
{
case UnlockKind.Free:
AddOwned(id); return UnlockResult.UnlockedFree;
case UnlockKind.BestScore:
if (UserDataModel.Instance.bestScore.Value < t.cost) return UnlockResult.NeedScore;
AddOwned(id); return UnlockResult.UnlockedFree;
case UnlockKind.Coins:
if (!CoinModel.Instance.ChangeCoin(-t.cost, "theme:" + id)) return UnlockResult.NeedCoins;
AddOwned(id); return UnlockResult.Bought;
default:
return UnlockResult.NoSuchTheme;
}
}
金币解锁直接复用 CoinModel.ChangeCoin 的扣费——余额不足它返回 false,解锁自然失败。整个系统又一次站在 EP4 那套货币地基上。
验证:24 条断言
==== 24/24 PASS ====
A 首登发放金币>0 / streak==1 / 领取消息触发
A 同日重复领取==0 / 不增加累计登录
A 次日连签 streak==2
A 断签后 streak 重置为1 / 累计登录==3(去重)
B 离线2h预览>0 / 封顶(100h==8h) / 从未离开==0
B 离线结算余额增加 / 消息金币一致
C 默认拥有classic / 免费解锁 / 金币不足失败 / 金币足够购买且扣费
C 最高分不够失败 / 最高分达标解锁 / 装备成功且广播 / 装备未拥有失败
钉死的核心:连签断签必须归 1(不能漏一天还连着)、同日重复不能重复领、离线必须封顶(100h==8h)、主题金币不足/最高分不够必须解锁失败且不发放、装备只能装已拥有的。留存奖励直接发钱,错一条都是白送或刷取漏洞,所以全用断言锁死。
这一集的产物与诚实的话
RetentionModel(登录账本,时间可注入)+RetentionController(连签 + 离线发放)+DailyRewardConfig(7 天表)+ThemeModel/ThemeConfig(皮肤)。- 两个数据资产进 Resources,运行时加载。
- 24 条断言全绿。
诚实地讲:这一集做的是留存的逻辑与数值层。还没做的:弹窗 UI(登录领奖弹窗、离线收益结算弹窗、皮肤商店面板)——那是表现层,和 EP7 一起做;以及真正拉动留存的推送通知(本地/远程 push 提醒玩家回来),那需要平台能力和后台,属于发布阶段。但"明天回来能拿什么、连签怎么算、离线怎么折算、皮肤怎么解锁"——这套决定留存经济的算法,已经建好并验证了。
下一篇 EP7:表现层与手感(juice)——把前 6 集积累的纯逻辑接上动效、音频(程序化合成)、震动反馈,让它从"能跑的系统"变成"摸起来爽的游戏"。
- 工具:funplay-unity-mcp
- 开源工程:本系列做出来的完整 Unity 工程已开源
- 上一篇:EP5 商城 + 内购
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)