随笔分类 - 游戏服务器
摘要:我的新手游项目很快就要进入到寻找发行商的环节,最近几天相对较空闲,逐将工作重心转移到服务器组运维工具的制作上.回想一年之前经历的那个不算成功的端游项目,因为运维工具设计得不合理,使用十分不方便,游戏上线之后搞得我焦头烂额的.之前一直没碰过web相关的技术,最近几天猛看了下php和javascript...
阅读全文
摘要:Survive之前采用的是C+lua的设计方式,其中网关服务器全部由C编写,其余服务全部是C框架运行lua回调函数的方式编写游戏逻辑.鉴于一般的手游对服务器端的压力不会太大,便将Survive用distri.lua框架重写了一便,distri.lua天生的支持协程,RPC和数据库访问直接使用同步接口...
阅读全文
摘要:经历过网络游戏运营的朋友都应该体会过,服务器集群的管理不是一件容易的事,特别是服务器/进程的数量变得越来越多的时候.我上一个运营的游戏,最开始并没有把服务器管理考虑在里面,开服的时候远程到物理机器上一个个进程的启动/重启把我给折腾坏了。后来制作了一个管理工具,可以直接通过一个客户端去操作进程了。但那...
阅读全文
摘要:luanet最初只是一个网络框架,它简单的封装了一些网络相关接口然后暴露到lua中,让lua可以构建简单的网络应用.随着我的手游服务器的开发,我发现在C语言中要实现一个简洁易用的RPC调用接口并不容易,于是开始考虑将整个服务器框架从主C,辅lua的模式转变成主lua,辅C的模式.网络通讯,异步日志等...
阅读全文
摘要:大挑战是一款手机休闲网络游戏,游戏形式为开房间,每个房间内最大能容纳20名玩家游戏.##服务器结构划分服务器按功能分成3类:1. redis服务器,负责数据的存储2. 主逻辑服务器,战斗等游戏逻辑的处理3. 网关服务器,负责用户的接入和账号验证先期考虑一个服务器组能容纳5W人同时在线,需部署3台服务器,基本配置如下:1. redis服务器, 4核心cpu,64GB内存,3T硬盘,高主频2. 主逻辑服务器, 16核心cpu,64GB内存,1T硬盘,高主频3. 网关服务器,8核心cpu,16GB内存,500GB硬盘,一般即可 服务器逻辑视图 -...
阅读全文
摘要:##使用kendynet构建异步redis访问服务最近开始在kendynet上开发手游服务端,游戏类型是生存挑战类的,要存储的数据结构和类型都比较简单,于是选择了用redis做存储,数据类型使用string基本就足够了。于是在kendynet上写了一个简单的redis异步访问接口.###设计理念1.项目时间紧迫,不打算提供一个大而全的访问接口,只提供一个request接口用以发出redis请求.2.数据在redis中key和value都存储为string,由使用者负责将数据序列化成string,从string反序列化回数据.3.服务支持本地访问和远程访问,服务自动根据请求发起的位置将结果返回给
阅读全文
摘要:网游服务器大多提供了网关服务,用于作为用户和内部服务器组之间通信代理.网关服务一方面将用户消息从客户端分发到正确的内部服务器.另一方面将来自内部服务器的数据包转发给客户端.一般对于网关应用来说,压力最大的就是广播服务。一个用户的在游戏中产生的行为消息可能要广播给周数百个能看得见他的其它玩家.下面用kendynet编写一个简单的网关服务,当然这只是一个示例程序,它只是简单的把来自一连接的数据发往另一个连接.真实网络游戏中的网关服务要复杂得多.首先介绍一下基本设计,static msgdisp_t disp_to_server;static msgdisp_t disp_to_client;s..
阅读全文
摘要:大型网络游戏服务器的逻辑大多采用单线程设计,典型的就是一个线程处理一个区域(地图),跨区域通过跳转实现,这样,不同区域的对象在逻辑上是不发生交互的。这样在一台服务器上开启N个线程就可以处理N个区域。但一个线程处理一个区域毕竟有其瓶颈,如果一个区域内挤进了过多的玩家就会导致为那个区域服务的线程不负重和,表现就是那个区域中的玩家发现操作响应变得不及时.最近一段时间在思考如何能并行的利用多进程多机器为同一片区域服务,这样可以通过多开几个进程提升单区域的承载量。一种方式是类似bigworld全分布式设计,同一区域中的对象可以分布在N个进程/机器中。以一个玩家为例,在一个进程中其是主动对象,所有对这个玩
阅读全文
摘要:首先本文并不打算详细的介绍A*算法,要想大致的了解A*算法可参看下面两篇文章:http://wenku.baidu.com/view/d39faba1284ac850ad02425d.htmlhttp://wenku.baidu.com/view/eaa14f11f18583d049645992.html其次,不用太纠结算法的效率,例如remove_min_pnode函数使用线性探索寻找最小值,实际上可以使用二叉堆或别的方法提高执行效率.本文的目的是提供一个较通用的A*框架,用于解决游戏中的寻路问题.首先看下结构的定义://一个地图块节点struct map_node{};//路径节点stru
阅读全文
摘要:网游服务器的逻辑一般来说比较复杂,而且在很多情况下还使用了多线程,因此使用基于引用计数的智能指针能很大程度的减少内存泄漏和对象失效等问提.但是基于引用计数的指针在很多情况下也会产生另一种情况的泄漏,例如:网游中有一个代表角色的类型character,角色的对象在网游中可以说是最常见的对象之一了,与几乎所有的游戏逻辑都有关系,因此,一个角色对象可能会存在于很多容器,或被其它的对象所持有,为了保证角色对象的有效性,常常会使用基于引用计数的智能指针来存放角色对象。问题由此产生了,例如当一个角色离开地图,我们就需要把所有指向这个角色的智能指针清0,稍有不甚,漏掉一个都会导致资源无法释放,而且要找到具体
阅读全文
摘要:前面的文章介绍了一个基于微线程的调度器框架,并测试了使用微线程实现远程调用的效率。本文将微线程和网络事件框架结合起来,在微线程中处理所有的事件(网络消息,用户定时器事件),这样,在事件回调函数中可以放心的发起远程调用而不用担心阻塞整个线程,只要还有未被阻塞的微线程,就可以切换到那个微线程上去执行,继续等待在事件队列上处理新到的事件.typedef struct coronet{ netservice_t nets; msg_loop_t msgl; sche_t coro_sche; uint32_t last_check...
阅读全文
摘要:续第一篇,前两天对核心存储做了些修改,以前只打算与关系数据库的行与表做对应,value类型只能使array或list,现在把7种基本类型也加入到value支持的类型中,以使得数据库更通用.当然,这都不是本文的核心,本篇主要介绍一个测试前端,以及测试的远程调用协议.先贴出测试前端的服务器代码:#include "netservice.h"#include "msg_loop.h"#include "datasocket.h"#include "SysTime.h"#include "db_protocal.
阅读全文
摘要:为了在各线程之间高效的传递消息,必须设计一种高效率的消息队列,传统的做法是mutex加queue,这种做法在每次执行push和pop时都要加锁,效率相对较低。其次还有使用循环队列,可以做到完全无锁,但只能实现1:1的消息传递。还有一些lock-free队列的实现,但基于其实现的相对复杂性,我不打算使...
阅读全文
摘要:AOI服务作为网络游戏中的中的一个重要组件,用于为地图中的对象根据当前坐标更新关注列表.对于玩家而言,在A关注列表中的对象,其状态发生改变时,需要通知A,这样A才能看到在视野内其它对象的移动,战斗等。对于NPC而且,关注列表中的对象表示在自己一定范围内的对象,可作为AI选择的攻击目标。典型的AOI算法包括格子,十字链表等,关于十字链表法可参考:http://www.codedump.info/?p=388本文介绍一种基于格子的算法.本算法实现的目标是支持可变长视距,根据视距半径,计算出一个包围这个视野圆的最小正方形,然后计算出这个正方形包含在哪些格子中,这些格子中的对象都有可能是可见对象.首先
阅读全文
摘要:将用户级线程添加到我的工具库中,主要的目的就是用于实现同步远程调用接口。这里的同步,是指在调用返回或超时之前,用户级线程的执行路径阻塞在调用接口上,但其底层的线程并不会阻塞,可以继续其它的工作。基于这个结构,我的服务器主线程将运行一个用户级线程调度器,并预先创建一组用户级线程池。当收从网络层收到一个网络消息时,从线程池中取出一个空闲的线程,将消息交给它处理。这个线程在执行的过程中如果发生了阻塞调用,就将运行权交换给调度器,由调度器挑选下一个可用的线程执行。阻塞线程直到超时,或被通知可以解除阻塞才被重新投入到调度器的可运行队列中。下面贴出一个简单的测试代码,用于测试调用的效率。首先是两个远程函数
阅读全文
摘要:网络游戏的数据变动比较频繁,如果每次数据变动都刷往后端数据库,会导致数据库不负重荷。在游戏逻辑和数据库间提供一层缓冲服务,有利于减轻这重压力.首先,网络游戏的数据在数据库中是以表的形式保存的,每个玩家的数据占用其中的一行或几行.以玩家基本属性为例:基本表: chainfo表结构:chaid,chaname,hp,mp,maxhp,maxmp ...为此,内存数据库将建立针对行集和行数据的抽象。为了提高查询的效率,在内存中建立一个大的hash-table,hash-table中只支持两种数据结构:变长的list和定长的array.list用以表示集,array表示数据行.根据建立的逻辑索引,数据
阅读全文
摘要:经过一段时间的设计与完善,我们游戏的AI服务器已经达到了基本的性能要求,目前单个AI进程可同时运行4000+个频繁的AI对象。在前面一篇博客中已经提到过,AI服务器的主逻辑循环是单线程的,这个线程上运行了数千个用户级线程,每个用户级线程运行一个AI对象。AI对象被激活之后就会运行一段lua脚本,以实现AI逻辑.之所以采用用户级线程(windows下是fiber,linux下使用ucontext)的方案,是因为AI的实现使用了大量的远程调用,如果使用同步调用势必导致主线程的阻塞,从而影响AI服务器的性能。采用异步调用又导致了逻辑的过分复杂。而用户级线程正好解决了这些问题,向上提供了一个同步调用的
阅读全文
摘要:最近这段时间在修改服务器AI,准备将AI分配到单独的服务器中做,但为了不至于对原有架构造成太大的影响,攻击的判定,移动的判定仍然在gameserver上处理,AI服务器的角色就是根据状态选择合适的决策并向gameserver发出决策命令。例如:一个简单的AI函数可能像下面这样void onAi(){ //从视野中选择一个目标 target = findtarget(); if(target && target.distence(this) <= 10) { attack(target); }}调用attack的时候,将向gameserver发送一条攻击命令,由gamese
阅读全文
摘要:网络游戏作为一种多人交互游戏,方便玩家在游戏中交流是很重要的。为了防止玩家在游戏中说违禁的东西,所有的聊天系统都需要对聊天信息进行过滤。本文描述了一种简单的基于DFA的算法用于过滤聊天内容中的违禁词,算法的运行复杂度,遍历输入字符串n,最多对每个字符执行一次二分查找lgn,所以最坏情况下也是O(nlgn).因为编写这段代码的时间很短,所以代码写得有点丑陋,但已经足以描述其主要思想了:#include #include #include #include #include "wordfilter.h"struct token{ char code; //字符的编码 ...
阅读全文