数值实测
node tools/sim/night.mjs --hours 1 --policy active --trace # 开局到一小时
node tools/sim/night.mjs --hours 24 --policy active --trace # 二十四小时
node tools/sim/night.mjs --compare --hours 4 --runs 3 # 松手判据
配表全部写在 night.mjs 顶部(FOODS / SIGNATURES / COST / TUNING)。
改数不改码。改完必须重跑本文所有数字。
本文所有数字都是这个脚本的实测输出,没有一个字是估的。 报告口径:贪心策略(每次都买回本最快的那一项)跑 N 次取中位数。
一、前 10 分钟:节奏是设计出来的#
| 时间 | 金币 | 收入/秒 | 客流 λ | 产能 μ | 队伍 | 菜单 | 灶 | 店员 |
|---|---|---|---|---|---|---|---|---|
| 10 秒 | 28.6 | 2.8 | 0.5 | 0.4 | 1.0 | 1 | 1 | 0 |
| 30 秒 | 84.7 | 2.8 | 0.5 | 0.4 | 2.8 | 1 | 1 | 0 |
| 1 分 | 2.2 | 4.3 | 0.5 | 0.8 | 5.8 | 2 | 2 | 0 |
| 2 分 | 92.5 | 5.8 | 0.8 | 1.2 | 5.8 | 2 | 3 | 0 |
| 5 分 | 446 | 38.1 | 3.7 | 5.9 | 5.8 | 3 | 8 | 3 |
| 10 分 | 1.07 万 | 750 | 33.0 | 27.9 | 8.0 | 5 | 18 | 9 |
关键节点(中等运气的一轮):
| 事件 | 时间 |
|---|---|
| 第一枚金币 | 0.2 秒 |
| 第二口灶 | 1.0 分 |
| 菜单扩到两种 | 1.0 分 |
| 第一位店员 | 3.3 分 |
| 第一次升小费罐 | 5.2 分 |
| 第一位贵客 | 1.0 分 |
- 第一枚金币 0.2 秒。开局不能有任何等待——街上空着超过 2 秒,玩家就关掉了。
- 队伍长度前 1 分钟从 1 涨到 6。这是"我忙不过来"的第一次信号, 也是玩家第一次主动想去加灶。这个信号不能来得太早(开局就排满会让人焦虑), 也不能太晚(一分钟还没感觉就太平)。
- 3.3 分钟出现第一位店员。从这一刻起玩家可以松手了。 这是整局的第一个"我赢了"的时刻,不能晚于 5 分钟。
二、24 小时曲线#
| 时间 | 金币 | 累计收入/秒 | 客流 λ | 产能 μ | 菜单 | 灶 | 店员 |
|---|---|---|---|---|---|---|---|
| 5 分 | 663 | 39.6 | 3.9 | 5.8 | 3 | 9 | 2 |
| 10 分 | 7 677 | 783 | 33.8 | 27.9 | 5 | 18 | 9 |
| 30 分 | 57.53 万 | 2.15 万 | 158.0 | 120.2 | 8 | 34 | 19 |
| 1 时 | 691.42 万 | 10.47 万 | 269.2 | 200.0 | 9 | 41 | 24 |
| 2 时 | 3 898.44 万 | 30.98 万 | 400.4 | 296.6 | 10 | 48 | 28 |
| 4 时 | 108.67 万 | 135.04 万 | 594.7 | 450.1 | 12 | 58 | 32 |
| 8 时 | 4.41 亿 | 386.91 万 | 748.0 | 554.1 | 13 | 64 | 36 |
| 24 时 | 134.11 亿 | 1 165.51 万 | 955.5 | 707.7 | 14/20 | 72 | 41 |
- 4 时那一行金币反而变少了(3 898 万 → 108 万):因为刚买了一口大件。 "收入/秒"这一列是累计毛收入的增量,不含支出,所以是单调的。
- 24 小时解锁 14/20 道菜。剩下 6 道是长尾,按当时的收入率还要几十小时。 这是故意的——增量游戏不该在第一天就把菜单开完。
- λ 永远是 μ 的 1.35 倍(955.5 / 707.7)。这就是核心玩法 4.2 那个稳态解,说明"产能永远是瓶颈、队伍永远排到街角"这条设计成立。
三、松手判据#
判的是「一直点 ÷ 完全不点」,但要分两个口径看,混在一起会得出错误结论:
3.1 同一摊子状态下(纯系数)#
在场 ÷ 离场 = 1.30×
就是 TUNING.presentBonus = 0.3 这一项。这就是"注意力"的全部标价。
3.2 跑完整局(含复利)#
4 小时,三次取中位:
| 口径 | 收入率 | 相对离线 |
|---|---|---|
| 离线不点(idle) | 82.23 万/秒 | 1.00× |
| 在场不点(present) | 169.15 万/秒 | 2.06× |
| 在场一直点(active) | 209.89 万/秒 | 2.55× |
收入结构(active 一轮):贵客占 10%、小费占 1%,其余 89% 是挂机自动收入。
3.3 换算成时间口径#
这是工程约定里记过的一条: 指数档位下"差 3118 倍"换算成时间可能只是"落后 4 分钟"。 报倍数一定要同时给时间口径,否则会把自己吓到。
| 时点 T | 在场不点落后 | 一直点落后 |
|---|---|---|
| 10 分 | 1.8 分 | 3.4 分 |
| 30 分 | 7.9 分 | 14 分 |
| 1 时 | 17 分 | 29 分 |
| 2 时 | 35 分 | 56 分 |
离线会越落越远(落后时间随时间线性增长),因为收入增长本身在减速:
落后时间 = ln(倍数) / 增长率,增长率降下来,落后就拉长。
这是增量游戏的常态,不是缺陷:离线依然在完整地赚,只是慢一点。 真正的红线是收入率之比不发散——3.1 那一项恒等于 1.30×,就够了。
四、调参过程中踩的五个坑#
前四个是设计问题(调参救不了),第五个是工程问题。 每一个都是先跑模拟器才发现的,不是想出来的。
4.1 坑一:花钱买名气,λ 指数爆炸#
现象:模拟器跑 15 分钟就卡死;打日志看到 λ = 228 人/秒。
根因:把「名气」做成花金币买 +18%。λ 成为瓶颈时买名气给的是线性回报, 而它的涨价被其他轨道的收入增长抵消 → 回本时间恒定 → 无限正反馈。 这就是工程约定里那种"增长率差一点就有一条通吃"的刀刃失衡。
修法不是调参,是改设计:把名气从"花钱买"改成"跟着生意走"——
λ 向 1.35 × 实际成交率 一阶收敛。稳态只剩唯一自洽解,λ 再也不可能失控。
顺带把主界面的概念从 4 个砍到 3 个。
4.2 坑二:加了新菜,收入反而降#
现象:跑了 8 小时,菜单还是只有 1 种。解锁按钮明明买得起(120 金币),贪心策略就是不买。
根因:收入公式写成了「菜单均价 × 产能」。加一道便宜的新菜会拉低均价, 算出来的收益是负的,于是贪心永远不扩菜单。
修法:改成每口灶各自按自己的单价结算:
收入 = 产能利用率 × Σ(每口灶的 单价 / 出餐时间)。
修完顺带出来一条设计:"往灶上放哪道菜"看的是 p/t,不是 p。
4.3 坑三:新菜只配一口灶,把队伍整条堵死#
现象:解锁茶蛋和糖葫芦之后,λ 从 26.7 塌到 4.15,而产能还有 39 却卖不动。 打日志看到 待取 57 / 上限 60(货堆满了),队伍 7/8(人堵满了)。
根因:客人从菜单里均匀点单。新菜只配一口灶,却要分走 1/3 的客流, 那口灶供不上 → 点它的客人永远卡在队首 → 后面的人进不来。
修法(两条一起改才够):
- 客人按产能加权点单——需求 ∝ 供给,队列不会再被错配堵住;
- 解锁新菜时按
0.5 份/秒给它配够灶。
只改其中一条,问题还剩一半。
4.4 坑四:贪心策略自己停摆#
现象:跑 2 小时卡在 11.41 亿金币,收入一动不动。
根因:给贪心加了个"回本时间 < 900 秒才买"的门槛。 后期所有项的回本都超过了 900 秒,于是有钱也不花。
修法:改成"永远买当前最优",门槛交给各条轨道自己的涨价曲线去管。
4.5 坑五:离散化假象,λ 卡在 128.00#
现象:λ 涨到 128.00 就不动了,正好是 1.35 × 80。
根因:逐份撮合的模型里,每 tick 最多只能服务「排队位数」个客人—— 12 位 × 10 次/秒 = 120/s 的假上限,而真实产能有 317/s。 把步长调小能绕过,但 24 小时的局要跑几百万 tick。
修法:改成解析式结算(成交率 = min(λ, μ),按产能占比分摊到各道菜)。
顺带把 24 小时的局从跑不完变成几秒。
- 试算不能靠 JSON 快照:灶数上百之后每 0.5 秒序列化五遍,8 小时的局直接跑不完。
改成
apply()返回一个undo闭包。 - "收入/秒"这一列必须用毛收入:用净金币的话,买一次大件会让收入看起来掉 17 倍。
五、还没验的#
诚实列一下,这些是设计里写了但模拟器盖不到的:
| 项目 | 为什么没验 | 打算怎么验 |
|---|---|---|
| 前 60 秒的手感 | 模拟器量不到"爽不爽" | 做出可玩 demo,找 3 个人看前 60 秒 |
| 队伍满时的视觉密度 | 是渲染问题,不是数值问题 | 场景演示页跑 40 人同屏,量帧率 |
| 贵客的回头率是不是真的 +10% | 要真人行为数据 | 上线后埋点:贵客停留时长、点击转化 |
| 招牌组合的实际最优搭配 | 贪心策略没做组合搜索 | 模拟器加一个"菜单搜索"模式 |
| 离线 8 小时的上限是不是太短 | 需要真实留存数据 | A/B:8 小时 vs 24 小时 |