Record your combat log, Detailed demon tail battle video recording system

After several years of development demon tail, and finally the end of June this year, the successful on-line, operational since more than two months, I participated in the development from the beginning of 2017, is responsible for developing the combat system demon tail, all the way to resolve some technical issues, stepped on some pit, feeling there are a lot of points are worth recording and sharing, hoping to borrow a few words, sum up experience in the development of systemic MMORPG combat systems.
This paper describes the combat video systems, video basic combat MMORPG games are all standard systems, it also can become a development and debugging tool, it plays an important role throughout the development phase.

The first is the debugging tool

When some of the project team to develop the combat system, may give priority to development-related functions involved in performance, the new iteration of combat performance, repair Bug, fighting until the entire performance looks fairly complete, and then at a later stage should plan requirements, supplementary combat video recording system. I project is in the development of mid-recording function to join the battle, after full combat development phase, the resulting experience is possible to build on the basis of the framework, front and back stage FBI began fighting the simultaneous development of video systems, the use of video to battle auxiliary systems development, debugging . To the end of the project, the video will play a greater combat usefulness, this time fighting system has been submitted to SVN version control, team everyone can experience the combat system, everyone is more or less playing the role of testers, pROGRAM feedback will combat system performance issues frequently, such as error, stuck, units fraud dead, and so, what feedback there will be, in short, use your imagination. At that time the development will frequently go back and forth in front of the computer each project team members, communication, view the log, trying to figure out the problem, after fighting with the video, we'll make them to video files, playback fighting video in a local environment, to reproduce the scene slowly locate the problem.
How much video can fight assist development and debugging, depending on how to improve the relevant tool chain , here are the demon tail tool chain for the project to build. First look simple fight video frame:


In general, there will be up underlying network layer service network layer, a network layer service demon tail into two, one for ordinary business logic, a dedicated network layer for battle. Instrumented through the interface at the network layer battle, fighting video module will be able to collect all the data of a battle. After the battle, the battle data is automatically saved to the cost of video files, of course, we would also like to provide an interface to manually save the video to the middle of the fight card is dead can save the video. Although there has been fighting data, but also with a fully functional GUI debugging tools in order to improve efficiency, so I developed a Unity-based video player fighting tool.

 

The figure is a fighting video player after a few iterations of shots, in addition to achieve the most basic play videos, view data capabilities, as well as view the device data upload / download videos, generate combat broadcast, differential kits and other building designated battlefield Round Features. I think in the early stages of development, to achieve video playback, viewing data will be able to meet most of the needs of the commissioning , development time and cost only 2-3 days, but it will be in the pre-development stage after 1-2 months or even longer help you locate shorten debugging time, saving more time early (bu) at point (cun) (zai) class (de), or plan to do more to help the demand, it is important that the liberation of mind, no longer struggling to communicate Bug, construction scene, because the scene in the video inside.

This brief description of the use of gestures debugging tools:

  • The development process encountered Bug battle, if not the first time to determine the cause Bug, save the video, and then gradually to analyze problems.
  • Select the error of fighting video, by the time stamp / fast mode to run heavy fighting, and gradually narrow the scope of the problem: To observe the fighting video broadcast to the first few rounds error, resource loading, election trick or stage performances given by log before being given gradually which class positioning which interface problems, guess again and verify a line of code until the problem is solved.
  • If the error is not stuck, can finish the fight, but the feedback planning a skill / Buff behave differently than expected, it is necessary to view key performance data package, backstage pass to see the problem, or the performance of the front desk did not do right.
  • Investigation of the above two types of problems are usually not in one step, the investigation process will continue to track suspicious code Code fight Log, will temporarily modify certain variables, temporarily modify certain code logic, relying on continuous re-running battle to verify.
  • 解决Bug的过程也少不了跟后台的沟通,在这之前,后台重数据轻表现,前台重表现轻数据,导致一种现象就是后台找前台问表现,前台找后台问数据,沟通成本比较高。有了这套工具,前台开发对于这场战斗包括服务器、角色ID、战斗ID、战场ID,协议数据等信息都了如指掌,快速分析出是前台问题就直接修复,是后台问题就告诉对方去修复哪块数据。

