## **前言**

作者首次接触到这个词，大概是20年，当时我正在探索技能实现的正确方案。在这期间，我了解到[Dota2](https://zhida.zhihu.com/search?content_id=255482146&content_type=Article&match_order=1&q=Dota2&zhida_source=entity)编辑器的存在，而Dota2的技能扩展就提到了“[数据驱动](https://zhida.zhihu.com/search?content_id=255482146&content_type=Article&match_order=1&q=%E6%95%B0%E6%8D%AE%E9%A9%B1%E5%8A%A8&zhida_source=entity)”这个词。

不过，Dota2并没有对数据驱动这个词下定义，也没有解释数据驱动的优缺点 —— 即为什么要这么做，再加之他们的技能设计和我的想法差异过大，我便没有深入研究他们的设计。

我真正理解数据驱动，是在将[行为树](https://zhida.zhihu.com/search?content_id=255482146&content_type=Article&match_order=1&q=%E8%A1%8C%E4%B8%BA%E6%A0%91&zhida_source=entity)成功引入战斗系统后。在将行为树引入战斗系统后，为了支持编辑技能和Buff，我将既有的行为树编辑器修改为了通用的数据结构编辑器 —— 不再限制节点的类型，就像这样：

  

![](https://pic3.zhimg.com/v2-71ba79a9cbbdbc9de6476bd6a180c6aa_1440w.jpg)

  

这样以后，对于简单的技能，策划就可以在编辑器中直接实现；而特殊的技能，也只需要程序提供特殊的节点即可。也就是做完这件事，我便理解了Dota2的数据驱动是什么意思。

---

## **那什么是数据驱动？**

我们编辑器导出的是[Json](https://zhida.zhihu.com/search?content_id=255482146&content_type=Article&match_order=1&q=Json&zhida_source=entity)格式（以后会调整），其内容虽然和Dota2有区别，但内核是一样的，那就是：**用数据描述行为**。

你可以将策划的配置（数据）看做是更高层的代码，而我们的程序则相当于解释器，解释配置实现对应的行为。

不过，数据驱动还有另一个解释：**通过修改数据，改变对象的行为**。

这个解释侧重最终目的，而非过程（怎么做）；因为数据描述行为的情况下，数据改变，行为自然改变。

这两个解释都应该知晓，前者可以指导我们该怎么做，后者可以检验我们设计的正确性，也可以告知他人我们的设计目的。

---

## **它主要干了什么事情？**

它其实就干了一件事：**分离接口和实现**。

注意，这里是分离接口和实现，而不是分离数据和行为（面向过程）。面向过程下，数据只是数据，它不关心它如何被处理；而技能的配置是完整约定了技能行为的，它不仅仅约定了函数名，还约定了函数参数。

所以，**策划的配置起的是接口的作用**，而我们的代码则是对接口的实现，所以是接口和实现的分离。

---

### **数据驱动的优点：**

1. 更好的扩展性和灵活性 —— 显而易见
2. 更好的可读性和可维护性
3. 解放策划的生产力，减少程序的工作量
4. 跨语言：配置通常采用语言无关的文本格式

  

### **数据驱动的缺点：**

1. 不确定性（安全性）
2. 解析开销（脚本实例化开销）

不确定性，是我在向策划提供技能编辑器以后最苦恼的事。在编辑器里组合节点是很容易的——就连个线，但行为之间可能存在数据（上下文）依赖，由于策划并非专业的程序员，对程序运行时的上下文也并不完全了解，因此可能拼出错误的逻辑，而这些错误难以在开发期检测出。

所以，即使在有编辑器的情况下，我还是会经常被策划喊：“磊哥，你看看我这个技能怎么不好使呢？”

所以，即使是有编辑器，对战斗策划要求仍然是比较高的 —— 但已然降低不少。

---

## **如何实现数据驱动？**

有几个关键点：

1. **控制反转**：将（部分）控制权交给策划
2. 组合模式：将大块的逻辑，拆分为一个个独立的单元，允许组合使用
3. 函数无状态：函数的输入完全来源于黑板
4. 保持数据结构简单：只使用简单的数据类型集合
5. 上下文使用黑板类型
6. 好的文本格式和序列化工具

---

### **数据驱动随处可见**

在游戏开发中，数据驱动有着大规模的应用，只是以前我们没有关注到这个词而已。我们的场景编辑器，任务编辑器，剧情编辑器，都是数据驱动的案例。甚至[Unity](https://zhida.zhihu.com/search?content_id=255482146&content_type=Article&match_order=1&q=Unity&zhida_source=entity)，都可以说是数据驱动的，它的资产文件就是数据，我们通过数据告知Unity动画该怎么播，UI该怎么展示。

所以，虽然你可能不了解数据驱动这个词，但工作中其实一直在使用。

**数据驱动与编辑器有关吗？**

无关。配置（数据）是可以手写的，编辑器的作用只是简化了配置方式 —— 算是简单的图形化编程。

**那以前策划通过Excel组合不同的技能效果算数据驱动吗？**

严格意义上来说，是算的，但我更想说不算。

因为通过Excel配置技能的方式，程序的工作并不轻松，策划的工作就更是艰难。此外，使用Excel配置技能的结果是：**数据，数据不清楚；行为，行为不清楚，那谈什么数据驱动呢**？

对于技能这种复杂的数据，应该舍弃Excel，使用Json或[Lua](https://zhida.zhihu.com/search?content_id=255482146&content_type=Article&match_order=1&q=Lua&zhida_source=entity)等来配置，只有数据和行为都清楚了，才算得上数据驱动。

---

## **结语**

游戏开发中有许多的词汇，这些词汇通常代表着一些模式， 了解这些词，可以让我们对项目的设计认知更为清楚。