Quake 3D Engine The big picture

来自于http://www.bluesnews.com/abrash/

这系列的文章应该描述的是quake1的相关设计的.这篇主要是引擎的宏观设计理念的介绍。

Quake是CS结构。客户端负责收集用户输入和显示游戏内容,服务器端则是游戏的逻辑和同步部分。由于是多人游戏,所以服务期端会在一个特定的时间片内处理用户们的输入,然后返还给各个客户端。客户端则收集每个Frame中的输入,发送给服务器。在这个结构里,服务期端负责游戏的逻辑,物理计算等任务,是个瘦客户端的设计。联想到那个年代,客户端是DOS,或者windows95,应该是可行的。

其他的好处就是用户之间的同步在服务器端进行,通讯程序实现调试比p2p方式简单。网络通讯模块,开始使用的是可靠连接,服务器向客户端传送的是增量数据,也就是客户端状态的变化量,而不是全部数据。这种设计有两个缺点:

  • 两次握手造成的延时;
  • 客户端的状态数据有历史依赖性,因为只有得到全部的增量数据,才能从头建造当前状态。

后来的设计是:使用可靠连接传输分数和关卡有关的数据。而客户端的位置等数据,是通过不可靠连接传输,数据是完整的,不是增量的。这个数据包含所有的客户算得数据,如果有包丢失,那么这个时间片的服务器时间就没有了,游戏有个停顿,但是,时间片很短,100~200ms,应该是可以接受的。

也就是说,客户端收到的是整个世界的数据(某一个时间片之内的,或许可以根据不同客户端,进行剪裁,呵呵,这样每个客户端需要传输的数据量就会小很多,例如,看不到的敌人,就不需要知道他的信息了)。

延时会严重影响游戏的可玩性和用户体验。对于用户在客户端的每个动作,都是由服务器端进行计算并同步。如果在客户端进行计算,则会有非常复杂的逻辑设计。因此,quake采用的是在服务器端进行计算。然后同步所有的客户端。有一个动作不必与服务期端同步的,那就是转视角。用户可以很快地转动视角。(我想这个地方有很多可以做的,如果对动作分类,“只读的”动作应该可以不使用服务器同步动作,但是这个不是很好判断)。

Quake使用内置的Quake-C来作为脚本,描述每个物体的逻辑。(宏观上来看,游戏中的数据是静态的和动态的两种,而动态的,就是可以使用脚本来定制的部分。这样,我们就有机会制作自己的地图和角色了)

对客户端来说,最重要的就是3d引擎了。数据可以分为世界数据和物体数据。世界数据是静态的。物体数据是可以移动的数据。物体包括怪物阿什么的,使用比较多的三角形。开始的时候3d引擎使用一个渲染管线。但是效果不好,因此,quake引擎使用不同的渲染管线。

世界数据存储在BSP结构中。多边型的绘制,主要是边表技术。为了提高渲染效率,减少边表的规模,quake使用了PVS技术。首先限制多边型的边数,然后综合BSP+PVS技术,绘制边表。实际的世界数据,是要事先经过计算的。这样在渲染时就可以使用计算后的数据来提高效率。这就是为什么quake提供了bsp编译器的原因。(输入的模型应该是CSG描述的,而不是BREP数据)