这里另外分享1个Bug调试修复的经验。个人认为Bug修复总时间 = 问题沟通时间 + 问题定位时间 + 代码修改时间 + 编译验证时间,像战斗这类大型系统,可能会经历多轮问题定位、代码修改、编译验证才能修好1个Bug。Lua代码做好Hot reload开关,最好做到修改某处代码,重进战斗就能验证最新代码。每次重启游戏至少花费30+秒,1个Bug平均几次重启验证就是几分钟时间,做好Hot reload节省下的时间相当可观。

初期在项目组内推行用录像反馈战斗Bug时,我们让大家把保存下来的录像文件单发给战斗开发来调试,很快发现用户体验并不友好,不是所有人都是开发,大家不清楚录像保存到哪个目录了,找到目录,他们也弄不清楚要发哪个录像给开发。在忍受了一段时间的灵魂三连问后,笔者又加上了录像上传/下载功能。

上面两张图是录像上传/下载流程及录像下载页面。我们将Bug反馈操作简化成游戏内一键反馈,点击按钮就能自动保存录像文件,并将二进制文件数据Base64编码成字符串,利用魔方质管组帮忙搭建的Web服务,通过Http请求将数据上传到Web服务器保存数据库,开发通过Web页面就可以搜索/下载base64字符串格式的录像文件,最后录像播放接口做适配,支持二进制/base64字符串两种格式数据的录像播放,整个环节就打通了。

开发阶段我们自行开发了战斗录像来辅助调试,确实也是到了战斗系统基本稳定后,策划们才前后提了战斗录像的正式需求,先做了一版基于服务器保存的活动录像,又做了一版基于客户端保存的战斗录像大厅。

前后做这两版录像需求,虽然都是观看录像,但其实现大不相同,因此需要谨慎设计整个录像模块,让两套逻辑独立并行,能共用底层功能,并尽量保持外部接口一致性。上图是整个战斗录像的模块划分,可划分为实现战斗录像基础功能的核心模块,及涉及界面UI的两版业务功能模块。BattleReplayManager是核心类,它对外接收录像相关的控制请求,对内调度其他核心模块类,获取/保存/构造数据,控制录像播放流程,并通过给战斗网络层发送协议数据影响战斗表现。

服务器录像

基于服务器保存的活动录像,所有数据都由服务器提供。前台首先发送观看录像请求,接收录像概要数据包,获取战斗波次/回合等信息用于显示和跳回合。收到初始战场包后进入战斗,在每回合表演完后请求下一回合表演数据。正常播放录像时,收到的协议数据跟普通战斗是一样的,但如果在战斗中途跳回合,除了新回合的表演包,还会收到新回合的战场包,用于恢复新回合初的战场单位状态。这个过程跟战斗断线重连恢复战场是同一套逻辑,因此把战斗断线重连的坑填完,实现服务器录像基本没有难点。

客户端录像

相对服务器录像,实现基于客户端保存的录像功能要考虑比较多问题:

  1. 确定录像数据结构,用什么数据结构存储一场战斗的所有协议及相关信息较优?
  2. 保证录制数据完整性。网络抖动、切出游戏再切回来等场景可能会导致少了某回合表演数据怎么办?
  3. 如何实现跳回合。一场正常战斗的协议包,除了初始战场包,每个回合只有表演包,没有战场包,跳回合怎么恢复战场状态?
  4. 录像上传/下载的传输策略。协议收发有64kb限制,录像文件大小超过了怎么办?
  5. 保证用户体验。评估极限情况的录像文件大小,保证流畅的录像观看体验。

模块开发初期就考虑这些问题,就可以避免基础设计出错,后期积重难返的尴尬情况。

1. 录像文件结构

