[转载]如何快速写游戏服务器业务逻辑

原文来源:https://www.cnblogs.com/rond/p/9226799.html
0. 背景
服务器框架设计者,如果设计的好,考虑到了这几种情况,无论是对于游戏服务器逻辑清晰度,还是对于写业务逻辑的程序员来说,是非常友好的。游戏服务器业务逻辑写多了,一个游戏策划提出的需求归纳到服务器业务逻辑开发上面,也就无非几种情况需要处理。

1. 业务逻辑模板
下面给出代码模板,无论何种语言开发,大体都类似。


-- 数据结构

-- tbPlayer 常见字段
tbPlayer = {
    dSocketId = 0,
    time_rec  = {    -- 常见时间
        birth        = 0,
        login       = 0,
        offline     = 0,
        dailyResets = {[{H,M}] = V, ...}
        weeklyReset = 0,
    },
    sysA = tbAInfo, -- 某系统
    sysB = tbBInfo, -- 某系统
}

-- 业务系统常见字段
tbAInfo = {
    lastTime = 0, -- 上一次刷新时间
}


function born(tbPlayer)
    -- todo 创建
    -- 初始化数据,预处理数据
end

function loadData(tbPlayer)
    -- todo 获取数据
end

function saveData(tbPlayer)
    -- todo 保存数据
    -- 定时?即时
end

function onLogin(tbPlayer)
    -- todo 登录数据预处理
end


function offline(tbPlayer)
    -- todo 下线数据处理
    -- 登出/离线
end

function sendOnLogin(tbPlayer)
    -- todo 登录协议同步
    -- 通常 dailyReset也会默认调用该函数
end

function dailyReset(tbPlayer, tbTime={dHour, dMinute})
    -- todo 每日重置
    -- 0点,也有其他时段的需求
end

2. 数据结构
一般游戏服是将数据直接存在内存里面,可能有些做法是即时保存,有些是定时保存。也有跟传统网站开发类似的,每次业务逻辑需要数据的时候,从数据库取出来,修改之后再存进去。毕竟游戏类型颇多,不同的游戏采用不同的持久化策略是很常见的。以上说的三种,再项目中,笔者都见到过。

关于游戏业务的数据结构的设计,个人经验说下。首先跟时间相关的数据主要有:

birth 建号时间
login 上线时间
offline 下线时间
dailyResets 每日重置时间,存在多个时间点
weeklyReset 每周重置时间

大多数业务逻辑都需要围绕在以上几个时间点来进行。这几个地方处理的好,是能够大幅度提高程序员的开发效率的。
dailyResets和weeklyReset时间点记录都是为了实现每日重置,每周重置的逻辑。
每日重置需要注意下,可能存在多个时间点。凌晨0点是进行每日重置最常见的时间点。但是也有些游戏为了照顾玩家休息,或者为了降低服务器在0点的压力,将部分或全部重置设置为其他时间点的,例如凌晨3点,凌晨5点。
每周重置的情况比较少存在多个的,一般选择周一凌晨0点。

很多游戏都会为了前期的七日留存做很多工作,建号时间也往往在这些地方需要。当然这是个很有用的字段,无论是对于业务逻辑,还是对于游戏数据分析,都需要建号时间。

上线时间是最常见的时间了,一般游戏只在玩家在线的时候处理逻辑。玩家一旦下线,很少再会对玩家数据进行处理。等到玩家再次上线的时候,才会对数据进行处理计算。补回那些玩家不在线,而又需要执行的数据。如每日邮件,每日奖励这种,我们不会真的每天都会将玩家数据从数据库取出来进行处理,而且等到玩家上线的时候再运算那些不在线时期发生的事情。而这些处理,都依赖于玩家的上次上线时间来计算。

下线时间用的没有上线时间那么多,但是也不少。

3. 常见逻辑
3.1. 建号 born
玩家的一切都起源于建号。建号需要进行一些数据初始化,如一些基础装备,基础属性。

3.2. 持久化 loadData和saveData
玩家登录的时候,我们需要把数据从数据库拿出到游戏服务器的内存里面。再数据发生改变之后,又需要存储到数据库进行存档,以防服务器崩溃发生数据丢失。但是每次发生改变如果都进行存储的话,无疑对数据库的压力会很大。为了权衡性能和数据安全,一般需要制定存储策略,如定时存储,或者定时存储加部分数据即时存储。不同的数据重要程度不一样,可以采用不同的存储策略。

3.3. 玩家上线 onLogin和sendOnLogin
为什么需要将上线的操作拆分onLogin和sendOnLogin两个函数。两者的区别是,前者用于进行数据预处理。补回类似刚刚说的,每日邮件啊,每日奖励那些处理。后者是再数据预处理执行完了之后,进行该业务逻辑的协议同步。将数据预处理和协议同步分开是非常有必要和方便的。另外如果某个系统依赖于别的系统,该系统的onLogin操作需要放在别的系统的onLogin之后。

3.4. 玩家下线和断线重连 offline和reconnect
玩家下线往往存在非常规操作,所以下线一般没有协议同步,只有数据处理。下线一般放在与客户端socket断开的地方处理。下线也可以决定是否进行存档。需要特别注意的是,再手游里面,断线是非常容易发生的。所以需要考虑断线重连的情况。是否立即存库其实也跟断线重连的设计相关。如果保留玩家的数据再内存一段时间,如1分钟,30分钟,offline的操作在手游里面就会极大的变少。可以根据下线成本自行考虑把。但是操作是必不可少的,只是执行的数量的问题。

4. 结尾
以上是个人经验总结出来的业务逻辑开发场景。只是单纯将业务逻辑的常见,此处不讨论游戏服务器的框架设计,如网络,日志,协议,持久化等。这些其实才是游戏服务器设计者的大头。

好记性不如烂笔头。


结构设计挺清晰的,就转过来记录下。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Netty是一个基于Java的高性能网络编程框架,它提供了一种简单而强大的方式来构建可扩展的网络应用程序。如果你想编一个Netty游戏服务器,可以按照以下步骤进行: 1. 导入Netty库:首先,在你的项目中导入Netty库。你可以在Maven或Gradle中添加相应的依赖项。 2. 创建服务器引导类:创建一个服务器引导类,用于配置和启动你的Netty服务器。这个类将负责设置服务器的各种参数,如端口号、线程模型等。 3. 配置ChannelHandler:Netty使用ChannelHandler来处理网络事件和数据。你需要编自定义的ChannelHandler来处理游戏逻辑,如接收和处理客户端的请求、发送游戏状态等。 4. 实现业务逻辑:根据你的游戏需求,实现相应的业务逻辑。这可能涉及到游戏规则、玩家管理、战斗逻辑等方面。 5. 处理网络事件:在你的ChannelHandler中,重相应的方法来处理网络事件,如连接建立、数据接收、连接断开等。你可以根据需要进行相应的处理,如解析数据、更新游戏状态等。 6. 启动服务器:在服务器引导类中,调用相应的方法来启动你的Netty服务器。一旦服务器启动,它将开始监听指定的端口,并等待客户端的连接。 7. 测试和调试:在服务器启动后,你可以使用相应的客户端程序来测试和调试你的游戏服务器。确保服务器能够正确地接收和处理客户端的请求,并返回正确的响应。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值