• 服务器框架回顾


      【c++端游】

      第一个接触的游戏项目,MMORPG,虽说MMORPG有蛮高的技术门槛,但那会大多在写逻辑,很少深入底层,所以收获有限。

      win平台的,整体看分了三层:HomeServer、GameServer、四个DB进程(AccountDB、CharDB、LogDB、MailDB)。HomeServer负责登录排队、同中控、平台交互等;GameServer是游戏主体,内部除了数据库、网络IO......游戏逻辑相关的采用了单线程架构,有统一的Service循环框架,各种功能都是注册进Service由主循环发起,比如:AI、Buff、移动、玩家数据写库...

      在线玩家均放于内存池中,因单线程缘故,所以对强交互的支持很高(不必考虑并发操作一致性,rpc调用,rpc delay……)。类传奇的战斗方式,也能应付密集计算。

      可惜整体上的实现了解不多,深入研习过的只有三个部分:AI、网络模块、活动设计。

     

      我们的AI是个基于虚函数的递归调用系统(本质用的解析器模式),附带初始化时指定切换规则。简单说来分为三个层级:

        1)Do:执行基础动作,如走路、攻击、睡觉

        2)Base:对Do层做简单包装,加入条件判断、控制等,如随机走、围绕某点、跟随

        3)Logic:组合任意AI(Logic之间也能互相组合),有切换逻辑

      同行为树的区别:

        1)逻辑判断、行为写在了一起

        2)行为树提取了通用节点,易于组织逻辑,比如

          a)Selector Node

          b)Sequence Node

          c)Parallel Node

      与外部系统交互上:

    • 行为树
      • 弄个全局变量/dic,写condition检测
      • 新增对应条件节点,Update时自己检查
    • 项目AI
      • 通过事件类型,直接告诉AI切换行为( OnEvent )
      • AI内部只关心自己的常规流程,比如巡逻、攻击、跟随…
      • 特殊条件的逻辑,全交给外界事件处理……觉得这样解耦挺不错
        • 发事件的地方,相当于决策层
        • 行为树里的决策层,就是整个树结构,行为都封装在行为节点,或一棵小树里
      • 相对而言行为树的Condition Node就得拉入外部数据

      

      这个AI系统,对比behaviac的行为树,量级算是很轻了,核心代码不超300行,容易把控细节,且实现大多玩法的AI不成问题。

     

      网络模块,windows下固然是IOCP,这个可以另开贴子详细描述,可挖的东西非常多。

      活动设计,一位大神的作品,用c++做通信内核、数据存放,具体逻辑全放Lua脚本,扩展性非常高,且使用方便。举个印象很深的例子:

      客户端需要的数据是非常杂乱的,很难统一格式,大神在脚本层做了一套指令系统,svr端只需调同一接口发出指令即可,形如“Command#param1#param2#param3...”,客户端脚本中,只需注册同名函数,即能自动调用。发送显示信息方便非常。

     

      AI和IOCP有整理重构过,源码地址:

      https://github.com/3workman/InterpretAI

      https://github.com/3workman/IOCP

     

      【lua手游】

      这个项目的架构比较时髦,Logic、Gateway、Battle、Cross、SDK、Center、DB、World……齐全了。

      多线程架构,c++做内核,Lua写逻辑,其中Logic、Battle、Gateway、DB均可水平扩展。Cross负责后台模块之间的通信,比如Battle同Logic(每个Battle、Logic完成初始化后,去Cross注册下)。

      先说优点:

        1)使用方便,包装的Rpc通信,不必注册消息,且用的buffer传参,代码中连定义消息结构体都省了;

        2)起服流程设计很好,区分了Init、OnReady、Sequence等不同的接口调用阶段,方便数据布局、热更新;

        3)借助Lua强大的mettable,可以做到在业务层消灭所有数据库操作,全底层控制,玩家数据自动同步客户端;

        4)支持逻辑事务性,server端批量操作,直接调接口,只要一个失败,整个msg调用自动回退……爽的一比,不用预先搞一坨判断;

      缺点也明显:

        1)底层有大量的数据拷贝,性能不高,作为手游服务器,貌似仅支持5k在线

        2)不支持强交互,同erlang、go自带的轻量线程不同,这里的是系统级线程,玩家之间的数据修改加锁的,且无法保证时序上数据的一致性,比如B先改了A的数据,C再去访问,很可能C拿到的还是旧数据……批量玩家的数据交互,甚至需要开发者自己预估竞态,然后用对应技巧规避;

        3)该服务器原用于页游的,被设计成:一个服务器进程可跑多个服的数据,所以一个线程可能在跑几个服的数据,而一个服的数据也会分在多个线程中。这个特性让你在写代码时要额外注意,比如A、B两玩家若分配在不同线程,那他们彼此是不可见的,用错API就一直返回空了;再比如活动数据,要求全服一致,就不能随便乱放了;

        4)静态生存期的数据种类太多了,有:玩家数据、玩家临时数据、ShareData、玩家共享数据、lua文件数据、全局_G数据……要理解它们各自存在的目的、适用场景~~可得一番功夫

     

      虽说如此,但这个架构我觉得是很优秀的,尤其设计思想,几个优点带来的福音,写代码high爆了,开发效率非常高,一个熟手就能应付全部svr端任务。

     

      【go手游】

      最近刚接触,go是个很好用的语言,并发虽然没erlang那么牛逼,但一般的游戏绝对够用。且写出的代码可读性高(也有不好的,没奇技淫巧玩,硬编码的写法多了不少),静态语言省了一大部分动态语言的debug时间。

      说回架构,这个项目用的多进程架构:accountSvr、battleSvr、chatSvr、crossSvr、gamesvr、logSvr、mongoDB。

      主逻辑服务器gamesvr用的http短连接(上面两个都是用的长连接,Battle战斗服务器用的UDP),battleSvr、chatSvr用的tcp长连接同client交互。

      每个模块都是单独的一个进程,架构非常清晰,功能内聚,很有些每个模块提供一种服务的味道,可以继续延伸,还在研习之中。

      这个相比之前的服务器,最大优点是简单、清晰,学习掌握成本很低,且够用……嗯,这也是go的设计哲学呐(*^__^*)   

  • 相关阅读:
    csharp: mappings using Dapper-Extensions+Dapper.net.
    SQL Anywhere5.5: Metadata
    Csharp: read Sybase SQL anywhere5.5 using c#
    Sybase SQL anywhere5.5
    Spark基本概念
    Spark之RDD(含Java运行环境配置)
    Spark简介及安装
    Scala编程进阶
    Scala面向对象
    Scala基础
  • 原文地址:https://www.cnblogs.com/3workman/p/5754330.html
Copyright © 2020-2023  润新知