首先是确定录像文件格式,由于妖尾协议基于pb通信,录像文件一开始就没有打算自定义二进制格式,而是直接基于pb定义数据结构,这样有几点好处:

  1. pb传输效率高,而且开发熟悉pb,不像自定义格式还有理解成本,开发效率也高。
  2. 协议与录像文件采用同种格式,比较容易根据查看列表,上传/下载录像等业务去反推最优的录像文件数据结构。让每份录像文件既可以有战斗录像数据,也有关于录像大厅的业务数据,一次设计,解决两个问题。
  3. pb支持数据结构嵌套,列表,能做出录像头、录像数据块设计,上传/下载协议也容易切分录像文件做分块传输。

基于几点考虑,录像文件由BattleReplayFile录像头、BattleReplayFileBlock录像数据块两部分组成。BattleReplayFile的blocks字段用于存放BattleReplayFileBlock列表,BattleReplayFile其他字段是概要信息。这样查看录像列表时,后台只需要返回不带blocks数据的BattleReplayFile列表即可。上传/下载录像时也可以先传录像头、再批量分次传录像数据块。

message BattleReplayFile
{
    optional string name = 1;                       // 录像文件名
    repeated BattleReplayFileBlock blocks = 2;      // 协议文件块
    optional uint32 block_num = 3;                  // 协议文件总块数
    repeated string ext_info_keys = 4;              // 录像额外信息参数Key
    repeated string ext_info_values = 5;            // 录像额外信息参数Value
    ... // id、时间、双方成员、回合、波次等录像概要信息
    ... // 简介、点赞、收藏等录像大厅业务信息
}

message BattleReplayFileBlock
{
    optional uint32 index = 1;                  // 协议块序号
    optional string name = 2;                   // 协议类名
    optional bytes data = 3;                    // 协议数据
    ... //时间、回合等其他信息
}

2. 录像文件校验

网络抖动、切出游戏再切回来等情况导致断线重连,可能导致战斗录像数据损坏,因此保存本地前先做录像文件校验,判断有没有丢关键协议包,包括初始战场包、入包表演包、各回合表演包及退出战场包,保证协议包序,通过校验才保存录像文件,不通过就提示玩家录像数据损坏无法保存。

3. 录像回合跳转

一场战斗录像单靠收到的协议包,可以正常顺序播放整个战斗,却不能跳转回合播放,因为中间跳过了几回合的表演演算,战斗逻辑层无法将战场数据修正成跳转回合的状态。服务器录像可以依靠后台发跳转回合战场包做恢复,客户端录像就要靠前台自己处理,用录像表演包演算出跳转回合的战场状态。

第一直觉是在战斗逻辑层处理跳出的表演包,只是跳过表演,直接做数据演算,但稍加思考会发现有很多问题:战斗逻辑层里,数据与表现基本耦合在一起,毕竟这样的编码实现方式最直观。想抽离表现只演算数据,只能在原有代码里加ifelse分支,重写数据演算逻辑。几十个表演类,新增这么多分支,编码再加调试,必然失去对代码的把控,也破坏了原有系统稳定性。即使哼哧哼哧硬写下来,也会发现只实现了向后跳转回合,没实现向前跳转回合,因为战斗逻辑层实现的是按回合往下演算的逻辑。

跳出这个误区,我们认为战斗录像数据应该要有每个回合的战场包,跳转时供战斗逻辑层重置回合战场,因此后台修改了战斗逻辑,每回合都会发当回合战场包,这些战场包做了特殊标记,只用于录像存储,不会影响战斗逻辑,实现起来很快,但也清楚有明显效率问题。

