用最少素材撑起最长跑道
放置经营游戏的命门是长线供给——玩家要连续几周每天上线,头顶必须永远挂着"下一个够得着的目标"。 Eatventure 的答案是 三层递进 + 模板/槽位分离 + 首城教学母版:53 套餐厅模板跨城重组成 416 个关卡槽位, 靠 ID 编码 + 数值放大自动生成,而不是手搓 416 个关。本篇拆清"递进"到底怎么搭出来。
①设计目标:递进做"宽"不做"深",内容靠"复用"不靠"新增"
内容是最贵的:手工设计 400 个不同关卡,成本不可承受。进度结构就是对"长线供给 vs 内容成本"这对矛盾的回答,落到两个根本取舍(承自 00 总览 取舍 1「宽度优先」):
1 · 递进做"宽"不做"深"
不让玩家在一家餐厅里死磕到底,用 60 城 × 7 餐厅 横向铺开 + 数值断层,不断把人推向"下一个"。
2 · 内容靠"复用"不靠"新增"
53 个餐厅模板跨城重组成 416 个关卡槽位,换皮 + 数值放大就当新关卡用,新增成本趋零。
②机制:四层嵌套结构 + 三层递进节奏
2.1 四层嵌套:同一套"升级→收入→解锁"在不同尺度复用
游戏把"关卡"拆成四层,每层都是独立的进度循环,机制完全同构,只是尺度不同:
City(城市) ── 大关:换真实城市皮、抬经济量级 cityMult └─ Restaurant(餐厅 / 关卡槽位) ── 关卡:独立升级树 + 布局 + 菜品 └─ Station(产线工位) ── 关卡内节点:升 5 星 + 利润里程碑 └─ Item / Food(出餐物) ── 工位产出:各有利润 / 速度升级链
City · 60 个城序
世界配置的城市列表正好 60 个城市配置实例(城序 0–59)。
Restaurant · 每城 6–7 家
全程靠 53 个模板复用拼出(§3 详述),对应餐厅配置。
Station / Item · 微循环节点
关卡内主循环主体(见 01 核心循环),本篇只用其深度参数工位满级深度。
同构复用
四层都是"升级花钱 → 提高产出 → 解锁下一个",换的只是尺度与皮肤——这是结构性省成本的根。
2.2 三层递进 ★(用户最关心的"递进")
把四层一展开,玩家实际体验到的是 三层嵌套的递进节奏,每层解决不同时间尺度的"下一个目标":
| 递进层 | 时间尺度 | 玩家看到的 | 驱动力 |
|---|---|---|---|
| 城内递进 | 几十分钟~几小时 | 首关小摊(1 道菜)→ 末关正餐(10 道菜),7 关逐级变深变宽 | 解锁下一家餐厅 |
| 城际递进 | 几小时~几天 | 做满一城 7 家 → 飞往下一座真实城市(环游世界) | 换皮新鲜感 + cityMult 抬基线 |
| 轮次递进 | 长线(周级) | 15 城走完 → 同 15 城换季节皮回炉第 2/3/4 轮 | 周目重置 + 量级跃升 |
城内:LemonadeStand → … → FineDining (7 关:小摊→正餐梯度) └─ 做满 → 飞下一城 ───────────────┐ 城际:SanFrancisco → NewYork → … → MexicoCity (15 真实城环游世界) │ └─ 走完 15 城 → 进入下一轮 ──────┐ │ 轮次:第1轮 → 第2轮 → 第3轮 → 第4轮 (×4 周目,换季节皮 + cityMult 放大)
③数据与公式:模板 vs 槽位,ID 编码
3.1 餐厅"模板"与"关卡槽位"分离 ★
这是整套进度结构最省成本的一招,必须分清两个概念:
餐厅模板 = 设计资产
餐厅配置:升级线 + 菜品 + 布局的一套配置,共 72 个。
关卡槽位 = 进度单位
玩家实际推进的一个个"关",每个唯一 ID。60 城 × 6–7 家 = 416 个槽位(逐城求和)。
模板数远小于槽位数,因为模板跨城反复复用:
| 维度 | 数字 | 说明 |
|---|---|---|
| 主线城市实际引用的不同模板 | 53 | 主线解锁顺序去重 |
| 主线 53 模板撑起的关卡槽位 | 416 | 60 城餐厅数求和 |
| 副本 / 活动 / 主题专属模板 | 19 | 72 − 53(Greek/Pirates 副本 + Mine/Moon/Seaport/PotionShop 主题 + 活动) |
| 模板总数 | 72 | 全部餐厅模板 |
*_Snow / *_NoHouse / 季节变体等被标成"主线"但未进任何城解锁链的边角模板。复用的极端例子:
同一套配置在不同城是不同 ID 的"新关卡",玩家感知靠 cityMult + station 公比把数值量级拉开(换皮 + 放大)。没有一个主线模板只用 1 次。
3.2 餐厅 ID 编码:把"哪城哪关"压进一个整数
槽位 ID 用一套编码规则生成,同时承担"定位"和"解锁门控"两个职责:
编码结构
ID 工具提供城基数常量 1000,以及"按城序+城内序号取餐厅 ID""从餐厅 ID 取城序""从餐厅 ID 取城内序号"三个方法。
算式佐证
所有解锁门控值(§5)都精确落在 (城序+1)×1000 整千边界(2000=第2城、4000=第4城、6000=第6城),与该编码规则完全自洽。
3.3 城内深度梯度:首城作为"教学母版" ★
进度结构里最精细的设计在 首城 SanFrancisco 的 7 关——它不是随便排的小摊到正餐,而是 一关引入一个新维度 的教学母版:
| 序 | 餐厅 | 工位深度 (工位满级) | 菜品数 | 功能升级线 | 这一关新引入的维度 |
|---|---|---|---|---|---|
| 1 | LemonadeStand | 25 | 1 | 2(雇工/拉客) | 最小闭环:单品摊,只教"升级→提速" |
| 2 | FoodStand | 50 | 2 | 3(+提速) | 多菜品 + 工人移速 |
| 3 | FoodTruck | 75 | 3 | 4(+全品利润) | 全品利润倍率 |
| 4 | Cafe | 150 | 4 | 5(+加桌) | 堂食/桌位(桌位数) |
| 5 | FastFood | 150 | 5 | 4 | 并发产线变宽 |
| 6 | DriveThru | 150 | 7 | 4(含车位数) | 得来速车流机制 |
| 7 | FineDining | 250 | 10 | 5(全维度) | 满配正餐,所有维度齐活 |
深度 · 蓝柱 25→250
工位满级深度是"单个工位升满要多少级"(餐厅配置的工位满级字段)。首关 25 级几分钟做满,末关 250 级要磨很久——单关时长本身就是一条梯度。
宽度 · 红线 1→10
每关多 1–2 道菜,并发产线越来越多,收入结构越来越复杂。
维度 · 绿线逐关补齐
第 1 关只有 2 条升级线(最小可玩闭环),第 4 关补"加桌",第 6 关补"得来速",第 7 关五维全开。新玩家每过一关只需学一个新概念。
3.4 关卡场景:区域 / 工位 / 顾客位 / 桌位 / 边界
每个槽位的"物理容量"由布局配置定义(72 行,是数据量最大的一张布局表):
| 布局元素 | 含义 | 样本(FineDining 系大店 vs LemonadeStand 系小摊) |
|---|---|---|
| 区域数 | 分区解锁,对应子区域 | 大店 2 / 小摊 1–2 |
| 工位数 | 并发产线 | 大店 10 / 小摊 2 |
| 顾客位 | 顾客排队位 | 大店 40 / 小摊 5–6 |
| 堂食桌位 | 堂食桌位数 | 大店 6 / 小摊 0–1 |
| 运输停靠点 | 跨区物流停靠点 | 主题/副本店才有 |
| 场景边界尺寸 | 布局网格宽×高 | 大店 8×42 / 小摊 6×3 |
| 区域连接点 | 跨区寻路接口 | 大店 2 / 小摊 0 |
布局复杂度(区域数、工位数、网格密度)随关卡递进同步抬升——"关卡难度/容量"被做成了可见的物理载体。区域之间通过区域连接点连通,工人靠跨区寻路任务在区域间移动(运行时逻辑,布局只给静态拓扑)。
④城际与轮次:环游世界 + 周目回炉
4.1 城际推进顺序:15 真实城市 × 4 轮 = 60
主线推进顺序就是真实的环游世界路线:
然后同 15 城回炉 3 轮(后缀 2/3/4),到 MexicoCity4(城序 59)收尾。第 2/3/4 轮换的是季节/装饰皮(如 *_Snow 雪景、*_park 公园皮)和不同的餐厅组合,骨架不变。下表节选 9 座代表性城市(首城 / 轮次起点 / cityMult 拐点 / 满级),行数据与全量表一致:
| 城序 | 城市(轮) | 真实城 | cityMult | 关数 | 城内餐厅解锁顺序 |
|---|---|---|---|---|---|
| 0 | SanFrancisco | SanFrancisco | 1.0 | 7 | LemonadeStand → FoodStand → FoodTruck → Cafe → FastFood → DriveThru → FineDining |
| 1 | NewYork | NewYork | 1.1 | 6 | HotDogStand → Kiosk → CoffeeTruck → Pizzeria → CafeArabica → Diner |
| 14 | MexicoCity | MexicoCity | 2.4 | 7 | IceCreamStand → TacoStand → FoodTruck → TapasBar → BurritoKing → MocktailBar → DriveThruTakeOut |
| 15 | SanFrancisco·2 | SanFrancisco | 2.5 | 7 | HotDogStand → FoodStand → RamenTruck → Cafe → JoghurtHouse → LobsterHouse → Diner |
| 21 | Venice·2 | Venice | 3.1 | 7 | LemonadeStand_NoHouse → BigIceCreamStand → CoffeeTruck → CafeNapolita → BaklavaShop → TapasBar → Italiano |
| 22 | Beirut·2 | Beirut | 4 | 7 | IceCreamStand → FlowerBoutique → IceCreamTruck → KebabShop → CafeArabica → BaklavaShop → MezzeBar |
| 30 | SanFrancisco·3 | SanFrancisco | 12 | 7 | LemonadeStand → FoodStand → FoodTruck → Cafe → FastFood → DriveThru → FineDining |
| 45 | SanFrancisco·4 | SanFrancisco | 27 | 7 | HotDogStand → FoodStand → RamenTruck → Cafe → JoghurtHouse → LobsterHouse → Diner |
| 59 | MexicoCity·4 | MexicoCity | 41 | 7 | IceCreamStand → TacoStand → FoodTruck → TapasBar → BurritoKing → MocktailBar → DriveThruTakeOut |
节选说明:城 0(首城教学梯度)、城 1(NewYork 系全程唯一 6 关)、城 14(第 1 轮收尾)、城 15/30/45(橙色分隔线 = 第 2/3/4 轮起点)、城 21→22(cityMult 由 +0.1 缓坡转 +1.0 陡坡的拐点)、城 59(满级 ×41)。NewYork 系全程 6 关、其余城 7 关,60 城逐城求和 = 416 槽位。
4.2 cityMult:城际倍率为何"压平"
放置游戏最容易翻车的是经济量级失控。Eatventure 把"指数爆炸"和"城际推进"刻意分开——指数留给工位(base^itemType)和升级(B^level),城际倍率 cityMult 做成温和的分段线性:
cityIdx ≤ 21: cityMult = 0.1 × cityIdx + 1.0 # city0=1.0 … city21=3.1,每城 +0.1 cityIdx > 21: cityMult = cityIdx − 18 # city22=4.0 … city59=41.0,每城 +1.0
满级 60 城也才 ~41×,而不是指数级。前 22 城几乎压平(缓坡),22 城后转成更陡的线性。这意味着:
新鲜感靠"重置 + 换皮"
换城的新鲜感主要靠"重置爬坡 + 换皮"驱动,而非 cityMult 本身爆量级——玩家到新城从 station0 重新爬,靠新地图对抗疲劳。
轮次量级藏在线里
第 1 轮(城 0–14)cityMult 1.0–2.4,第 4 轮(城 45–59)已到 27–41×,但全程线性可控,不会失控。
⑤关卡进度与解锁门控(通关判定 / 功能进度解锁 / 进度记录)
5.1 通关判定:全部工位满级
一家餐厅"做完了"的判定,是它所有工位都升到满级。游戏用"工位满级"逐工位判定,关卡完成 = 全部工位满级。判定逻辑由工位等级与餐厅配置的工位满级深度比较得出:
# 单工位满级 def StationIsMaxed(station): return station.Level >= restaurant.max_station_level # 工位满级深度 # 关卡通关:所有工位满级 → 解锁下一家餐厅 def RestaurantCompleted(restaurant): return all(StationIsMaxed(st) for st in restaurant.stations) # 城市完成:城内全部餐厅通关 → 解锁下一城 def CityCompleted(city): return all(RestaurantCompleted(r) for r in city.restaurants)
5.2 侧系统解锁:用主线 ID 当门控
侧系统不维护自己的进度,而是复用 §3.2 的餐厅 ID 当主线进度标尺,到达某 ID 即解锁:
| 解锁点 | 门控值 | 解锁内容 |
|---|---|---|
| 餐厅 ID 2000 | 第 2 城开头 | 副本面板 |
| 餐厅 ID 4000 | 第 4 城开头 | 万能钥匙 MasterKeys(+ Vault 装备升级库,同门控) |
| 餐厅 ID 6000 | 第 6 城开头 | 俱乐部 Clubs |
| 玩家等级 3 | 早期 | 限时活动 Event |
# FeatureProgressionUnlock 判定(基于主线进度标尺) def feature_unlocked(feature): if feature.gate_type == "restaurantId": return player.max_reached_restaurant_id >= feature.unlock_restaurant_id elif feature.gate_type == "level": return player.level >= feature.unlock_level
5.3 进度记录
进度记录是埋点/进度记录系统(技术底座),记录玩家当前城/餐厅/工位进度,供存档、推送召回、运营分析使用。无玩法数值,归附录,此处仅登记不展开。
⑥平衡与节奏:三层递进如何咬合
把前面的机制合起来看节奏设计——三个尺度的钩子永远同时挂着:
| 时间尺度 | 递进层 | 旋钮 | 防疲劳手段 |
|---|---|---|---|
| 几十分钟 | 城内 7 关 | 工位满级 25→250(单关时长梯度) | 逐关加维度(教学母版),每关都有"新东西" |
| 几小时~天 | 城际 15 城 | 换真实城市皮 + cityMult 缓抬 | 重置爬坡(新城从 station0 重来)+ 环游世界叙事 |
| 周级 | 轮次 ×4 | 季节皮 + cityMult 线性放大(→41×) | 周目回炉,熟悉骨架 + 量级跃升给"变强"实感 |
这是 Eatventure 进度结构的精髓:用 53 个模板 + 一条压平的 cityMult + 逐关加维度的母版,就让玩家在任意时刻都看得到三个不同远近的"下一个目标"。成本上,416 个关卡只手搓了 53 套配置,剩下全靠 ID 编码 + 数值放大自动生成。
⑦关键发现 / 对自研的借鉴
1 · 模板/槽位分离是省成本核心
53 模板 × 跨城重组 = 416 槽位,换皮 + cityMult/station 公比放大就当新关。要长线供给时,优先"少量模板 × 大量复用",而非手搓每关。
2 · ID 编码一举两得
(城序+1)×1000+城内序号 既定位关卡,又当主线进度标尺给侧系统做解锁门控——侧系统不需要各自维护进度变量。
3 · 首城是教学母版,单独打磨
用工位满级 + 菜品数 + 功能线数三条梯度,让新手每关只学一个新维度;甚至跑 A/B 实验调首城长度。
4 · 城际倍率要"压平"
把指数留给关卡内。cityMult 分段线性(满级仅 ~41×)保护经济不失控,换城新鲜感靠"重置爬坡 + 换皮"而非倍率。
5 · 三层递进套娃,铺满全时间尺度
城内(分钟)/ 城际(天)/ 轮次(周)三个尺度的目标同时在线,是放置游戏对抗"无目标流失"的结构性答案。
⑧关键数值速览
| 结构 | 关键数值 |
|---|---|
| 城市规模 | 60 城 = 15 真实 × 4 轮、环游世界推进顺序 |
| cityMult | 分段线性、满级 ~41× |
| 模板/槽位 | 72 模板 / 53 主线复用 / 416 槽位 |
| ID 编码 | ID = (城序+1)×1000+城内序号 |
| 首城梯度 | 首城 7 关深度/菜品/功能逐关递进 |
| 布局元素 | 区域 / 工位 / 顾客位 / 桌位 / 边界 |
| 解锁门控 | 2000 / 4000 / 6000 / 等级 3 |
| 通关判定 | 全部工位满级 → 解锁下一关 |
| Vault 门控 | 与万能钥匙共用 4000,无独立数值表 |