游戏服务器架构简述--逻辑服务器

来源:互联网 发布:ai软件图标 编辑:程序博客网 时间:2024/06/10 15:15

    最早的商业化的逻辑服务器恐怕是mud系列了,国内的商用服务器大部分都源于此。在以前简单的说过mud,为了支援简单的访问模型mud的网络结构比较简单,没有线程结构。早期的扩展把mud作为了游戏逻辑服务器交互的命令一般通过一个服务器中转到mud.因为和客户端交互的指令已经不限于早期的文字,大量的图片,渲染,甚至声音这些已经不需要mud处理的了。完全可以通过简单的文件压缩然后下发客户端,通过文件名称等方式供逻辑系统调用。提到逻辑系统不得不提到一个概念心跳。目前的mud使用心跳的只是为了在定期的执行一些指令,所有的物件心跳是相同的。有一个很有趣的例子当把所有的指令通过一台服务器发送的到逻辑的服务器时。指令发送的快慢实际变成了服务器时间。传送的快服务执行时间就快传送的慢服务执行时间就慢。服务器的心跳演变成了服务器的时间每一次的脉动服务器时间就加一。但每个人的时间为什么要一样呢。如果不考虑思维一个人单位时间内作的事情多了,他的时间就快了,如果一个人单位时间做的事情少了他的时间也就慢了。如果考虑思维一个人想得多了他的时间也相当于快了。实际不过是人的身体里有好多的时间单位而显得时间不那么统一而以。当我们控制了时间的时候构造一个世界就容易多了。我们知道用户行为是由一些列的命令产生的命令和行为的最大区别就是行为和行为间没有因果关系而命令间会有因果关系。
   为什么要区分命令上因果关系呢?前面我们把用户命令放到一个命令中转服务器里有中转服务器调用逻辑服务器注意这里的调用。逻辑服务器是被动的执行指令时间在这里被强迫的单一成一个线。容易产生一个问题就是一个用户的指令如果有问题都会令这个世界都崩溃的尴尬局面。只有两个指令是没有因果关系的这才是和我们现实世界很相似的描述。一个行为只能有两个可能,有效的和无效的,有效地指令到的结果奖励,无效的指令无结果。在游戏世界常用的一个判断是只有一个命令做完才可以引发下一个命令的行为逻辑在现实世界是的一个行为改变了某些东西可以用另一行为继续改变这个物品。重要的概念,行为是不应该有束缚的。什么样的行为有什么样的结果。这是游戏逻辑的行为,但又为什么要引入命令的感念呢。因为软件的行为是要有束缚的,在有限的资源内软件的行为是要有前提的。例如菜单的先后逻辑,模式对话的选择。这些上下文关系是临时的当一个行为结束例如对话结束时这些上下文的数据也就失效了。
   既然每一个人都应该有自己的心跳当心跳开始的时候他就应该执行一个行为。这里要区分其他人的行为作用在他身上和他自己的行为。例如人家坎了他一刀,他流血这是其他人作用在他身上的行为,而不是他自己的行为。
   回过头在说时间每个人都有自己的时间只有在自己的时间内执行行为才符合现实。所以每个人应该在自己的时间去找自己该做的行为,同一时刻可能会爆发多个行为这些行为是并行的。游戏的多线程会不会有产生逻辑错误呢。我认为游戏的逻辑数据不应该有多线程安全的问题。最简单的多线程安全的问题是一片文章修改其中一部分的内容,两个线程同时修改就会产生逻辑问题,或另一个情况是一个线程读一个线程删除,抑或一个线程喝药一个线程减hp如何判定死亡。但我相信无论上述那种情况都不会造成困惑。游戏不会有第一种的情况,游戏的数据不能删除整数都是有范围的整数,只要在数据操作上作好互斥判定实现对单一数据的操作是没有问题的。第三种情况先执行的喝药就不会判定死亡,现死亡喝药就是无效的行为。那么服务的行为就是收集用户的命令按心跳的频率指示线程池分配线程执行命令,并淘汰过期的指令,排列指令的优先级,并在指令到来的时通知对象。对象调用行为的脚本代码执行相关的行为对数据集进行一次操作。

   捎带说下面相对象是一个概念,其核心的原则是方法依附于相应的数据。但忽略了一个很重要的概念方法可以作用的不同的数据局集。方法和数据是相对的用那种组织形式都不能可能完美,为了解决方法的通用性有了模版的概念但他是一个编译前的概念而不是动态的。继承有时很好用不过超过3层以上的继承就会让人感到很混乱通过继承的复用的情况也真的不是太多。面向对象完全是一个概念可以用这类的思维方式组织程序。组织的方式也并不完全依赖语言,甚至很多情况是语言无关的。我发现越是简单的语言生命力越强,其实用C也可以完全做到面向对象只要你用面向对象的方式去写程序。服务器的情况和应用软件不太一样,以C++为例应用软件在进程范围内变量的使用和C++的对象变量的使用是重叠的,也就是说在编译过程如果没有把变量声明为全局变量哪么就会报错。服务器的变量使用是在个个不同的线程甚至是跨语言跨进程,使用一个数据只有在运行的过程中才能发现是否有错误。在服务器的面向对象更多的是指的是概念上面向对象的方式组织工程的开发。所以“云风”常常提到他写程序更喜欢C这种简单的语言。无论概念上的面向对象还是概念上的方法复用都是运行时段报错,把这种开发的方式提高到了工程的角度,而不是简单的依赖编译器来纠正工程学上的错误。

原创粉丝点击