« 冰与火之歌果然是个好游戏 | 返回首页 | 降低 lua gc 的开销 »

关于地图编辑器的一些想法

大凡 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 哲学,用小工具(特定编辑工具)和管道(数据同步中心)组合出强大的功能来一样。每个工具都能有持久的生命期,并可以专注于特定目的做的更好。

Comments

用git管理數據嗎xd

虽然评论里反对居多 但我支持你→_→

chentan
每次我推销自己的观点的时候,大部分同事都认为:第三方的东西,必然存在很多的bug,不如自己写。

我也常遇到,他们都认为自己最牛x,没办法。一个流行的,各大公司都用的开源产品他们都这样说。经过这么多人的验证的产品难道不比他自己写的好么?

刚刚入行没多久,先前也在考虑自行研发一个简单的2D引擎,并携带专门的编辑器。
楼上朋友说的RPGMakerVX用过,自己也曾尝试将所有功能都集成到一起,后来发现真的挺麻烦。
云风大哥的文章倒是给了我一定的启示,虽然没有复杂到产生C\S结构,不过,我想我可以尝试多写几个.EXE,让他们分别实现编辑器中的不同功能~

个人认为这个部门可以参考ECLIPSE的框架

2D游戏的话,个人觉得《RPG游戏制作大师VX》很不错

to hacker47
游戏的美术资源,就是图形算法要处理的数据。
所以美术资源的结构,就是图形算法的数据结构。
算法和数据结构是紧密耦合的。
适用于所有算法的数据结构实际上根本无法发挥特定算法的优势。
就像你要对数组存储的数据进行插入排序,而对链表存储的数据进行交换排序一样,虽然程序可以运行,但纯属扯淡了。

所以,你所讲的把内容制作和算法分开,虽然肯定可以实现,但是纯属没事找事。

太难了。。

不知道LZ认为一个整合的编辑器以及引擎是一个什么样子的复杂度,我个人认为很简单。
一般一个支撑国内3DMMORPG的引擎我估计也就只有10w行的代码,编辑器6w左右。
看起来好象一个人用一年的业余时间就可以完成了,所以我才认为没有分离的必要。
也许我们对制作一个什么级别的引擎理解不同吧。可能是我想象的引擎过于低级了。

我得仔细想像下,那是一个什么样的编辑方式。

我得仔细想像下,那是一个什么样的编辑方式。

关于这个问题,还记得在杭州,和云风争论了一个晚上,也没有结果,感觉云风应该多去听听美术/策划同学的使用感受,而不是仅仅为了实现unix的简单分离哲学,按照云风的思想肯定能做出一个c/s的编辑器,但其易用性值得考虑.

难以想象的是, 如果photoshop的各个小工具(油漆桶/钢笔等)工具都分离了,用户使用起来什么感受?

换个角度看,分离可以把事情做的更好。一些曾经认为不可分的东西,也未必一定不可分。

从这段时间的应用来看,最直观的第一点好处:

美术想知道从某个角度看一个远景的效果,比如从城镇中,远眺山景。

这个时候他很自然的打开了两个窗口,一个摆好视角。另一个拉到山头上去修地形。修地形的效果立刻就在另一个窗口显示出来了。

同时还可以有一个漫游窗口在游戏世界里到处跑跑。

如果做到一起,势必需要给编辑器加上多窗口支持。虽然多窗口渲染也不是什么难事,但增加了设计复杂度。

设置路点,触发点,地形,摆物品都是可以分开的。只不过原来集成在一起的时候,是靠工具栏去切换操作,而分开了,是靠切换进程窗口而已。摄象机的位置,操作的角度这些,如果需要都可以通过统一机制同步。

关于呈现的部分,最终游戏总要做的,并且支持所有的数据,所以是不可节省的。仅仅只是把数据源从硬盘改成网络而已。对于设计良好的 3d 引擎,数据来源是个黑盒子,不会增加什么工作。

