这套书的代码都能在你自己的机器上跑起来。这篇前言讲三件事:怎么读(三条路径)、怎么跑(五档口径与环境)、怎么验(怎么确认书里的数字不是编的)。
一、这本书写给谁
如果你是产品经理或主策,想搞清楚一款 SLG 从定位到经济系统怎么被搭起来,读第 1–8 章。读完你能画出一张自洽的系统地图,并且用脚本证明它没有环、没有孤儿、解锁链可达。
如果你是数值策划或经济策划,想搞清楚资源怎么产出、怎么消耗、怎么不崩,读第 9–15 章。读完你能跑出一条 180 天的资源曲线,诊断它是否收敛,并找出最危险的参数。
如果你是制作人或团队负责人,想给团队一套能对齐的口径,两条路径都值得过一遍——重点是第 4、5、8 章(系统地图、模块边界、指标体系)和第 12 章(闭环稳态)。
如果你只是想看看别人怎么做 SLG 设计,直接跳目录页 的「常见问题速查」表。
二、三条阅读路径
路径 A:产品经理的系统课(第 1–8 章顺序读)
从品类定位开始,经玩家分层、核心循环、系统地图、功能架构、交互信息架构、版本规划,到指标体系。这条路径回答「一款 SLG 怎么被搭起来」。
路径 B:经济策划的建模课(第 9–15 章顺序读)
从资源与货币分层开始,经产出端、消耗端,到产出回收闭环、通胀治理、交易市场、经济风控。这条路径回答「经济怎么不崩」。
路径 C:只看闭环(第 9 → 12 → 13 章)
如果你只想搞懂经济闭环这一件事:第 9 章给你账本模型,第 12 章给你闭环稳态判定,第 13 章给你通胀治理。这三章是全卷的核心,其余章节按需回填。
三条路径都建议先读完序 ,它讲清楚了这套书的写法和边界。
三、可运行性五档口径
这套书是产品设计书,不是代码书,所以不能照搬代码书的分层。每个代码块头部都标着它属于哪一档:
| 层 | 含义 | 怎么验证 |
|---|---|---|
| S 仿真层 | Python 数值仿真:成长曲线、经济闭环、概率期望、匹配公平性 | python3 sim/<name>.py --config config/,产出 JSON + CSV + SVG |
| P 原型层 | TypeScript 配置驱动原型:资源结算、城建、兵种战斗、联盟战 | node --test 'proto/**/*.test.ts' |
| D 静态层 | 产品文档、系统地图、功能树、配置表 schema | schema / lint 校验 |
| X 不可复现 | 真实竞品后台数据、真实买量、真实用户调研 | 正文显式标注,命令行不可复现 |
| B 基准 | 稳态偏差、期望对照、拟合残差、结算吞吐 | 产出 JSON,软告警不硬失败 |
每个代码块的第一行是文件路径,第二行是层级,第三行是验证命令:
# file: sim/bastion_core.py
# tier: S
# verify: python3 sim/bastion_core.py
看到 # file:,就说明这段代码是一个完整可运行的文件,不是从大文件里摘出来的片段。纯展示用的片段会标 # snippet:。
为什么要有 X 层? 因为产品设计里确实有一部分内容无法在命令行复现——比如「真实竞品的后台留存曲线」。与其含糊地写成「据观察」,不如明确标出来:这类内容需要真实业务环境,你在这台机器上跑不出来。 这是诚实,也是这套书对读者的承诺。
四、贯穿项目 bastion
全书围绕一个虚构的 SLG 《王朝纪元》 和一套工具链 bastion 展开:
bastion/
config/ # 唯一真源
resources.json # 资源定义与上限
buildings.json # 建筑等级、产出曲线、升级成本
units.json # 兵种属性与克制环
battle.json # 战斗规则常量
sim/ # Python 仿真
proto/ # TypeScript 原型
src/
test/
《王朝纪元》 是一款大地图 + 城建 + 兵种 + 联盟 GVG + 赛季制的中重度 SLG。它的范围被钉死在「一份能自洽跑通的设计案」:产品定位 → 系统地图 → 经济闭环 → 数值体系 → 商业化与赛季。产出仿真 JSON、SVG 曲线、可跑的原型回放,就是这套书的验收标准。
bastion 的核心主张是一份配置、两处消费:config/ 是设计的唯一真源,sim/ 用它跑平衡,proto/ 用它跑玩法。改一个数字,两边结果都变。
能力阶梯分四档,从 P0 到 P3 逐步建起来:
| 档 | 能力 | 出现在 |
|---|---|---|
| P0 | 资源结算(产出/消耗 tick + 资源账本) | 第 9–12 章 |
| P1 | 城建(建筑等级、建造队列、解锁) | 第 4、10 章 |
| P2 | 兵种战斗(兵种三角、阵容、确定性回合结算) | 卷二第 3–4 章 |
| P3 | 联盟战(联盟、GVG 匹配、赛季结算) | 卷二第 15 章 |
每一档都要求「改 config 里的一个数字,仿真与原型的结果都跟着变」。
五、环境准备
需要的只有两样:
# file: check_env.sh
# tier: S
# verify: sh check_env.sh
python3 -c "import numpy, pandas; print('numpy', numpy.__version__, 'pandas', pandas.__version__)"
node -v
- Python 3 +
numpy+pandas:S 层仿真用。 - Node 26 或更高:P 层原型直接跑 TypeScript。
不需要 tsc、不需要 npm install、不需要 package.json。 Node 26 能直接执行 TypeScript(只支持「可擦除语法」——所以本套的原型代码不使用 enum 和 namespace,改用 const 对象加联合类型)。断言用 Node 内置的 node --test,零依赖。
图表也不用 matplotlib。 本套的 SVG 是纯 Python 用标准库 xml.etree 画出来的,零依赖、可复现。下面这段就是最小示例:
# file: sim/svg_line.py
# tier: S
# verify: python3 sim/svg_line.py
"""纯 Python(零依赖)生成 SVG 折线图:不依赖 matplotlib。"""
import os
import xml.etree.ElementTree as ET
SVG_NS = "http://www.w3.org/2000/svg"
def polyline_points(series, lo, hi, width=640, height=360, pad=(56, 24, 24, 40)):
"""把一组数值映射成 SVG polyline 的 "x,y x,y" 字符串。"""
pl, pr, pt, pb = pad
span = (hi - lo) or 1.0
inner_w = width - pl - pr
inner_h = height - pt - pb
n = max(len(series) - 1, 1)
pts = []
for i, v in enumerate(series):
x = pl + inner_w * (i / n)
y = pt + inner_h * (1.0 - (v - lo) / span)
pts.append(f"{x:.2f},{y:.2f}")
return " ".join(pts)
def render(series, path, title="resource curve"):
lo, hi = min(series), max(series)
svg = ET.Element("svg", {"xmlns": SVG_NS, "viewBox": "0 0 640 360", "width": "640", "height": "360"})
ET.SubElement(svg, "rect", {"width": "640", "height": "360", "fill": "#ffffff"})
ET.SubElement(svg, "polyline", {
"points": polyline_points(series, lo, hi),
"fill": "none", "stroke": "#1f6feb", "stroke-width": "2",
})
label = ET.SubElement(svg, "text", {"x": "56", "y": "16", "font-size": "13", "fill": "#111"})
label.text = title
os.makedirs(os.path.dirname(path), exist_ok=True)
ET.ElementTree(svg).write(path, encoding="utf-8", xml_declaration=True)
return path
if __name__ == "__main__":
import math
curve = [1000.0 * math.exp(-0.006 * d) + 12.0 * d for d in range(0, 181, 10)]
out = render(curve, os.path.join(os.path.dirname(__file__), "..", "out", "intro_curve.svg"))
print(f"wrote {out} points={len(curve)}")
跑起来会在 bastion/out/ 下生成一个 SVG,用浏览器直接打开就能看。这套书的每一张图都是这么画出来的。
完整的目录结构与全部实跑命令见附录 A ,配置表字段字典与整数比约定见附录 B 。
六、怎么验证书里的数字
这套书的每一个数字都来自本机实跑。你可以自己复核:
- 抽一个
# file:块,按路径还原成文件。 - 跑它头部的
# verify:命令。 - 对照正文里的数字——应该一致。
正文里的数字会写成「同机相对量级,绝对数值不可移植」。这句话不是免责声明,是准确描述:一次结算的耗时、一条曲线在第 180 天的稳态值,都跟你机器的性能和这版配置有关。可移植的是方法和结构,不是绝对值。
如果你发现某个数字对不上,那大概率是两种情况:要么配置被改过了(这正是「一份配置两处消费」该有的行为),要么正文写错了——后者请告诉我。
七、接下来
- 想直接开始:从第 1 章 1.1 SLG 品类图谱与细分 读起。
- 想看全书结构:目录页 。
- 想先看经济:第 9 章 9.1 资源分类与货币分层 。
- 想直接看闭环:第 12 章 12.2 闭环仿真与稳态判定 。
本页是前言。接着读第 1 章 1.1 SLG 品类图谱与细分 。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。