关于地图编辑器的一些想法
大凡 RPG 游戏(包含 MMORPG),在制作期都需要开发一个地图编辑器。
早年 2d 游戏就有这个需求,基于 Tile 的 Engine 如是,基于整图的 Engine 亦如是。到了 3d 游戏,这个东西更少不了。
对于 3d engine 中附带的地图编辑器,通常有几个用途:拉地形(也有基于模型的地形)、摆放物品(以及特效)、设置玻璃墙(或是设置障碍格);有时也包括设置摄象机、事件触发点、摆放 NPC 等等。
在很长时间里,我都倾向于制作一个大而全的编辑器 IDE 。但最最近两年,随着编程风格及开发习惯的改变,我对这种做法产生了怀疑。
一旦制作 IDE ,就涉及对 GUI 底层的选择。无论你用 MFC 还是 QT WxWidget 或是 .net framework ,对开发人员都有一个学习过程。以我所见的大多数程序员的喜好,只要开始制作 IDE ,一上来第一见时间必定是设计一个所谓自己的 framework ,制定所谓插件规范,以用来解决上面提出的各种不断会面临的功能需求增加。
以我 10 年游戏开发的成功和不成功的经验来看,设计所谓框架是最最最不靠谱的事情。设计和实现的结果,最终一定会导致框架的分量比实际功能更大,生命期也更短。(欢迎大家驳斥和批评我的这个观点,我不会跟你争论的 :) )
和写程序不同,程序员可以眼前代码千行、胸中蓝图万卷;美术人员、策划人员都需要有直观的视觉反馈,所以 Tex 那种对书籍论文排版的方式往往是行不通的。
所以,我不反对 GUI 界面的选择,单纯是考虑 IDE 的必要性和替代方案而已。
从我有限的视角去看。其实制作人员最喜爱的工具往往是最熟悉的东西,专门性强的工具;所以对 2d 图片的处理总是首选 Photo shop ,对 3d 模型则爱 3dmax 或 maya 。如果情况所迫要用开发人员提供的编辑器、那么,往往生命期越长的工具就活的越长。活的最长的工具总是那些功能单一,又能解决问题的东西;甚至于到了最后,连源代码都不见了,或是有了源代码却构建不回来(通常是由于动态链接库版本问题,或编译器版本造成一些 bug ),但留下二进制执行文件而一直用下去。
编辑器的作用到底是什么?它产生的是数据、以一种更直观的方式得到需要的数据。
早年,我们为了简化开发流程,使用标准编辑器(Photoshop)制作地图。然后编写命令行工具提取出数据,转换为最终的数据格式;随着项目的繁衍,也开始制作一些专门的 GUI 小工具辅助开发。
后来,我们开始为新项目新引擎制作专门的编辑工具。这通常需要至少一个全职程序员十个甚至二十个月的持续跟进。直到工具庞大到难以维护。
我想过好多次,能不能找到另一条思路。
目前的构想(并已经实现)是这样的:
把编辑器做成 C/S 结构。并不规定具体的实现方案,只指定数据通讯和持久化协议。这个 S(erver) 其实是一个实时版的 SVN 。它不理会数据的具体含义,只是忠实的记录编辑器的 Client 提交上来的数据,为每个原子数据产生唯一版本号。所谓实时,指 Server 会在收到提交后,才很短的时间内把数据推给其它 Client 。
首先,这样做可以使得多个编辑器 Client 同时编辑同一个对象(一张地图)变为可能。我们也不必提供锁机制,用操作链表的融合保证并发编辑的有序。Server 同时也保存了整个编辑过程的历史,可以无限制的回退。
举例:
如果有 A B 两个 Client 同时编辑一张地图。A 原子提交了 1 2 两个对象(可能是连在一起的两个地图块高度信息),而 B 在差不多的时间提交了 2 3 两个对象。
在没有得到 Server 的成功反馈之前,谁也不能把实际效果作用在 Client 的界面上。而是把未确认的操作保存在一个链表中。Server 收到 A 或 B 的提交后,核对版本号,给予最早提交的一方,比如 A 一个成功信号。这时 A 就把操作链表真正作用于地图。
而 B 的提交一旦晚于 A 的达到,由于发生版本冲突,会得到 Server 的失败反馈。B 就需要把 Server 推给它的 A 的修改先更新后,再把操作链表中的操作重新做一次,继续提交。
关于回退(Undo) 操作,和传统的 svn 代码管理不同,我们不能每次简单的回退一个版本。因为涉及多人协作,这样做和干扰他人的工作。
恰当的方式是,先向 Server 查询属于自己的最后一次操作,并递归回退相关影响的对象。
另外可以提供查询 History 的功能,可以查看整个地图的制作演变过程。
其实,多人协作这个功能只是一个结果,不是这个方案的主要目的。
我实际想做到的是,可以以 Server 作为一个数据同步中心,可以把地图编辑的多种功能完全隔离开发。每个工具只专心做好一件事。它们可以忽略掉自己不认识的数据,仅仅显示自己可能关心的数据(只读),修改自己份内的数据。
比如,拉地形高度图的工具往精里做地形编辑;摆放物品的工具调好操作手感。(这两种工具需要的摄象机操作方式可能不同)甚至可以有个专门的观察器,只用于多角度查看编辑效果:顶视、第一人称漫游、特定角度等等。
一旦工具内容专一,我们可以取消繁杂的界面,不把精力放在这个方面。也可以不必苛求渲染引擎的一致。甚至有些工具可以简单的用 2d GDI 方式实现。比如,圈定战斗区域,规划路点等等。
而美术、策划人员使用之时,完全可以多配备几台显示器,用多进程的方式启动多个不同或相同的工具(相同的工具是为了从不同视角观察地图)。最多我们做一个 Chrome 那样的专门进程管理器来管理相关进程而已。
这就有点像 Unix 哲学,用小工具(特定编辑工具)和管道(数据同步中心)组合出强大的功能来一样。每个工具都能有持久的生命期,并可以专注于特定目的做的更好。