Skip to content

独立游戏提效的真相:从饥荒的“Lua 引擎”说起

——写给还在 Unity 里“一锅乱炖”的独立开发者

本文缘起知乎问答「如何提高独立游戏开发效率?」,原回答里我提了一句“在 Unity/UE 之上再写一层玩法级引擎”。评论区吵得很凶:
“这不就是 RPG Maker 吗?”
“小团队搞编辑器是不是过度工程?”
“饥荒这种体量的游戏是怎么做的?”
于是有了这篇文章——把饥荒拆开,看看到底什么是“玩法引擎”,再给出一条最小可落地的独立游戏提效路线。


1. 先把话说清楚:三层架构模型

层级通俗叫法饥荒里的对应职责
L0 系统引擎Unity / UE / GodotC++ 引擎层(Klei 自研 fork)渲染、物理、音频、IO
L1 玩法引擎我们吵了一整楼的那层C++ 侧的 Sim + Lua 虚拟机提供对象系统、组件生命周期、热重载、调试器
L2 游戏内容策划案 / 配表 / 脚本90 % 的 Lua 脚本(scripts/ 目录)角色、物品、季节、AI、剧情、MOD

一句话:
独立开发者最容易忽视的就是 L1——玩法引擎。


2. 解构饥荒:为什么 90 % 的代码是 Lua 还能稳定跑?

2.1 目录结构速览

dont_starve/
├─ data/                 # 美术、音效
├─ scripts/              # ← 90 % 游戏逻辑
│  ├─ prefabs/           # 每个实体一个文件(草、斧头、巨鹿)
│  ├─ components/        # 可复用能力(燃烧、可拾取、烹饪)
│  ├─ brains/            # AI 行为树
│  └─ tuning.lua         # 全局数值表
└─ bin/                  # C++ 可执行 + LuaJIT

2.2 L1 玩法引擎(Klei 的“Lua 引擎”)提供了什么?

功能饥荒的实现独立游戏可抄的要点
实体-组件系统(ECS)每个 prefab 是一个实体,挂任意 AddComponent("combat")自己用 ScriptableObject 写 200 行就能跑
热重载修改 scripts/prefabs/axe.lua → 游戏内按 Ctrl+R 立即生效Unity 用 Addressables + Compile And Run 可 50 % 模拟
模块化 AIBrain = 行为树用 Lua table 写用 NodeCanvas 或自写 100 行 Lua parser 即可
调试器内置 c_debug() 控制台 + 可视化碰撞盒Unity 用 ImGui + DrawGizmo 一小时搞定
MOD API直接暴露整个 Lua 环境实际上就是“官方教你用我们的 L1”

Klei 用 C++ 写了 不到 10 % 的代码,就把“饥荒”这个框架钉死;剩下 90 % 用 Lua 像填表一样做内容。
这,就是“玩法引擎”的威力。


3. 评论区高频质疑统一回应

质疑用饥荒案例回答
“小团队写引擎是不是过度工程?”Klei 最早 3 人,先写 Lua 虚拟机 + ECS 花了 4 周,后面 6 年都在填 Lua 内容。ROI = ∞。
“RPG Maker 千篇一律”饥荒的 Lua 层没有限制你做任何玩法,巨鹿、船难、哈姆雷特全是同一套 L1 长出来的新内容。
“策划和程序视角不同”饥荒策划眼里的“引擎”就是 tuning.lua 里那张数值表,因为改一行就能让巨人血量翻倍,这就是“自助”。
“我没作品空谈架构”饥荒第一个可玩 Demo 是 7 天 GameJam 用纯 Lua 写的,验证完才补的 C++ 渲染层。架构先行 ≠ 拖延上线。

4. 最小可行路线:从 0 到“自己的饥荒”

以下步骤按 1 人全职、2 个月搭框架、剩下时间填内容为假设。

4.1 第 0 周:玩法原型

  • Unity 新建空项目,灰盒一个“砍树→掉木头→做斧头”循环。
  • 代码写得越烂越好,只要能跑。

4.2 第 1~2 周:提炼 DSL

  • 把“树、斧头、木头”抽象成 3 个 JSON 配置:
    json
    {
      "id": "axe",
      "components": ["weapon", "durability"],
      "damage": 30
    }
  • 写个最丑的 RuntimeLoader,能读 JSON 生成 GameObject 即可。

4.3 第 3~4 周:最小编辑器

  • Unity Editor 窗口:
    • 左:树形列表显示所有实体
    • 右:Inspector 改 JSON 字段
    • 按钮:Save & Hot Reload(用 Addressables.Relocate 实现)
  • 里程碑:策划无需打开 VSCode,能在 30 秒内新增一把“40 伤害的大斧头”。

4.4 第 5~6 周:组件化

  • 把“耐久度、武器、可拾取”写成 MonoBehaviour,但注册方式用 JSON
  • 目标:代码只增不改,策划通过 JSON 组合出新物品。

4.5 第 7~8 周:Lua 绑定(可选)

  • 如果策划不会 JSON,引入 MoonSharp(C# Lua 解析器)。
  • 让配置写成 Lua 表,获得“函数级可编程”能力,饥荒同款。

4.6 长期:内容洪水

  • 剩下 90 % 时间只做两件事:
    1. 填 Lua/JSON 表 → 出新实体、新关卡。
    2. 发现“编辑器不支持” → 回到 C# 扩展 DSL,循环往复。

5. 小结:一句话背下来

“独立游戏开发效率的杠杆点,不是把 Unity 用得多么花哨,而是在第 3 周就搭好自己这款游戏的‘饥荒级 Lua 引擎’——让策划像写 MOD 一样做游戏。”

如果你已经在 Unity 里第三次重写背包系统,是时候停下来,先写一把“斧头编辑器”了。