Lost Gate

这个世界实在太无趣了… 既然如此,那就再创造一个世界如何?

战斗系统的构成笔记(上):战斗演出系统构成、打击感的营造


魔力的战斗是典型的日式纯回合制,整个战斗流程非常简洁明了。

双方在思考周期内下达所有成员的指令,然后由服务端运算之后,发出一个回合内所有的战斗结果,客户端收到后进行演出,之后进入下一个思考周期。

 

 

虽然大框架简单,但要复刻魔力这套战斗系统,依然是不小的工作量,因为单机化以后,原本服务端要做的内容也将迁移到客户端,这部分工作量有点超出了我的想象。

事实上,任务系统,地图事件等内容之前也是由服务端运算,现在都要迁移过来。所以虽然单机化少了网络通信相关的开发量,但其他开发量却等同于制作客户端+服务端…

最终,花费了大约3个月的业余时间完成了整套战斗系统,用原作中经典的BOSS战测试了下,与印象中的情景很符合。

 

整个开发过程大体分为: 客户端演出系统、战斗配置解析、战斗运算(原服务端),本篇先说战斗演出系统

 

客户端演出部分,是一切的基础,先做表演效果,可以助于构建游戏框架。

 

从技术角度来说,没有什么特别的难点,整个流程可以概括为

 

  • 战斗入场效果

魔力的入场效果是比较奇特的扭曲效果,需要使用shader实现,对uv采样偏移,控制进度,即可达到效果。

 

  • 战斗开始,根据站位排布各个角色,设定属性和状态显示

 

这一步很简单,只要角色的view包装得足够好,基本只是做下显示流程。不过,问题在于魔力的站位并非是顺序的,拿我方队形做例子的话,我定义的队形是

98765

43210

这样方便计算站位,然而魔力的站位却是

86579

31024

这是为啥呢? 因为这样根据index排列下,发现始终是围绕中心去排列的,这样队伍很整齐。比如只有3人, 那站位就是    _102_  ,而不是  __210  ,很不美观。

所以需要一对字典映射魔力和游戏内坐标,直接贴代码:
private static List<int> seatMapHero = new List<int> { 3, 1, 0, 2, 4, 8, 6, 5, 7, 9 };
private static List<int> seatMapEnemy = new List<int> { 8, 6, 5, 7, 9, 3, 1, 0, 2, 4 };

 

 

  • 模拟出战斗演出的回包,客户端收到后解析

魔力的战斗有许多特殊的设定,例如,角色的反击、必杀、闪躲、护卫、制御巫术等需要概率的特殊情况。

如果通过硬编码进行测试,将非常没有效率,而且后期调试技能细节也非常困难。

我选择做一套演出回放系统,也就是录像系统,除了可以调试战斗外,还可以做一些战斗场景下的固定剧情或者新手引导。

载入使用XML,修改起来比较简单。

 

  • 根据行动不同,导向不同的演出解释器。这一步的特殊难点:打击感营造

这一步在技术上无非就是归纳各类技能特性,建立好继承关系。比如将物理攻击统一为一套基本处理流程,物理技能继承后进行细节修改。

在技术上无难点,但细节还原上需要对魔力有足够了解,尤其是打击感相关。

打击感还原度好不好,是“魔力味”营造的关键。 魔力的打击感在同类游戏中很优秀,秒杀梦幻西游这类国产游戏。(虽然梦幻更赚钱)

魔力的打击感主要从几个点去还原:  基于关键帧的打击判定、僵直、逆僵直、音效、屏幕效果、子弹时间

在原始资源中,AnimateInfo 中记录了动画每帧的间隔、音效、事件,其中事件为 1 代表最终判定, 0 则是中间攻击判定。

角色执行动画时,从身体动画信息中获取这些,解析,即可还原出大部分效果。

子弹时间也是魔力的特色,击杀时慢动作,通过time的scale以及对所有自定义的延迟系统做缩放,就可以达到效果。

 

  • 顺序演出行动包,直到全部完成。这里还有个特殊的处理:乱舞系统

 

乱舞系统是指,当连续的几个行动,参演角色互不干扰的时候,客户端进行同时表演,增强演出效果,并降低演出总时长。

举个极端例子,我方10个角色,分别选中对面不同的10个目标,没有乱舞系统时,需要一个个上去砍,而有了乱舞系统,10个人会几乎同时冲上去砍。

实现原理不算复杂,将每个行动包中提取出参演角色,放入一个字典,下个行动包检验冲突,不冲突就继续,直到冲突或者队列清空。

 

