莉莉丝工作室《刀塔传奇》主程张振新:刀塔传奇客户端技术经验分享
主持人:感谢洪涛洪总给我们关于市场、关于用户,还有关于IP方面的分享。IP方面的事情讨论比较热了,但是有一个IP大家都很熟悉,就是刀塔传奇,刀塔传奇是目前国内最火热的游戏,目前在国际市场有取得了一系列的成绩,下面我们就欢迎莉莉丝公司的张振新给我们分享一下关于刀塔传奇的技术经验。
张振新:大家好,我叫张振新,来自莉莉丝科技,我从2009年开始负责PC端游戏的开发,2013年非常荣幸的进入莉莉丝科技,参与了《刀塔传奇》的开发,这是我开发的第一款手游,非常的高兴。下面给大家分享一下《刀塔传奇》客户端技术经验分享。
首先介绍一下《刀塔传奇》的客户端的整合结构,我们在Cocos 2d-x下面封装了一个数据模块,还有一个网络模块,最大的一块就是业务逻辑模块,里面分UI系统、战斗系统和事件系统,大家玩的游戏都是通过这些模块搭建起来。
我们这个模块除了用Cocos 2d-x在C++层面实现,《刀塔传奇》很大程度上都是通过Lua实现的。
Lua是一个小巧的成本语言,它的设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。由于它的设计目的,导致它的四以下几个特点,一个是轻量级;二是可扩展性,Lua本身没有提供太多的库,但是提供了接口的机制;三是非常容易上手,而且简单灵活,这一点对用户有帮助,因为它学习比较方便,操作灵活。Lua带来的好处是开发效率问题,它省去了大量的编译和链接的时间。我们一般运行代码和直接运行程序就可以看到效果。
我们在脚本层面装了一个热加载的模块,主要用于《刀塔传奇》在运行时来重新加载Lua代码,在游戏运行时我们修改的代码可以立即生效,这样省去了关闭和打开应用程序的时间,节省了开发效率。我们在Lua层面做了一个封装,做了各种的场景,我们做热加载的时候会把这些场景删除,用新加载的代码去重新还原这个产品,这样可以做到立马看到代码的效果,减少了UI,提高了效率。
除了开发效率,Lua给我们《刀塔传奇》带来的好处就是版本更新。版本更新是手游上市之后的非常重要的环节,直接影响到手游产品的质量。回忆传统的PC端的时候,手游版本的更新比PC更加的恶劣,因为是通过App Store审核的,而Andriod里面非常的复杂,开始做这个产品的时候就考虑了产品更新的问题,就采取了Lua的问题。
Lua提供了一个叫Lu四doin(音)的方式,能够声称一个程序块,我们程序启动的时候会拉起一个自主串。这个是发生在Lua代码之后的,这样可以用我们代码覆盖版本上的一些代码。我们线上的一些代码,我们叫A,或者它Clind1(音),adfation(音)就变成clind2(音)的问题。重新去版本发布这个流程非常长,用户体验非常差。××(55:00)我们《刀塔传奇》一些数据反馈、bug等方面都是通过这个方式解决。
这种方式也有一个需要注意的地方,就是用lousdui(音)覆盖的函数覆盖到我们群体域里面覆盖的函数,这是一个矛盾的,从我们设计的角度来说,一个模块不应该对外暴露太多,它应该子内部消化,给外部尽可能提供少的接口。这个地方是一个矛盾点,看大家自己怎么理解了。
我们《刀塔传奇》都是Lua脚本,我们更新完一个API之后,只要把它重新起起来,就可以达到它×(音),这个更新机制也是对用户来说体验比较好。这边也有一个注意点,我们更新包不能用于解决更新流程之前的bug,这一点之前我们也出现过这个问题,我们在登陆的时候发现一个登陆的bug,我们就出现了一个更新包,但是登陆的bug在登陆之前,所以这没有什么用处。
有一个大的更新包之后,我们会出一个忖量包给到渠道,这样可以提高玩家的转换率,因为万家要通过好几个大版本的分析,能够提高玩家的体验。
全量包更新,这个是我们最不愿意采用的版本更新方式,有一些时候不得不用。比如《刀塔传奇》刚刚上线的时候跨服蓝牙堆栈功能,这边每个数据跟大家分享一下,每次完整包更新的时候,当日的日活跃大概会少10多万。它的优化方案是制作低清版本,解决包大小的问题,还有一个在游戏内准备继承一个下载器的功能,就是在游戏启动过程当中,跟游戏更新包类似,在游戏启动过程当中完成一个全量包的下载和安装,达到优化更新体验的目的。
优化包也会带来一些问题,比如调试问题,Lua的开发者经常会碰到的,就是开发效率极快,一下子做起来了,但是维护特别的困难,其中很重要的原因就是调试困难,很难找到bug。《刀塔传奇》除了采用Print,我们还开发了Debug函数,它可以添加在代码的任意地方,但是函数会在代码的添加地方输出当前的调用堆栈,并进入调试希望环境,在里面输出当中的一些后变量来完成调试。通过这个方式我们可以解决定位比较复杂的大的问题。
还有一个叫xpcall,这是Lua在安全模式上的一个函数,它接收两个参数,一个是执行函数,一个是错误处理函数,我们在脚本的主循环处使用xpcall额调用执行函数,并使用DEBUG作为错误处理函数,一旦脚本抛出异常,使会进入DEBUG的调试模式。我们还做了一个游戏错误框,类似这样的效果图。我们《刀塔传奇》是在PC下面开发的,等版本发布出来,到Andriod、iOS一跑就各种问题,也不知道出现了什么问题,然后到各种下面去查非常的麻烦。然后我们就在手机发布上面去添加了这么一个框,当有错误的时候它可以以这个形式展现过来,我们在发布内部的测试版方面,我们发这么一个框,可以很容易的定位到手机版本的问题,他们提交的bug单可以让我们找到错误的信息,这对bug来说是很方便的事情。
除了调试之外,还有一个问题就是shapshot的问题,它可以对当前的Lua State做一个完整的快找,并记录对象的引用关系,我们可以在不同的手机端对Lua进行两次快找,通过两次的对比可以的出新增加的内粗处于何处。
它在第一行做了一个快照,分配了一个Test1,然后他又做了一个S2,这对我们定位的内部发生了斜路都有很好的解决。特别是对Lua问题发生的不太容易发现的,通过添加xpcall的方式可以解决。
把性能瓶颈相关的代码用C或C++实现,《刀塔传奇》没有遵循C或者C++,《刀塔传奇》主要是做Lua。他原来采用的方式是通过设置产品区域的方式来隐藏,不在区域下的action(音),我们考虑通过这种添加,预裁剪的方式,把不可见的IP做一个×(音),第一个我们在Lua的层面做,把所有不可见的设为可见的。但是这样增加了cpu的负担,主要的原因是采用了大量调动Lua的原因,后来直接改在C++的层面上实现裁剪。
Lua还有三个变量,大家知道local、upvalue 、global。我们应该在Lua里面,尽可能的多的使用local的变量,在某些地方可以用upvalue,其次没有办法了再使用global。
还有一点对table的使用,要预先分配大小,减少rehash。当我们把新的见解给table额的时候,若数组合哈希表已经满了,更会触发一个再哈希,再哈希的代价是高昂的,首先会在内存中分配一个新的长度的数组,然后将所有记录再全部哈希一遍,将原来的记录转移到新数组中。
Lua的创新跟其他的脚本实现方式不太一样,它采用了内例化的实现方式,所有的字符串在Lua中都只储存一份拷贝,并且都以引用的方式保存。这边可以考虑一下,Lua保存的方式可以用table保存。
除了刚才讲到的问题,还有一些问题,因为我们用了基本的全都是Lua代码,然后把其他的代码都全部导出。之前我们都有过触控的,我聊过,它提出一个方案,他们想把亿引用技术的方式在C++里面保存。《刀塔传奇》是规避了这种,我们会在Lua层面上,一般这种事情会发生在服务器的协议下发的界面的情况下。我们把所有的服装都放在Store下面的,只有我这个作用率生效的时候才可以采用。一旦我这个做出,它们都会结束掉,这样就保证了没有机会出现这追访问不到的情况。
我的分享结束,谢谢大家!
网易《迷你西游》主程杨乔杰:《迷你西游》对Cocos 2d-x 3D化的探索
主持人:感谢张振新把关于《刀塔传奇》里面的东西给大家分享,Lua语言相对来说用得不错,效率也还可以,当然张振新给我们分享了一些需要注意的地方。下面有请杨乔杰给我们分享一下《迷你西游》对Cocos2d-X3D化的探索。
杨乔杰:这次给大家分享的主题是,《迷你西游》对Cocos 2d-X3D化的探索。首先,我们在做Cocos2d-X3D化要讨论一个问题,为什么要3D化。增强这个产品的表现力,这是我们开发这个东西的唯一原因。我们所有的开发都是服务于产品的,满足我们的以产品为核心。不是我们的技术多牛逼才做这样的事,而是认为做这样的事之后,我们可以大大增强这个游戏的画面表现力,只要是对产品好的,我们都挥想方设法用一切牛逼技术来实现它。
实现它的方法通常有两种。plandA(音)就是一种成果。站在巨人肩上,使我们有更多的可能。PlandD(音)就是我们做的。
从我们的技术目标来说,最小化引擎修改,Cocos引擎并不是我们写的,我们不可能一朝一夕就对它了解了,所以我们每次修改之前都会做风险的评估,如果做颠覆性的修改会使产品不稳定,并且我们做测试,让它稳定。我们把风险控制作一定范围之内。还有一个好处,可以方便引擎的升级和更新。因为我们并不是孤军奋战,而是我们可以来到cocos引擎开发团队的风险果实。
成熟的工具链的支持。这一点对我们开发团队非常的重要,没有成熟的工具支持,会使产品开发成本和沟通成本急剧提高,直接影响产品的迭代速度,严重的话会影响产品品质提升的瓶颈。
简单使用,这也是从成本层面考虑的,简单化的使用可以使逻辑开发更加的高效,减少bug出现的概率。
我们从三个方面讲我们对cocos设计。
关于作者对cocos设计的详细讲解,请观看本次大会的演讲视频实录。
DeNA《变形金刚》主程彭承:变形金刚和Cocos 2d-JS的邂逅
主持人:谢谢杨乔杰的分享。今年变形金刚4在国内卖得非常好,然后DeNA也做了一个游戏,我们下面请DeNA《变形金刚》主程彭承给我们做他们的分享。谢谢!
彭承:大家好,我是彭承,来自于DeNA,今天跟大家分享的主题是变形金刚和Cocos2d-JS的邂逅。
我们讲几部分,我们为什么用cocos2d-js,第二选择cocos 2d-js之后的工作流是怎样的,第三开发过程中遇到的坑以及解决方案。
变形金刚的项目背景,我们DeNA到中国之后有一些水土不服的状况,2013天随着国内的MT、大掌门等一些商业化的游戏出现,我们公司也逐渐把我们的工作重点转移到自研的项目上来,我们项目组打造的第一款游戏是基于cocos 2d-js引擎开发的。
我们为什么选择cocos 2d-js,它是跨平台的开发引擎,大家知道在发布的时候它支持iOS、Andriod等一些平台,大家如果选择cocos 2d-js引擎,可以直接集成,它研发的时候也是跨平台,支持Windows、Mac,还支持linux。
Cocos 2d-js支持非常多的开发工具,所以整个工具链支持的特别好,大家不需要用特别多的时间学习一些其他的工具。
还有它是完全开源的、可扩展的,这一点非常重要。我们有很多亟待学习的功能,时间非常紧,我们采用开源的工具可以有很多的支持。
强大的社区支持,我们开发过程当中遇到很多的问题,我们底层人员到cocos论坛当中收集了一些资源,对我们的支持非常好。
为什么选择Script,简单来说入门门槛低、开发效率高,可以热更新。刚才两位的游戏都是用Lua来编写的,所以脚本有它天生的就是。我们为什么选择JavaScript。我们首先有群众基础,JavaScript在国外比较流行,整个的JavaScript社区非常的活跃,不仅后端,就是做Web的人以前用过JavaScript,我们客户端有很多也用过JavaScript,学起来非常的简单。对于我们项目来说,因为我们以前项目成员有一个Services端的都有JavaScript基础,所以我们人组员比较的成熟。
大部分国内厂商要经过一年、两年的时间才可以把手机开发引擎从其它引擎转到cocos2d-x。还有一点就是它可以调试,其实Lua也是可以调试的。
我们选用了cocos2d-js的时候,我们的工作流程怎么样?首先我们策划团队用了一个操作稳当,有我们的客户端、美术,之前我们刚才说的我们是采用Vodle-JS来开发,首先我们编写服务的模型。客户端这个时候同时用cocos2d-js来编写客户端的逻辑层。在美术我们是Cocos Studio,它做UI布局只需要通过美术成员拖出去之后,一行代码就可以了。还有一个叫粒子,它采用Prrticle Desiner上,这样的话,包括动画,包括动画都可以统一使用×(39:14),它提供JS-comuter(音)。最新的Cocos Studio也可以支持flash的导出。
通过这个图可以看到,客户端和服务端,是通过JavaScript结合在一起的,完全用的一段代码,客户端和美术是通过cocos 2d,包括cocos2d-js和Cocos Studio结合在一起的,其它几层的工作只需要一个C++的程序去修改一些需要修改的引擎代码就可以了
开发的前期,我们客户端的程序员也帮助服务端进行开发,服务端只需要把底层的模块写好,我们客户端的程序员利用他们的经验写一些简单的服务方面的程序,可以极大的提高我们的供销。
资源的热更新,在开发者大会上讲过好几遍了,我今天一下我们不同的地方。为什么采用热更新,测试方便、发布方便、多语言支持方便,非常容易进行国际化。
我们的版本合作是什么呢?我也讲讲和其他的差别。
第一,我们可以法版本更新,很多的游戏做热更新的时候,都是1.0更新到1.1,然后1.1到1.2。如果我们下载的更新包是1.0的话,它可以直接跨越到1.1、1.2,直接到1.5,这样可以节省很多的流量。
关于作者对cocos设计的详细讲解,请观看本次大会的演讲视频实录。