基本上,战场包都会比表演包大,甚至大很多,如果某个回合技能不太复杂,那表演包数据其实非常小,为了实现跳回合,由后台给每个回合加发战场包,会非常影响战斗的协议数据量,保存录像文件变大,也会增加上传/下载录像时的负担。这么实现不合理的点在于,每回合战场包其实是冗余数据,每回合状态是可以通过初始战场包加表演包推算出来的。为了优化这个问题,前台实现了一个战场包构建器,以初始战场包、回合1~n-1表演包为输入,输出目标回合n的战场包。这样在保存录像时不需要保存回合战场包,录像跳转回合时由构造器动态生成战场包即可。编写调试战场包构建器时,要注意检查前后台的战场包差异,我们会打印战场包数据,通过Beyond Compare查看差异,不断调整代码,直到构建的关键数据一致为止。战场包构建器调试好后,只要后续不新增表演类型,就可以保证构建器可信可用,即使新增表演,代码工作量也很少。

优化完做下简单测试,打了一场40回合的5v5 pvp战斗保存录像,比较两种方案的保存录像文件大小:优化后文件大小是优化前的65%,减少了252KB,由于5v5pvp表演复杂,因此回合表演包数据本身也非常多,换做是一般的战斗,数据优化比率会更高。

4. 录像上传/下载策略

妖尾一次协议收发有64KB大小限制,看前面的数据可知,回合数比较多的战斗录像文件大小肯定会超过64KB,我们既不希望上传/下载录像单次传输的数据量超过64KB,又不希望单次传输数据量太少,导致协议发送次数过多,浪费太多时间在RRT上,因此采用的录像传输策略是,首次传输单独发送录像头,后续传输录像数据块切块传输,保证每次传输的所有BattleReplayFileBlock的data总大小不超过50KB。采用这样的策略,5回合以内的小型战斗基本都能分2次传输完毕,像上面的5v5 pvp大型战斗则需要进行11次传输。这就引出了下个问题思考,大型战斗的录像观看会不会有体验问题。

5.流式传输及录像缓存

战斗录像大厅的设计初衷,是让玩家可以自主分享/观看他们觉得满意的战斗录像,所以我们猜测玩家会比较多的上传/下载/观看大型pvp战斗录像,对于上传而言并不会有什么问题,因为就是一次性操作,但对下载/观看场景就要尽量进行优化,我们不希望玩家每次看录像,都要有感知地等待一会,等上10次网络回包,下载完录像文件才能观看录像,也不希望玩家每次看录像都得重复下载文件,对玩家的手机流量也很不友好。

针对这两点问题,战斗录像参考网络视频的做法,加上了流式传输及录像缓存的特性。

如上图所示,流式传输的目的在于优化玩家观看新录像的体验,不管一个完整的录像有多大,需要多少次传输才能完成,只需要先获得部分头部数据,就能观看录像。前台只需要头2次回包,获取录像概况、初始回合战场包和表演包,就足以表演第1回合的战斗,进入录像战斗后,静默下载其余的录像数据,一般后续的录像数据下载速度远远快于战斗表演速度,这样完全不影响整场战斗的录像观看。假设网络环境极端恶劣,表演完当前回合战斗后,后续录像数据还没返回,BattleReplayManager会每帧轮询等待下个回合表演数据,即使网络断掉了拿不到数据,玩家仍然可以点击按钮退出战斗录像。

录像缓存的目的则在于优化玩家重复观看录像的体验,减少流量消耗。当看过一次录像,下载了完整的录像数据后,前台就会把录像保存到本地缓存起来了,尽管录像头里存储了部分战斗录像大厅的字段,比如点赞、收藏数等,这些字段数据会失效,但战斗数据是不会变的。查看大厅的录像列表时,后台会返回只有录像头BattleReplayFile,没有数据块BattleReplayFileBlock的列表,玩家请求观看时,判断本地缓存有没有该录像缓存,有就不再走原来的下载流程,直接读取缓存文件播放即可。

洋洋洒洒写了一些关于战斗录像的总结,也确实是因为录像系统对战斗开发调试有所帮助,作为一个功能系统,也需要在早期考虑一些问题,做设计和优化,希望本文能对MMORPG或其他类型游戏战斗的设计开发,提供一些借鉴经验。

附上我们的游戏官网[妖精的尾巴:魔导少年],快来玩吧~

Guess you like

Origin www.cnblogs.com/leoin2012/p/11321889.html