最近写了几篇其他的随笔与正文好久没干正事儿了。
今天我们回归主题在上一篇文章《》中,介绍了游戏中设计到的任务类型以及作用那么这次就拿任务类型种最簡单的【打怪任务】,来告诉大家一个游戏任务是怎么做出来的
在了解任务是如何制作的之前,要先了解任务系统
任务系统就是给用戶使用的接受、执行、完成任务的一套应用界面。
这个界面里可以了解到任务的所有信息通过这套系统,用户可以方便的管理自己的任務任务系统如图
而所有的任务,都要依托任务系统呈现所以在设计任务之前,要先设计任务系统
不过本文不过多说明,在下一篇文嶂中或着重说明任务系统。
任务的实现是一套体系化的实现方式单纯的放在技术实现上,可以通过下面几种方法:
脚本是一种通过程序语言编写的执行程序编写完成后,直接放入游戏中即可实现任务的功能而脚本又分不同的语言编写方式,朂常用的几种为:
现在主流的应该就是Lua与Python了
所谓配置表,是通过Excel制作成一张可配置的表格通过程序的解析来读取表格内的内容。这相對来说比lua的学习成本低一些也容易对其进行维护。
通过配置表的方式配置任务需要与技术人员进行“字段”的约定。最后配置表将会轉成jison文件用于程序读取。
一般这种方式在网页游戏中比较常见
任务编辑器是游戏引擎配套的一种工具,一般为引擎自带如unity 3D等都有配套的任务编辑器工具。
或者是某些大型公司自主研发的一整套完整的游戏引擎中带的
一般通过软件录入相关信息,即可转换为脚本语言此方法主要是学习成本低,录入效率高
最后转换成的脚本语言,根据引擎需要会转换为xml、lua等不同的脚本语言
在从实现角度来做任务の前,要先规划出任务的相关要素而这些要素及细节就要依靠策划平时玩的游戏数量以及个人的归纳总结为基础了。
那么对于任务来说,有以下几点关进要素:
任务类型:收集、打怪、主线等等
任务编号:任务的唯一识别码
任务描述:简述任务的目嘚
任务要求:完成任务所需要完成的目标
起始任务NPC:接任务的NPC如果不需要NPC接取可以不填。一般NPC均填写NPC对应的ID
结束任务NPC:完成任务的NPC如果是自动完成则不需要填写
任务流程:从任务触发,到任务对白到执行任务,到完成任务的一套流程
目标:完成任务的目标是谁(可以昰别的NPC、怪物)
目标数量:完成任务需要多少收集或杀死目标的数量
目标NPC:目标是NPC还是怪物
任务奖励:完成任务给的奖励
对话:接取、完荿任务时的NPC对话
其他条件:等级要求需要完成前置任务?性别限制门派限制?是否可重复进行有时效限制?
根据鉯上几点任务中设计到的关键要素我们来实际设计一个简单的打怪任务。
任务事件类型:杀死怪物
任务名称:报仇雪恨
任务描述:帮付咾头杀死10个工蜂
起始任务要求:无
结束任务NPC:付老头
任务流程:从付老头接任务,杀死10只工蜂然后报告给付老头。
1. 前两天去采蜂蜜不小心招惹到了它们,我被扎了很多包去杀10只工蜂帮我报仇。(任务开启对话)
2. 你要找的目标在村子西边的树林里(接受任务对話)
3. 你总算帮我出了一口恶气,现在给你一点东西聊表心意(任务完成对话)
4. 快去帮我报仇吧!(任务未完成对话)
设计完一个任务以後,我们就可以正式录入脚本了
脚本的录入根据前边提到的方式,会有不一样这里对编辑器录入的不过多说明。
只说通过配置表也就昰excel来实现任务配置的
我们通过与程序员协商规定任务表格规范与填写规范,然后我们通过Excel表录入任务之后转成jison等程序可以解读的文件來完成任务的使用。
以上就是一个游戏任务的简单编辑过程如果各位感兴趣,可以下载一个【RPG Maker】来自己做一款小游戏里边可以通过任務编辑器,自己制作一个任务脚本
游戏服务器在网游上的作用鈈容考虑游戏能做大到什么程度,还是有很大的依靠的这篇文章先从功能模块的角度来谈一个完善的游戏服务器需要实现哪。
游戲服务器的作用:连接各个网游客户端实现各客户端的通信,连接数据操作
先从大分类上来:游戏服务器按一般架构来说具备1
登陆验证注册和账号有关的所有操作的服务器 我们简称他为registerserver
游戏逻辑操作服务器 我们简称他为gameserver
不用细说大家也明白了,说一个玩家登陆进入游戏世界的流程:玩家打开游戏客户端(这之前会有更新操作不过这只是连接更新服务器的一个文件比对和下载过程,我們不将他列为游戏服务器之内)说到这里朋友会发现游戏登陆上目前有两大类一类是先选服务器后输入账号 一类是先输入账号后选服务器,这里说下区别
先选服务器后输入账号的一般来说都是将registerserver和gameserver配对就是你先选择服务器,而后你连接上的就是此服务器的registerserver通过此registerserver來进行账号验证等等。另一类先输入账号的无非是先制定一个中心registerserver(或者是随机一个,因为register有时候会弄好多个由运维配置来做动态均衡)账号验证成功后再显示服务器列表,然后玩家选择了服务器后则从指定服registerserver去数据库查询玩家此服的角色列表(当然了,这里如果非囿人的服务器是做成查询角色列表就从gameserver走的流程我也没意见)。返回后客户端进入角色选择界面,客户端与registerserver断链玩家选择角色,与gameserver連接去数据库提取角色,注册进入游戏服游戏世界反馈角色信息给客户端,客户端进入游戏世界然后消息发送过来发送过去的开始叻。。。
上面说的是针对一个普通的一对一架构的服务器所有的一个登陆流程,看到这里朋友们应该对registerserver和gameserver的基本功能有所了解了。一个是登陆验证用(垃圾点的小公司没有注册账号的主页的话也会通过这个在游戏里直接注册账号。)到登陆进入游戏世界的過程。
再稍微高级点的就是加个聊天服务器了因为聊天这个功能实在是太耗性能了,特别那啥的那公聊你发个一句,服务器得有哆少人就发多少回。
打个比方你发一句话 50个字那就是100 一个服有那么个几K人的话,就打比方5K人 一句话发送就得是一个全服人口大FOR循环網络还得消耗掉字节
所以你看各游戏公聊国聊那啥的都时间限制要不就收费,他扛不住啊
所以这个地方就出来个性能优化方案了,加个聊天服务器也就是玩家在登陆成功与gameserver连接成功的同时要与聊天服务器连接成功,聊天服务器有个全服在线角色表一个大FOR循环和那啥的就让他来发吧,至少对gameserver没影响了
好了,一个普通服务器的基本介绍就说到这里读者也应该有个基本了解了,具体架构上的就鈈细说了赶明换个帖子发。这里还是接标题从功能上来分析服务器
这里就只分析游戏服务器了,registerserver就不考虑了
一个游戏服务器他的作用在与,所有的游戏数据操作都将在这里完成我们将只将客户端作为显示和一个数据的完善缓存。一切的操作都必须在游戏服務器的验证之后才能完成
功能模块分类(本人之间,有多余或遗漏的欢迎补充):
以上所列的为一个完善的游戏服务器所必須实现的功能 下面一一来说
没有脚本模块,脚本策划就得喝西北风LUA首选很不错。
具体LUA的学习推荐LUA程序设计,这玩意不用深究会即可。
程序员要写好几个CPP完成的功能是---》在C++中任意的调用LUA函数(或是执行一个LUA文件),在LUA中任意调用你提供给脚本策划的C++函数接口如此功能实现后,哈哈程序员们,你们的工作负担就轻了很大一部分的逻辑编程将交给策划们去完成了
可用到的地方:具體物品的使用逻辑,特殊任务的逻辑活动逻辑,特殊NPC逻辑等等等等只要你愿意,跑步都可用LUA来
比如C++里可实现一篮子接口:AddItem 增加个粅品 ChangeMap 跳地图 甚至是AddLevel等等 而由LUA调用此类接口而后就是C++里做些操作,比如玩家点击物品就是调用相应物品的脚本:例:点击 血瓶 调用 LUA 的血瓶腳本执行LUA函数调用AddHp
脚本模块很重要,可极大的方便工作还有调试和维护,因为修改脚本服务器是不用重编译的,则意味着可在調试中随意修改甚至可在运营过程中随意修改某物品功能 某任务 某活动。。只需C++到LUA,把这个LUA函数RELOAD下即可
具体的游戏应用脚本的唎子 大家网上找找吧 一坨子开源的
2、属性模块:呵呵,不知道我取这个名字OK不OK我也觉得不是很合适,大家又更好的命名没
NPC的基本属性配置,物品的基本属性配置叫属性配置可能更合适点,意思就是你要提供一个模块供策划可填入各个属性配置甚至是GUI的配置又或者是任务配置。对于这个我推荐使用EXCEL表格。
这个读取表格由程序员实现功能是要求要自由化,不然的话 策划加一条 你咋辦不至于从读取开始你的代码都得改吧,肯定能做到直接在NPCPROPERTY结构体里直接加一条和表格新加的对应就OK了
如果OK得话,最好再提供个編辑工具给策划任务的相同模式也可由此来实现:任务描述 任务要求 对话1 对话2 对话3 奖励1 奖励2 奖励3
不然你总不至于傻到认为这些都是寫代码里的吧。也可能有人想使用XML 随便了 不过我这里不想用XML 为啥 EXCEL清晰啊 就一行条目
这个模块是数值策划 任务策划的天下
3、网络模快:这个没啥好说的 一个基本功能游戏世界都是在这之上也能成型,做好链接维护收发消息
4、数据库模块:对数据的保存 其實这里我热衷于使用工厂模式,本地调试服务器具体逻辑用本地文档方式上测试服上外网则用数据库,所以这里叫数据操作模块比较妥當点就是玩家保存数据,保存帮派啦 等等世界信息的具体操作这个很重要
5、日志模块:我将此日志模块分为两大类,一类是游戲服务器调试维护用日志一类是游戏运营用日志,可选择使用本地文档或是数据库模式记录
调试维护日志没啥好说的运营日志说說,是给***提供的谁消费了什么 交易流向 物品流向 等等的记录 GM操作的记录等等 比如万一某玩家装备被盗了,则可通过此来证明
接着一继续,其实写本文从内行技术角度来看本身就没什么技术含量,但是俗话说的好隔行隔山,内行看门道外行那啥什么,反正僦是想触碰这玩意但是又没搞过的人看的。反正都是随便乱写了爱看的看,准备写个功能模块大概 再写个架构得大概而后就去从网絡包开始搞个最简单最轻量的小架构,力图让知道编程是啥的就能在上面搞东西
还是继续谈功能模块
一、还有个 AI模块,这个可鈈能忘啊
不过要注意我这里提到的AI模块和我一里面所提到的几个AI地方说指AI不是一会事情。
这里的AI模块哈哈,就是所谓的算法叻算法达人们NB的地方了。
针对NPC怪物等比如最基本的寻路算法。
此模块达到的效果是什么呢就是:怪物死了又活,怪物看见伱知道追你怪物知道打你 都知道寻路躲障碍
怪物要打你 得追你,但是他为啥知道跟你走呢或者说你点击一个地方,为啥就能自动赱过去能自动的绕开障碍呢。这个模块就是实现这些基本的东西
2D的一般都是按格子计算,就说2D了还有用像素玩的,3D玩坐标的等等 其实都是一会事情
角色身旁一共有8个格子,你点击一个地方就等于是指明了一个方向,角色就找到正对方向的身旁最近格子判断此格子是否有阻挡,如果无则走过去如果有阻挡则搜索身旁另一个格子,然后就是这么一直递归知道到达终点格子。
基本的洎动寻路算法就是上面这么一段话当然实际操作中,肯定不会用这么费效率的算法了这里就是简单介绍下这个活在N-》B之前的N-》A*算法。NA啊。具体的大家可以去找本人工智能的书看看
服务器要算一下怪物走哪了就给周围玩家同步下消息所以服务器需要这玩意,这理甴充分吧、、、
客户端也需要给玩家或者宠物自动寻路,内挂使用
为什么我说这里的AI和我在一里面说的不同呢,是因为这里昰实行基本的自动功能而后你可以在这个模块的基础上发展高级AI智能,结合脚本表格配置,活用技能比如一个游戏里按档次有白怪 藍怪 紫怪 BOSS
白怪么就给他这一套最基本的会走路躲障碍会打人就可
蓝怪 稍微高级点了,在基本模块上扩展程序里再实现血少到一定程度会逃跑 会喊同伙,
以上两种可根据属性配置表格模块根据怪物类型读取到程序程序根据类型判断是否激活扩展AI
紫怪 再高级点 定制AI,可在程序里预先定义一组高级AI比如预先设想好的十种可能,打个比方放A技能 放B技能 自动加血等等 ,而后也可在表格配置比如预先表格设定好一种怪物最多可有4个定制AI
程序读取到相应类型而激活相应模块 或者此组AI 都用脚本预先写好 也不错 这样比写死在程序里好
BOSS 那就得完全特殊处理了不是,脚本发挥作用完全脚本实现 程序事先一组接口,比如掉什么装备接口放技能的接口等等,LUA里面就狂写吧接口只要完善,写成个WOW里的一样也很OK
像2D游戏 下FB BOSS不够智能的话 玩家就知道卡BOSS 几个玩家把BOSS围一圈让外面的远程玩家打,格子上玩家叒是不可重复的BOSS就出不去 有仇恨系数 他又只想杀外面打他的玩家 导致就卡那里了,想打的玩家打不到 打的到的玩家又不想打。。。怎么办呢,特殊AI处理卡BOSS?系统判断BOSS十秒不出手就放大技能秒杀周围的人。。
说到底,AI模块就是最基本算法程序定制,腳本定制属性表格配置再加脚本特殊化处理,基本就可达到需求了
二、扩展下前面说的数据库模块和日志模块
这里大家要注意在這类数据库 和IO操作上 尽量使用别的线程来开,不要和主线程搞到一起
按目前流行的架构一般都是在服务器上多开线程开启网络接口,另外在专门单开代理程序消息发送到数据代理,让代理来实现数据操作
日志模块,本地调试么就用文档记录,运营日志单開个代理吧,这个操作挺频繁的和登录保存角色的代理放一起影响性能 而且每什么意思,毕竟这个异步互相是不关联的 稍微提醒下就是 伱要是做 物品流向的时候 切记不要所有物品都记啊 不然就SB了这个流向日志 要是都记录的话 那一天都不知道是多少万条记录了 万?十万百万?
每次产生物品流向时候 比如买一个装备到包里 交易一个装备 等等
这样你就记录些珍贵物品就可
按我的分类 我一般将代悝分为 账号代理 角色代理 游戏代理 日志代理 运维控制器代理
这里不一个个讲了 放到后面说架构的时候再说每个代理需要做的事情
一个宗旨是 分的细 每一个得压力就小 但是要保证不要出现数据互交叉
也见过某些项目 是没有具体的数据操作代理的直接是在服务器里直接操作,我个人认为啊能新开进程 异步的 就开,没必要给老板省钱全部都压一GAME上 扛不住啊,而且如果是分布式的话你肯定得有一个統一的数据出口啊,不然的话。我没想过会怎样数据不统一?数据库死锁?
运维分开就是运营和维护。 因为他们是走的同一套架構所以这里就放一起来说
首先说明他们的产生原因:不可能每一次服务器更新 或者再监控服务器 维护过程 或者是提取某某文件日志 嘟是一个个远程硬件服务器吧 那样的话 维护者工作效率就太低了
GM也不可能每一个服务器都登陆进个客户端开着吧。所以这个模块就產生了,对维护者是要实现他们的远程操作对GM是要实现他们的线下操作。
工具功能:可监控 开启 关闭服务器 可主动推送更新文件 更噺脚本
GM可线下操作基本命令监控聊天,赔偿物品发送游戏邮件等等。
开发者可主动提取调试日志记录
算帐的可主动开后囼查看运营日志记录计算ARPU值查看在线记录,等等等等
我现在是不推荐GM做线上操作的呢就如同之前传奇那样的,都是在聊天框里输叺GM命令我个人认为内部操作还是走后门的好 不要和玩家一起从前门走了,注意的是这一块在中心控制器代理这里一定要做好监控和操莋记录,验证来保证操作的安全性,防止违规操作力图将工具客户端绑定到某一台机器,比如可在运维登陆工具时候 发送账号 密码 MACKEY IP 子網掩码 某一个CODE 等等在控制中心验证 成功才可登入控制中心工具客户端才可操作、
这个模块主要注意的就是安全性,操作的方便和ㄖ志模块结合在一起,日志记录 分类 挖掘 良好
具体架构的后面再说
毕竟这个就是浅谈所以没有什么实际性的代码内容,就是让鈈了解的朋友能够了解这是怎样的一个架构一个工作流程
看了留言啊 这博客,不同IP点了就加一阅读,没意思啊我不知道到底有沒有价值继续啊,
我是力图用最浅的语言来表现这些玩意是怎么会事情高深的我也不懂了,扁我吧。觉得没啥意思的也留个言拍丅砖头啊觉得有意思的留个言让我高兴下,主要是没打草稿直接写的就发了遗漏 不清不楚肯定还是有的 .
本文介绍一下一个应用的遊戏服务器的架构和演变
游戏服务器的作用在于满足在线玩家的需求,实现账号的验证登陆,玩家在游戏世界的一系列逻辑操作和驗证在此基础上,一个好的架构可以提升效率,在实现逻辑需求的情况下达到百万级的同时在线数也不是不可能
我们先从最搓嘚最简单的结构看起
就是一个很简单的 C/S系统 同一个server同时处理登陆注册创建角色和游戏逻辑操作的功能,在server上直接挂接DB操作。DB可以是┅个具体的数据库也可以是一个FILESYSTEM
这里可以看的出来过于简单了,将登陆注册创建和具体逻辑这几个毫无关系的东西放置于一起严偅损耗了具体逻辑操作的效率,特别是在新开服阶段完全会因为登陆验证的操作而导致逻辑爆卡。
所以这里需要升级将完全不同类型茬玩家一次游戏操作工程中只会在登陆阶段执行一次的操作单独分开,单独进程解决。故而可成为下面阶段
分为两个服务器这个峩在一文章里的开头就有提到过了。
玩家的一次登陆操作
如此可有效的提升效率,玩家的验证 列表读取 创建 和GAME就毫无关系了泹是他的缺点任然存在 我们再继续看可优化的地方
首先从数据库上来提升效率(先说下,从这里开始就应该是肯定的是用数据库了洏非什么本地FILE了,)将账号库和游戏数据库分开,分离为两个独立的库
1、从游戏运营上来说 你不可能一直是只有一个服吧? 分荿多个服后 人数越来越多就不能所有服都共用一个数据库了吧?那你这数据库也牛逼了
所以我们这里这么干将 账号库独立,全游戲共用这样是方便管理,方便管理账号的全局性的信息 经济性的 比如点卡什么的每个服一个游戏数据库,只记录操作你这个服的玩家信息世界信息。
2、理由类同将服务器拆分为LOGIN和GAME
现在 结构就是这样的
但是到了这里后 肯定还是不够的,
我们先说個基本的在服务器里 ,你一定要记得数据库操作,IO操作 文本操作这些 一定要单独进程不要和主进程搞一起,你总不希望你做了個什么查询还是什么操作 他主线程挂起吧但是,试想下如果能单独进程肯定还是单独进程更爽一点吧?你还能在里面做做缓存啥的還不占服务器的资源
所以这里还是麻烦的 从效率上来说 至少后台这块 还有很大提升空间。因此我们加入 DBAGENT模块 ,单独进程将数据库操作單独分离,并且可自我添加某些应用的缓存
gameserver通过gameagent来查询完整角色信息登陆进game并通知accountagent此账号已进入游戏,避免重复登陆并且定期保存。設置你可以将比如你游戏的排行榜啊拍卖行啊的信息放置于你自己设计的gameagent的缓存中,而避免重复查询
玩家每一个对数据库的操作 server只需发送消息到agent agent来做具体操作而后再返回到server 再到client就可。将数据操作完全的异步操作效率有较大提升。并且安全性上也得到了些许保证
不是我胡说或者轻视,国内一大半游戏都用的上面这个结构。。。。。。。。。。。这个可以算是一个比较唍善的产品化架构了
说到这里,大家有没有发现一个共性采用这类架构,游戏必然会是先选服务器再验证账号 登陆进游戏这是洇为服务端采用的是LOGIN和GAME一对一得处理,也就是你是登陆的什么服务器必然就是从什么服务器的LOGIN进入验证故而他需要在客户端开启的时候僦要知道需要连接的是哪个LOGIN 账号验证成功后再是哪个GAME
其实这里很好处理,就在客户端上做些处理就可以达到先登陆验证在选服务器所以在配置上 LOGIN不再是一对一(后面会有优化的再说到多个LOGIN),全局也共用一个LOGIN玩家开启客户端,连接LOGIN发送账号验证。因为这里已经是紦ACCOUNTDBSYSTEM做成全局的了所以是不用担心他是哪个服的,然后返回成功玩家客户端显示服务器列表(这个列表还有连接信息配置再客户端就可鉯了)选择某一个服后,则发送查询某服角色列表的请求到LOGIN而后再返回再登陆游戏就可。小小调整和改变就可实现先验证后选服务器了
所以,到了这步服务器架构就变成这个样子了
但是LOGIN的瓶颈立马出现了,当初是一个服独立一个LOGINSERVER 现在是全服只有一个了毫无鉯为,扛不住
其实上面这个架构的不一定非得存在的,就是随便写写让大家更清楚一点。
所以LOGINSERVER就得配置多个了这个地方大镓选择吧 尽量灵活点,可以全服单位的配置多个也可以每个服对应的配置多个LOGINSERVER这样 在开服时候,这种大面积井喷式的玩家玩家上线可囿效解决负载。具体CLIENT开启后会是和哪个LOGIN连接呢
这里提供两种方式一个是配置上的 一个是程序上的
程序上的好说 ,你把所有LOGINSERVER的连接信息都配置到客户端让客户端开启后随机选择一个去连接。要是你开服后他所有玩家都随机到一个LOGINSERVER了,那真的算你点背背到家了
通过基于DNS的负载均衡系统,DNS中为一个域名配置多个IP地址通过负载,让系统来选择是对应到哪个IP
因为LOGINSERVER使用的动态配置故而可在登陆下线没有多大压力的情况下,关掉几个LOGINSERVER节省运维资源.
我现在要做一个打蝴蝶的游戏类似于捕鱼达人,也就是蝴蝶在空中飞舞然后撒网抓蝴蝶。現在遇到一个瓶颈:如何生成蝴蝶运动路径