《游戏设计》卷二《策略、涌现与体验度量》目录

《游戏设计》卷二《策略、涌现与体验度量》目录:16 章 48 节,从卷一的可执行规格出发,把机制跑起来之后的动态与体验全部操作化为可计算指标——策略空间与 Shannon 熵、支配策略检测、极小极大与均衡、涌现与退化解、平衡与相变、玩家动因与类型、情绪曲线与心流带宽、技巧习得、体验度量与可玩性、参数反推。本页给出与既有内容的分工、六档可运行性口径与全书 16 章 48 节完整清单。

这是《游戏设计》三卷本的第二卷。它接住卷一留下的那条基线——一份可执行、可证明、跨宿主一致的玩法规格——然后问下一个问题:这份规格跑起来之后,会发生什么?玩家又会体验到什么?

卷一(《玩法机制与可执行规格》)做的是 M 层(Mechanics):机制怎么写成规格、规格怎么被 S / P / W / B 四处消费、四处怎么逐字一致。这一卷做的是 MDA 的另外两层:机制跑起来涌现出什么(Dynamics)、玩家因此体验到什么(Aesthetics)。站内这两层基本无人占,而它们恰恰是可计算、可跑、可比较的。

做法只有一句话:把「好玩」拆成能算的量。策略空间的 Shannon 熵、支配策略缺失度、涌现度、相变临界宽度、心流带宽、情绪张力曲线、可解率——每一个都是整数或千分比,都能从同一份 config/play_spec.json 真跑出来。它们是代理指标(proxy),只用于相对比较,不用于证明「好玩」。 这一点全书反复声明。

贯穿案例仍是虚构的卡牌构筑 Roguelike 《灰烬牌库》(工程名 ashdeck),底座与卷一完全相同:config/ 放规格,sim/ 是 Python 仿真,core/ 是 TypeScript 确定性内核,web/ 把内核内联进单文件 HTML 供无头浏览器真玩。

这套书与站内既有内容的分工

站内已经有大量相邻内容,写清分工比重复写一遍更有价值。下面五处边界是本卷最容易混淆的,务必分清:

  • 《小游戏开发实战》卷一《市场品类与产品设计》 是产品口径:品类选择、用户动机、立项预算、变现前置。本卷是动态与体验口径:机制跑起来涌现什么、玩家体验到什么,全部操作化为可计算指标。它那一卷有三个点最像本卷,逐个划清:① 核心循环拆解 用 S 层算循环时长占比,本卷第 1 章算的是策略空间(动作序列的枚举规模与 Shannon 熵);② 难度-心流曲线 给的是 S 层心流单点模型 + B 层难度敏感性,本卷第 6 章与第 10 章给的是相变 / 序参量与心流带宽(区间而非单点);③ 可玩性指标测试 的指标偏占比类(S 层模拟采样 + 置信区间),本卷第 12–13 章给的是策略熵 / 支配缺失度 / 涌现度 / 相变宽度等机制量。
  • game/indie/ 的四篇长文是散文式 + Unity csharp 片段、不可跑:核心循环与手感设计 (约 690 行)讲手感参数体系,本卷第 11 章把它换成技巧习得曲线(建模 / 习得曲线与难度曲线 / 天花板与瓶颈);平衡与经济 (约 1430 行)是概念罗列,本卷第 2 章给可判定的支配策略检测;关卡设计与环境叙事 (约 940 行)讲空间引导与难度曲线,本卷第 9 章把张力与释放写成可算的情绪曲线;叙事设计 属叙事方向,本卷不覆盖叙事。
  • game/ 专题其它篇讲的是概念与流程:经济平衡 是经济平衡概念 + 示意代码,本卷第 5 章给策略平衡度量;平衡治理流程 是流程治理(委员会、评审、榜单),本卷第 4 章给涌现度量;新手引导清单 是清单,本卷第 11 章给习得曲线。凡「该走什么流程」看那些篇,凡「这个量等于多少」看本卷。
  • 《数值平衡与商业化运营》 管 SLG 的赛季膨胀 / 数值 / 商业化;本卷第 3 章只取博弈最优(极小极大、混合策略、最优解的计算代价),不做商业化数值。《风格与品类美术实战》 做的是风格距离矩阵,本卷(与卷三)做的是机制距离矩阵(口径对照,不重造风格矩阵)。
  • 《引擎实现与体验打磨》 与 /posts/game/industry/ 分别是引擎 API 与行业短文的家;本卷第 14 章做的是纯 xml.etree SVG 的动态可视化(曲线与谱、策略空间热力图、相变图读法)。本卷的前一卷《玩法机制与可执行规格》讲「规格怎么写」,本卷讲「规格跑起来之后是什么」,其分卷目录见《玩法机制与可执行规格》卷末第 16 章 16.3 节的交付说明。