当以上的流程运转起来后,就是漫长的技能解释器编写,魔力约100个技能(不过有不少形式重复),还是消耗了不少时间。

还原完魔力的技能后,仍然还有许多技能要做:

LostGate既然要对魔力复刻以及二次开发,就需要原创技能。 初步的想法是针对每个主要角色,制作专属技能,这样可以针对动作去定制。

 

MapEventEditor(地图事件编辑器)基本完成


所谓地图事件编辑器,是指标准单机RPG所需要的事件触发编辑以及运行时解析

因为魔力原本是一款网络游戏,所有的剧情基本靠对话来推动,而对话由服务器来驱动,其功能较为单一

要实现自由编辑剧情,就得废弃掉魔力的地图配置,只保留地图的表现数据,在其之上叠加上新的事件驱动机制和脚本。

 

那么这个编辑器即是做这件事的,它读取魔力的地图数据,在之上进行编辑NPC,传送,坐标区域事件等内容,与之前的剧本系统对接,来达到驱动剧情推进的目的

当然,编辑地图事件始终是一个很费时间的事情,所以仍保留了导入魔力数据的功能(可以导入NPC,传送信息),这样仅作修改即可。

 

还是以熟悉的坎那贝拉村为例,这是导入的传送点数据。 (有人问我,为啥老是坎村,因为这里漂亮啊)

 

导入的NPC数据,并新增了几个NPC(村长,阿紫),并附加了剧情脚本,这种图形化的剧情配置,还是很容易操作的。

 

下面做个小剧场来验证,随意挑选了一个地图,放置一个NPC,通过对话传送队伍到神秘地图。

 

地图里设置了几个秘之NPC。。

 

测试与剧情脚本的对接,没问题。

 

秘之地图的编辑器界面

 

 

以上。

 

预计下周开始对两大编辑器进行bug修复等工作, 再往后就是战斗系统二次开发了,创造各种全新技能。

剩余的内容大概是这样

  • 战斗系统针对手机特性,二次开发,AI完善,技能补全和新增
  • 使用时间轴串联剧情测试
  • 开始正式的游戏剧情编写。

 

魔力宝贝 手机版(腾讯代理),快上线了


一直秘密的参与, 也该介绍下了。不同于LostGate,这是个真正意义上的商业大作。

我负责战斗部分的开发,引擎基于LostGate逆向移植,整体战斗表现非常接近魔力宝贝原版,希望大家喜欢。至于玩法太过接近梦幻,我的看法是,这样更适应新一代玩家的游玩习惯(虽然我个人也喜欢老魔力的自由性)

 

 

此项目与LostGate不冲突, LostGate会继续下去的。

ps。说起来这原画真的很棒,个人的人设瞬间相形见拙 ……

 

 

脚本编辑器开发中……


选用json作为脚本格式的初衷就是可以摆脱编辑器(或者说可以省掉一个开发量),然而手写脚本难免有错,经历了无数次格式错误后,终于决定还是做一个编辑器。

虽说是给LostGate用的,但实际上可以用于所有流式脚本的项目,界面如下,标准的程序员式界面(笑)

目前还差输出和一些便捷操作(批量copy,排序等)

 

按理说,这并不是一个多么复杂的工作,为何进度如此慢呢?因为…  公司项目到了关键时刻啊,实在分身乏术。毕竟理想还是得需要面包支撑啊(笑)

LostGate8月份总结


最近公司项目比较忙, 没太多时间。 不过也是有几个令人兴奋的点,首先是确定了剧本演绎规则。采用 章节+ 主线、支线的方式进行, 有点类似于baldr 系列,通过在任务中的关键选项来推动剧情到不同的分支。

其次,基本敲定了event的触发机制以及相关的实现。 大体上,event分为 tile触发、对话触发、章节变化触发、event中触发等。

另外,保存and读取有了正式的GUI以及功能,可以在手机上实现save and load了。