而对于特定编辑器,不需要可以呈现一切。比如游戏里需要用 SpeedTree 但不是所有编辑工具都需要用 SpeedTree 去呈现,它只需要表达出那里是颗多大的树而已。美术如果关注整体效果,完全可以开一个游戏也连进去,放在旁边方便随时查看。

对于数据状态同步,远没有想象的复杂。因为对于服务器,是不需要具备任何 3d 有关的知识。这些功能模块就自然的被正交分离了。

最终,所有小工具合起来的代码还不到原来做一个完整 IDE 的代码的一半。用更少的总代码量做更多正确的事情,这才是设计的目的。这是要跟过度设计分开的。

C/S 结构的这种思想古已有之,不是什么新鲜玩意。统一的通讯协议,而不是代码接口,X 和 openGL 都是这样设计的。

最好还是因需而定吧。否则用户不答应也不好。

即使是一个初级的编辑器,某些功能恐怕也不好分离。以下功能应该被整合。例如:
1. 地形编辑(包括地表高度编辑、地表纹理编辑)。
2. 模型摆放(Max导出的固有模型、场景贴花模型、草壤特殊模型、树木特殊模型、粒子模型、触发器、曲线编辑、寻路点、摄影机、光源、辅助标签等。
3. 渲染(Lightmap生成、Radiocity生成、合成阴影图生成等)
4. 性能调试工具。
5. 引擎Debug工具。

这些功能的紧密性太大,例如:
1. 美术需要一边调整地形一边修改模型的位置。
2. 一边摆放粒子一边修改粒子参数以适合场景。
3. 一边处理曲线轨道一边调整地形防止曲线撞地。
4. 一边渲染Lightmap一边修改模型位置,保证得到更加漂亮的影子。
5. 一边设置摄影机位置,一边设置贴花参数并渲染贴花,发现位置不合适可能就会调整地形和模型的位置。
6. 尤其对于特有的模型,例如引擎集成了SpeedTree之类的外部库,或自己开发的植被系统。
那些繁多的参数可能更加需要在一个统一的场景管理器中进行编辑,以得到适当的效果。
7. 性能调试和引擎调试工具就更要集成在一起了,调试者可能需要随时修改场景,并进行性能和功能的调试。确定性能瓶颈以及BUG位置。
8. 其他的一些外部库,例如PhysicsX或者Havok需要进行场景碰撞调试等工作,都需要集成在一起运行吧。

很好举例。

搞不好分离开才是过度设计。才是最最不靠谱的事情吧。

所以我还是比较倾向于模块是相对独立的,但是功能是整合的的编辑器。
对美术策划来说易用,对程序来说易维护。

过度设计是程序员的原罪,哪个程序员都不安分守己,总是想搞出一些新名堂。并洋洋得意。
即使是那些嘴里喊着千万不可过度设计的程序员,也肯定为自己巧妙的构思而偷着乐吧。

稳定/高效的底层库/核心,和以图形处理/操作为中心的用户界面,是两个不同的领域.

拿底层库/核心的设计思想,去套"用户界面"的设计思想,就象,是让火车头电动机的设计思想,去套电动汽车的电池设计.....

IBM的OS2出现时,业界的评价是"第一个,可以让普通用户,不需要经过过多培训,就能轻松上手的GUI系统"

那个时候,IBM做银行大机的OS/DB和各种工具,已经做了多少年了?而这个时候,才做出第一个"让普通用户稍觉方便的GUI系统".

斗胆提醒一句:
unix/linux体系结构设计精美,生命力顽强,但却不是最流行的(大众化)。
反到一个质量最差的操作系统特别流行。。。

其实是个两难:
每个程序都只作好一件事情,程序自身稳定,好维护,并且把组合的自由直接给最终用户;但是同时,也提高了使用的门槛。。。

云风的作法更像是RISC指令集的思维策略:把一件大的事情,分成更精细的小的事情来完成。这种作法的优点我们这里暂时放下不谈,其最大的缺点是:把原来控制在一个IDE下的复杂度给暴露了出来,因此本文后面云风十分必然的要大费周章的设计出一套协同机制。——这如同RISC把复杂度从CPU内核转加到编译器的道理一样。

如果我来设计,我会采用中庸之道——在一个大的IDE下,包含一系列小的工具。即可一起运行,也可分开独立运行以检查各步骤间的问题——这有点像目前编译器的情况,各家厂商都选择了这一策略:一个可视化、处于核心作集中调度的IDE,然后在bin下面又包含了一整套的工具,把预编译、编译、优化、链接、汇编等等独立出来。

如果让云风做一个类似魔兽争霸、Crysis这样的编辑器,估计美术策划还有关卡设计师都疯了。现在国外引擎工具的趋势是整合,尽量把相关工具整合到一个IDE,比如特效编辑器做完的素材,直接就可以在场景编辑器中使用,还有像流程图编辑,天气效果编辑,都需要很形象直观的表示,降低使用者的门槛。像unreal/crysis基本上游戏数据都有相应的工具来显示(编辑)。如果你把各个工具分开之后,举个例子,你把地形拉高了,但ld要求地形上面的实体跟着地形变化,怎么办。

做界面我从来不做插件式的开发,只以最少的代码完成功能,重点是易用性。

参照现实生活,你居住的楼房由装修工人装修的,但你不会在装修期间居住。

但是房子还是同样的房子。

分布式的游戏制作工具是很有必要的,剑网3内部就有大量的这种工具,工具把一些会冲突的内容隐藏起来(比如说ID等,由后台分配),然后操作同一行加锁,操作不同行或者添加新行都可以并行进展,后台是个数据库,没有这种方式,几十号上百号人协同工作几乎是无法想像的。

不过场景编辑器也这么搞个人觉得必要性不大,本身分工可以很简单明确,按场景直接就分开了。并且需要同步协同的东西更复杂。

我觉得楼主可能没有写过比较大型的编辑器,很难想像当一个人在编辑地图的某一部分时,另外一个人也在编辑同一部分,这就好像你在编辑一个c++文件时,另外一个人也在编辑它,并且那个人的编辑结果居然可以被你立即看见,类似于楼主提出的这种方式会带来很多的麻烦,比如说数据传输量的问题,undo/redo的问题.
另外,用小工具组装完成大功能的概念在使用的时候是有难度的,对于content creator来说,这个门槛我觉得有点太高了,不能仅仅从实现功能的角度来选择最简单的方法,也要从使用者的角度考虑.我相信大部分的普通content creator对一个整合的,功能全面的编辑器会觉得更友善一些.你也很难想像photoshop或者3dsmax被分成很多小工具,楼主不喜欢集成环境,不代表所有人都不喜欢.

有点类似GIS领域的多人共同编辑地图。
引擎只是对某一数据库里面的内容进行显示。
至于以什么样的方式去编辑这个数据库的内容,就是外部决定的了。

这就有点像 Unix 哲学,用小工具(特定编辑工具)和管道(数据同步中心)组合出强大的功能来一样。每个工具都能有持久的生命期,并可以专注于特定目的做的更好。

这才是关键

深有同感。
我们现在做的一个网络游戏引擎就有一个超级复杂使用Lock自带版本管理的All In One编辑器。
游戏项目开发的中期就发现两个比较大的问题:
1. 基于Lock的版本管理不靠谱。最后还是退化成单人编辑了。
2. All In One编辑器非常难以扩展和定制。Bug也很难清除。更不用说调整手感了。
3. 数据的导入和导出比较困难。

UNIX的编程哲学确实是久经考验的哲学。
一个程序只做一件事,并做到最好。再用进程协作的方式组合成一个工具链是最有效的方式。

一个用脚本驱动的,多进程,工具链,应该是我以后设计引擎的范式之一。


做个Web版本的编辑器好了,核心还是数据,必要的时候合成上图片就看到效果了。

其实你是完全误解了我的意思,所谓通用编辑器不是指大而全企图解决所有问题的编辑器。我所谓的通用编辑器的核心思想是建立在一个统一的可自描述的数据存储格式基础上的,一旦有了统一的格式,就不再需要特定的数据存储读取代码,编辑器产生的数据可以被任意的读取,而且不同的数据就可以用不用的编辑工具来编辑产生,而不再需要一个大而全的编辑器了。编辑工具一旦特化到某一类数据上,那么这种编辑工具就具备了通用型。此谓通用编辑器。其实这些跟你文件里的所提到的是有些不谋而合的。
问题的核心不在于编辑工具怎么写,而是春据存储的格式怎么设计,如果是考虑纯文本的数据,XML也可以胜任,但是游戏里一般都需要大量的二进制数据,即使文本数据的量也往往不小,出于性能的考虑,基于二进制流的格式还是需要的。另外如何定义数据的自描述的meta-data也是需要仔细考虑的问题。

@analyst,

首先是看有没有必要写编辑器,如果可以用已有工具比如 ps , max 可以办到,那么就不要做。

其次是为专有目的做编辑器,解决 ps , max 这些做不了的事情。而且一样东西解决一个问题。

所以,我还是那个观点:一个大而全,企图解决所有问题的编辑器是没有必要的。

呵呵,前段时间跟云风提起过编辑器的问题,当时本来想谈谈通用编辑器的,云风却非要跟我扯有没有使用编辑器的必要,让我很无语啊....

@liuworld

锁机制是一个陈旧的概念,应该屏弃。

观察器也是工具的一种,其实游戏 client 本身也是观察器之一。你完全可以一边编辑,另一边运行着 client 看。

还有 关于写作开发地图的工具已经有实现了,可以支持同时4人开发,并且能够实时看到别人编辑的内容,还可以在指定的区域加锁,防止其他人编辑

分开工具是有问题的,开发出来的工具是给美术用的,整张地图的美感要从整体考虑,如果是工具分开,不说操作和培训,每次做完了以后看效果都不好看 。
而且worldedit 没那么负责,我们自己worldedit 比魔兽争霸的还要功能丰富(包括环境光和shader等都可以设置),但其实开发起来并没有想象的那么复杂。

其实这种设计也可以说成一个框架:OS的进程机制+协作协议:)
只不过这种框架并不是把未来的东西塞进已有的框框里,而是把已有的东西粘起来,当有新的东西加入时,再涂点胶水就行。
不过这还是需要一些手段做支撑的,云风有空的话看看这个链接里的讨论,发表下看法:
http://groups.google.com/group/pongba/browse_thread/thread/ec177e2f1312cdbf/468686c8510b0f5f?show_docid=468686c8510b0f5f