一句话:本卷做的是「机制跑起来之后,动态与体验能不能被算出来、被比较」,不是「机制怎么写」(卷一),也不是「怎么把它做成原型、换成别的品类」(卷三)。

明确不在本卷范围内

为了让边界清楚,下面这些这一卷不讲:

  • 玩法规格本身的字段、校验、版本与迁移——见卷一《玩法机制与可执行规格》第 1–2 章。
  • 四处消费的工程做法(内联、无头真玩、跨宿主摘要)——见卷一卷五、卷十五、卷十六。
  • 产品立项、品类选择、变现与买量——见《小游戏开发实战》卷一《市场品类与产品设计》。
  • 叙事、关卡与美术的创作——见 game/indie/ 的叙事长文与《游戏美术与技术美术》三卷。
  • 真实玩家测试数据、真实测试服、真实榜单:本机没有,一律标 X,正文逐处显式标注「需真实业务环境,命令行不可复现」。
  • 任何第三方素材:贯穿案例为虚构游戏,所有 PNG / SVG 由程序化生成。

可运行性六档口径

本卷每一节的代码块头部注释里都写着它属于哪一档。所有代码块都在本机实跑过,正文数字等于实跑输出;但「整卷项目复现」(把全部配置与共享模块一次性组装跑通)由第 16 章交付,本页不单独声称。