经验获取以及物品掉落也做了解析, 这样离一个正式的游戏又近了一步,可喜可贺啊 (笑

 

2017年中,进度Mark


完成了GUI框架, 使用魔力的素材做了点修改。 个人对最后的动画效果还有体验比较满意

之后,GUI里的队伍管理,换装,物品管理,交易等内容花费了挺长的时间,毕竟这是一些相当无聊的内容啊(笑)

直到上周,GUI里的主要几个功能完成了,马上开始了队伍的图形化。

这点倒没有花费多少时间,2天就搞定了。

接下来,继续补充一下宠物的管理和队形管理,大概需要1个月左右?

最后,就到激动人心的,剧本推进系统了,希望今年内可以发布序章体验版吧

自己上下班的路上,脑补了无数次序章的细节

不过,毕竟是业余项目。

虽然进度缓慢,但总有那么一天的,我相信。

LostGate笔记:存档完成


采用Json存储,这是以后成长体系的基础。

接下来开始考虑队伍系统。

LostGate笔记:针对移动平台进行资源整合与性能优化


先看看成果

先说资源方面

之前进入游戏需要载入的内容如下

 

初始载入:

 

arr.Add(“bin/GraphicInfo_20.bin”);  //图像信息文件集合
arr.Add(“bin/AnimeInfo_3.bin”); //动画索引文件
arr.Add(“bin/Anime_3.bin”); //动画信息文件
arr.Add(“bin/auto.dat”);  //小地图调色板
arr.Add(“bin/pal/palet_05.cgp”); //大地图调色板

if (loadExConfig)
{
arr.Add(“bin/GraphicInfoEx_4.bin”);  //3.0版本的图像信息文件
arr.Add(“bin/AnimeInfoEx_1.bin”); //3.0版本动画索引
arr.Add(“bin/AnimeEx_1.bin”); //3.0版本动画信息
}
t = res.content.assetBundle.LoadAsset<TextAsset>(“msg”);  //对话配置
t = res.content.assetBundle.LoadAsset<TextAsset>(“warp”);  //地图的传送点配置
t = res.content.assetBundle.LoadAsset<TextAsset>(“result”);  //地图index
t = res.content.assetBundle.LoadAsset<TextAsset>(“tech”);  //技能配置
t = res.content.assetBundle.LoadAsset<TextAsset>(“encount”); //遇敌范围与概率
t = res.content.assetBundle.LoadAsset<TextAsset>(“enemybase”); //怪物模版
t = res.content.assetBundle.LoadAsset<TextAsset>(“enemy”); //怪物表
t = res.content.assetBundle.LoadAsset<TextAsset>(“group”); //怪物阵
t = res.content.assetBundle.LoadAsset<TextAsset>(“enemyai”); //怪物AI
t = res.content.assetBundle.LoadAsset<TextAsset>(“enemytalk”);  //怪物对话

xxxx.dat   地图逻辑文件

 

Read More »

LostGate笔记:RPG固定剧情的实现


作为一款单机RPG,固定剧情是不可缺少的部分

顾名思义,采用脚本驱动游戏自动演示一段剧情。

简单的例如一段闲聊,复杂的如一段剧情杀场景(笑),都是需要编辑并演算出来的。

一个游戏至少有几十,甚至上百个固定剧情存在,要达到这个功能,总结下来有几个步骤

 

Read More »

LostGate 2014~2017年回顾


2014年

转型Unity后,一直想找个题材练手,于是,再一次…

最初,是纯粹的移植,确切说是翻译。 仅仅是把之前的成果,从As3版本(flash)翻译为C#(Unity)

按理说是个枯燥的活,不过Unity的IDE意外的有趣,简直是个RPGMaker的高级版

大概用了一个月左右的闲暇时间,把除了战斗的部分都翻译完毕

之后为了回味以及重新熟悉下游戏,打算回怀旧服玩一段时间

然而我忘记了这游戏相当杀时间,一个月后我才60级,还个重装,技能非常难练

如果要继续下去,估计1年才能到头吧。

于是我果断买了一个110级剑士帐号(ID 狂妄之灾),好好的体验了一番。

为了快速游戏,金币装备大部分也是RMB交易。 于是我的游戏乐趣很快衰减到无味。

 

2015年

断断续续完成了战斗部分,并发到了贴吧,得到了广泛关注。

年底的时候放出了体验版,该版本没有游戏内容,并存在内存占用巨大的问题。

 

2016年

停工了近一年,重新拾起来,开始构思玩法,以及优化方案。

年底时,开始动手优化资源部分,这其实相当困难。

2017年

持续了3个月左右,完成了资源的整合优化,抛弃了魔力原始的素材,而使用专为手机优化的素材

优化方案之后会单独记录。

其结果是,在低端手机上也能很顺畅的跑起来。

 

不过从玩法层面,仍然是原地踏步,这就是之后的工作了。

 

Email
57085445@qq.com

讨论群
LostGate同人游戏 184379459
魔力宝贝官方手游群 540221885