前言:怎么读这套书

卷一的阅读指南:三条阅读路径(产品经理的系统课、经济策划的建模课、只看闭环)、可运行性五档口径(S 仿真 / P 原型 / D 静态 / X 不可复现 / B 基准)、贯穿项目 bastion 的目录结构、需要准备的环境(Python 3 + numpy/pandas、Node 26,无需 tsc 与 npm),以及怎么验证书里的代码真的能跑。

这套书的代码都能在你自己的机器上跑起来。这篇前言讲三件事:怎么读(三条路径)、怎么跑(五档口径与环境)、怎么验(怎么确认书里的数字不是编的)。

一、这本书写给谁

如果你是产品经理或主策,想搞清楚一款 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 静态层产品文档、系统地图、功能树、配置表 schemaschema / 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 。

六、怎么验证书里的数字

这套书的每一个数字都来自本机实跑。你可以自己复核:

  1. 抽一个 # file: 块,按路径还原成文件。
  2. 跑它头部的 # verify: 命令。
  3. 对照正文里的数字——应该一致。

正文里的数字会写成「同机相对量级,绝对数值不可移植」。这句话不是免责声明,是准确描述:一次结算的耗时、一条曲线在第 180 天的稳态值,都跟你机器的性能和这版配置有关。可移植的是方法和结构,不是绝对值。

如果你发现某个数字对不上,那大概率是两种情况:要么配置被改过了(这正是「一份配置两处消费」该有的行为),要么正文写错了——后者请告诉我。

七、接下来

本页是前言。接着读第 1 章 1.1 SLG 品类图谱与细分 。

继续阅读

探索更多技术文章

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

全部文章 返回首页

「slg」更多文章

  1. 12.3 留存与付费的联合分析
  2. 12.2 流失预警与召回
  3. 附录 C:全书公式、参数与数据集索引