档数据源算什么(真跑)产出断言
Sconfig/play_spec.json策略空间枚举与 Shannon 熵 / 支配策略检测 / 极小极大与混合策略 / 涌现度量与退化解识别 / 策略平衡度量 / 相变扫描与序参量 / 情绪张力曲线 / 心流带宽 / 习得曲线 / 体验指标与置信区间 / 可玩性组合指标 / 参数反推JSON + CSV + 纯 xml.etree SVG脚本 exit 0;SVG 可 ET.parse;整数指标误差 = 0
P同一 spec机制不变量(守恒 / 不可达 / 单调 / 无死锁)+ 确定性回放 + 跨语言摘要core/src/ashdeck/*.ts + core/test/gd_play_*.test.tsnode --test '<glob>',fail == 0
W同一 spec 内联进单文件 HTML浏览器里真的玩:注入整段策略序列、断言状态与胜负、采样可玩性指标web/dist/play<NN>.html + out/shots/*.pngPlaywright 无头:断言全绿 + 两遍确定性 + canvas ≥ 1px
D规格文本动因模型表、玩家类型表、指标定义表、装配检查表、交付清单JSON / YAML / Markdown 表schema / lint;必须与 S/P/W 同节搭配
X真实业务真实玩家测试数据、真实测试服、真实榜单无正文逐处显式标注「需真实业务环境,命令行不可复现」
B可扰动参数指标对参数的敏感度、相变点、稳健性JSON软告警不硬失败;数字来自本机实跑

「好玩」在本卷被操作化成几个可算的代理指标(策略空间熵、支配策略缺失度、涌现度、相变临界宽度、心流带宽、可解率),只用于相对比较,禁绝对化——它们证明的是「这套规格的动态可控、可分辨、可比较」,不是「这游戏好玩」。

贯穿案例《灰烬牌库》的动态侧面

卷一从机制角度解剖了《灰烬牌库》:一个 12 张牌的牌库、若干张手牌、能量与伤害、回合上限、胜负条件,全部写在 config/play_spec.json 里。本卷换一个角度看同一份规格——它的动态:

  • 策略空间有多大:把「每一回合出哪几张牌、按什么顺序」写成动作序列,一局的可选路径有多少条?枚举规模与 Shannon 熵给出一个整数上界(第 1 章)。
  • 有没有支配策略:如果「永远先出重击」严格优于其它选择,这个游戏就被解开了。检测严格 / 弱支配、给出算法与复杂度上界(第 2 章)。
  • 最优解值多少:极小极大告诉你「双方都最优时会怎样」,混合策略告诉你「随机化能换来什么」,以及求出最优解的计算代价(第 3 章)。
  • 涌现出什么:规则简单,跑起来却出现设计者没写过的模式——涌现度衡量「可达模式数 / 规则数」,退化解则提示模式其实很少(第 4 章)。
  • 平不平衡、有没有相变:胜率分布是否集中、可用策略是否够多(第 5 章);参数扫过某个点后游戏性质突变(第 6 章)。

这些都是同一份 play_spec.json 在不同维度上的投影,全部由 sim/gd_play_*.py 真跑产出。

全书 16 章 48 节

第一部分 · 策略与均衡(第 1–3 章)

第 1 章 策略空间(S)

第 2 章 支配策略检测(S+B)

第 3 章 均衡与最优(S)

第二部分 · 涌现与相变(第 4–6 章)

第 4 章 涌现(S+B)

第 5 章 平衡(S+B)

第 6 章 相变(S+B)

第三部分 · 玩家与体验(第 7–13 章)

第 7 章 玩家动因模型(D+S)

第 8 章 玩家类型(D+S)

第 9 章 情绪曲线与张力(S)

第 10 章 心流带宽(S)

第 11 章 技巧习得曲线(S+B)

第 12 章 体验度量(S)

第 13 章 可玩性的可计算化(S+B)

第四部分 · 可视化、反推与装配(第 14–16 章)

第 14 章 动态的可视化(S)

第 15 章 动态到设计的反推(S+B)

第 16 章 装配:规格跑起来(S+P+W+B)

三卷递进

三卷不是三个话题,是同一条链上的三段:

  • 卷一《玩法机制与可执行规格》(gd-mech-):一份玩法规格怎么写、怎么被四处消费、怎么证明它自洽。落点是 M 层(Mechanics)。
  • 卷二《策略、涌现与体验度量》(gd-play-,即本卷):规格跑起来之后涌现什么、玩家体验到什么,全部操作化为可计算指标。落点是 D 层(Dynamics)与 A 层(Aesthetics)。
  • 卷三《原型、可玩性与品类》(gd-proto-):把同一份规格实例化到 6 个品类,6/6 通过可玩性闸门,产出品类间机制距离矩阵。落点是跨品类成立性。

三卷共用同一份 config/play_spec.json、同一个 sim/、同一个 core/、同一个 web/。换卷不换底座——这也是「一份规格,四处消费」能被验证的前提。

本卷用到的代理指标速查

下表把本卷反复出现的量集中列一次。它们全部是代理指标(proxy),只用于相对比较,不用于证明「好玩」。

指标定义(整数化口径)主要出现
策略空间熵动作序列分布的 Shannon 熵 × 1000 取整第 1、13 章
支配策略缺失度1 − 支配策略数 / 总策略数,千分比第 2、13 章
涌现度可达模式数 / 规则数,千分比第 4、13 章
相变临界宽度序参量跨越阈值所对应的参数区间宽度(整数)第 6、13 章
心流带宽挑战-技巧匹配区间的宽度(整数刻度)第 10、11 章
可解率可解种子数 / 总种子数,千分比第 12、15 章
张力峰值单局张力曲线的最大值(整数)第 9、14 章

底座:策略枚举的公共入口

本卷与卷一共享同一套底座:S 层公共库 sim/ashlib.py,P 层内核 core/src/ashdeck/{types,rng,cards,combat,digest}.ts,W 层打包器 web/pack.mjs 与验证器 web/verify_mech.mjs。底座只读,各章只在它之上写自己那一节的枚举与度量脚本。

策略枚举的可复现性,前提是随机源可复现。下面这段是本套的随机源,与工作区 core/src/ashdeck/rng.ts 逐字节一致——它是三条跨语言纪律里第二条(自实现可播种 PRNG)的落点:

// file: core/src/ashdeck/rng.ts
// tier: P
// verify: node --test 'core/test/gd_mech_base.test.ts'
//
// 自实现可播种 PRNG(Lehmer MINSTD),与 sim/ashlib.py 的 rng_next 同算法。
// 跨语言逐位一致的唯一保证就是这里:整数运算,绝不用 Math.random()。

export const RNG_MOD = 2147483647;
export const RNG_MUL = 48271;

export function rngNext(state: number): number {
  return (state * RNG_MUL) % RNG_MOD;
}

export function shuffleDeck<T>(deck: T[], seed: number): T[] {
  const out = deck.slice();
  let state = seed % RNG_MOD || 1;
  for (let i = out.length - 1; i > 0; i -= 1) {
    state = rngNext(state);
    const j = state % (i + 1);
    const t = out[i];
    out[i] = out[j];
    out[j] = t;
  }
  return out;
}

用规格自带的基线策略跑一局,S 层产出的摘要如下——它与卷一给出的那一行逐字相同:

{"block":0,"cardCount":12,"damageConserved":true,"dealt":50,"enemyHp":0,"energy":1,"hand":["strike","jab","heavy"],"over":true,"played":9,"playerHp":48,"turn":4,"won":true}

读法同卷一:4 回合取胜,打出 9 张、累计造成 50 点伤害(恰好清空敌人 50 血),余能量 1,玩家剩 48 血。换卷不换底座——同一份规格在同一台机器上永远给同一行,这是本卷所有动态指标可比较的前提。

复现前提

想在本地把本卷的代码块跑起来,需要这些条件(都已实测可用):

  • Python 用 /opt/homebrew/bin/python3(3.14.6,带 numpy / pandas / Pillow;无 matplotlib / scipy,图表一律纯 xml.etree 生成 SVG)。
  • Node 用 node(v26.5.0,原生跑 .ts;strip-only,禁 enum / namespace)。
  • 工作区是 $HOME/.gdbook/ashdeck(不是 /tmp,会被系统清理),底座文件 config/play_spec.json、sim/ashlib.py、core/src/ashdeck/*.ts、web/pack.mjs 与卷一完全相同。
  • 随机一律用自实现可播种整数 PRNG(Python 与 TS 同算法同种子),禁 Math.random() 与 Python random——否则跨语言对照必然漂移。
  • 每个代码块头部注释都写着 # file: / # tier: / # verify:,file: 指向工作区里的真实文件,与正文块逐字节一致。
  • 真实玩家数据、测试服、榜单在本机不存在,凡涉及它们的段落一律标 X 并显式写明「需真实业务环境,命令行不可复现」。

怎么读

三条路径,按你的目的挑一条:

可运行性总表(各章档位分布)

章主题档位
1策略空间S
2支配策略检测S + B
3均衡与最优S
4涌现S + B
5平衡S + B
6相变S + B
7玩家动因模型D + S
8玩家类型D + S
9情绪曲线与张力S
10心流带宽S
11技巧习得曲线S + B
12体验度量S
13可玩性的可计算化S + B
14动态的可视化S
15动态到设计的反推S + B
16装配:规格跑起来S + P + W + B

整卷口径:每一节至少有一个 S / P / W 档的可跑代码块;S 层脚本逐个跑(/opt/homebrew/bin/python3 sim/gd_play_*.py),P 层写全 glob(node --test 'core/test/gd_play_*.test.ts'),W 层用 web/verify_mech<NN>.mjs 无头断言;B 层软告警不硬失败。完整指标公式表与数据集索引见附录 A 。

继续阅读

探索更多技术文章

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

全部文章 返回首页

「gamedesign」更多文章

  1. 附录 A 品类参数表、机制距离矩阵与数据集索引
  2. 9.3 自走棋的涌现
  3. 9.2 自走棋的经济与平衡