git是否能满足要求?

受教了, 谢谢云大哥指点, 我们作了一款图形编辑软件, 框架是我设计的, 一年了, 框架还在不断改, 跟楼上说的初哥一样. 现在也倾向于写小工具,写精简的接口, 特别是现在对字符串和TCL很迷恋,呵呵

我的很多同事都喜欢写一个framework。

我则相反,随便找一个流行的,觉得够用就可以。

每次我推销自己的观点的时候,大部分同事都认为:第三方的东西,必然存在很多的bug,不如自己写。

云风的这个思想其实是CSCW领域的一个重要分支,是很能出paper的:)很多学校都有专门研究这一方向的实验室

一上来就喜欢写framework的,大多是不知道过度设计的初哥。
生命是有限的,这么多framework,先不说能否写的比人家好,自己先看看有没有现成可以用的总是最好的选择。

UNIX的设计思想。

其实看了你上面的叙述,我也觉得是像UNIX哲学所谓的小工具模式.
很久之前就有一个想法,为什么不把游戏引擎的开发和最终的内容制作分开呢,这样游戏引擎的开发者可以集中精神对算法进行优化,而内容制作者可以展开天马行空的想象.
呵呵不知道是不是有点异想天开.

高山仰止啊!

这个想法太棒了

Post a comment

非这个主题相关的留言请到:留言本