我为2026年世界杯制作了一款足球预测游戏。为期一个月,共104场比赛,
最终决出一名获胜者。它运行良好,人们参与其中,没有出任何乱子。
随后,我将同一个应用应用于一个国内联赛:法国足球甲级联赛,共306场比赛,34个比赛日,
历时九个月。数据模型相同,计分规则相同,模板也相同。没有发生崩溃,没有
抛出异常。所有测试均保持通过状态。
然而,应用内几乎每一个产品决策突然间都变得错误百出。
以下是四个至关重要的问题,因为它们都不是技术性问题,而且没有任何一个
会在测试套件中显现出来。
1. 累计排行榜在十月便已尘埃落定
在杯赛制锦标赛中,总积分榜就是游戏的全部。你进行四周的比赛,
最终的榜单就是故事的核心。
而在长达34个比赛日的联赛中,大约到第八周时,这个榜单就不再具有游戏性了。起步良好的玩家
领先60分,十一月才加入的玩家在数学上已无望夺冠,
而其他所有人都在阅读一个他们无法改变的记分牌。产品功能依然正常,
只是不再有任何悬念。
解决方案并非更复杂的算法,而是引入第二个时间维度:每个比赛日的
独立排行榜,这样每个周末都有自己的获胜者,再加上一个赛季荣誉榜,统计
每位玩家赢得了多少个比赛日。积分和计分规则不变,只是切片方式不同。
总排名第十四位的玩家仍然可以赢得本周末的胜利,而这正是促使他们
在周五回归的动力。
值得注意的是,我没有做的事情:没有重置积分,没有让分机制,没有追赶奖励。任何
对人们正在参与的计分系统进行追溯性调整的行为,都会破坏对积分榜的信任,
而积分榜是整个产品的核心资产。
2. 滑动的24小时提醒变成了100封邮件
提醒任务是为杯赛制锦标赛设计的:“如果玩家有在未来24小时内开赛的未预测比赛,
就给他们发送邮件。”比赛每天零星进行,因此这相当于每天一封邮件,
体验尚可。
法甲的一个比赛日从周五20:45持续到周日20:45。同样的任务逻辑,若不加修改,
会在每个周末向同一用户发送三封邮件:周五因一场比赛发一封,周六因三场发一封,
周日因五场发一封。每赛季每位用户大约会收到一百封邮件。这不再是提醒,
而是变相的垃圾邮件投诉。
此外,邮件会在第一场比赛的早晨送达,而联赛中的自然行为恰恰相反:
用户通常会一次性填写全部九场比赛的预测,且时间随意,只要想起来就行。
因此,该任务现在在同一命令中拥有两条互不相关的代码路径。杯赛制锦标赛保留
滑动窗口机制。联赛则每个比赛日只发送一封邮件,当该比赛日的第一场比赛
距离开赛还有24至48小时时触发,列出该比赛日所有尚未预测的比赛。
我喜欢的一点是:这里没有 reminder_sent(提醒已发送)表。幂等性由窗口
本身保证。“第一场比赛距离开赛还有24至48小时”这一条件在日历上仅有一天成立,
而定时任务每天运行一次。唯一 legitimately(合理地)产生第二封邮件的情况是,
比赛延期导致第一场比赛重新落入该时间窗口内,而当赛程变动时,
恰恰正是你需要再次提醒用户的时候。
这种权衡在定时任务配置中以直白的文字体现:将定时任务频率加倍会导致
邮件数量加倍。注释比数据库表更廉价,只要注释位于可能出错的地方即可。
3. “即将进行的比赛”不等于“所有未来比赛”
仪表板列出了所有未来的比赛。在杯赛制锦标赛中,这最多只有几十张卡片,
进度徽章显示“已预测 12/18”,让人感觉可以实现。
在联
免责声明:本文内容来自互联网,该文观点不代表本站观点。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请到页面底部单击反馈,一经查实,本站将立刻删除。