|
……(最近有一个朋友,找我来问自己的地图为什么会出Bug~)
……(这是一件很可怕的工作…………但是我还是帮他完成了~其实问题很简单)
……(其实就是物品的等级搞错了还有GameCache在Store之后才初始化的……)
……(为了让大家能自己快速的搞明白自己的Bug所在和以后能避免被某些人骚扰的情况发生,我总结了以前在家)
……(单挑Bug的几条经验…………帮大家能更好、更快地完成自己的作品…………其实我不能说一定会起作用……)
……(接下来我先将Bug分为几类,进行描述并讲一下解决办法……)
……(嘛…………就先这么多……………………………………)
……(想对自己的小手指揉揉…………揉……………………揉……~~…………打字打得有点疼……)
……(1.Bug的分类及解决方法)
……(首先,按照教科书上的说法……Bug分为三类:编译时期的Bug、调试时期的Bug和真正“走出家门”,展现给玩家的Bug。)
……(其中,发现的越晚,他们对作品造成的负面影响就越大,编译时期的Bug几乎除了费上编译员几秒钟…………)
……(其实几分钟比较恰当……以外,也别无其他的负面影响,可以说是最好解决,也是最不用脑子解决的Bug)
……(如果有不知道为什么出错或不知道如何解决这类Bug的情况发生,99%是出在尚未熟练掌握Jass的新手上。)
……(这也很好解决,一般来说,一个编译器就可以帮助新手们解决所有的编译阶段的Bug……)
……(准确来说,这可以称为语法错误。使用WE默认的语法检查器,可能会非常糟糕。因为WE默认的语法检查器不仅本身Bug百出,而且)
……(没有语法高亮,这令人无法接受。对于新手来说,有语法高亮就可以避免function拼成fucntion等等不必要的错误了。)
……(一般来说使用自带语法检查器的非官方WE或者使用JassCraft等等第三方软件可以有效的解决此类Bug…………)
……(如果看了语法检查器的解释仍然不懂的话………………强烈建议你重新看一遍jass教程……)
……(注:使用WE自带的语法检查器,会出现写if不写endif会导致卡机等等RPBug,但是第三方软件都不会。)
……(其实解决这类Bug的方法就是在痛苦中继续写jass代码…………从短到长,从简单到复杂…………当你把自己的第一个jass作品完成时,你会发现其实这类Bug已经被你踩在脚下了…………)
……(调试阶段的Bug是编译员碰到频率最高,难度多种多样的Bug)
……(我将其大致分为2类,一类是如果编译员不解决,这个作品就没有完成或者根本无法执行到下一阶段的严重Bug)
……(或者编译员已经意识到的Bug)
……(一类是隐藏在代码中的极其阴险的Bug,一般测试是无法找出其所在的,这种Bug需要特殊查找)
……(第一类是威胁不大的,除了给予编译员一些心理上的打击和浪费时间以外并无其他负面影响)
……(这类Bug一般会在第一次调试的时候就出现,表现形式多种多样。一般来说是某些功能原本在条件满足时就显现出来,但是没有反应)
……(或者在执行代码时无缘无故的退出等等,而编译员自己发现的我就不说了,就是顺眼看了一下代码发现的…………)
……(引起这种Bug的原因:代码、魔兽本身的某些疏漏或者他的特性——一般我们称其为RPBug。)
……(代码方面是重点,而魔兽产生的Bug虽然触发几率>20%,但如果不是编什么太大的作品以外,基本就可以忽视这些RPBug)
……(代码方面有以下几个经常出现的问题)
……(代码段的实际执行顺序与预想的不一样、代码顺序颠倒、变量名意义不明确导致变量实际传递的值有误)
……(响应event的GetTriggerXXX与使用的不搭配、没有考虑到真实情况等等等等等等等等等等等等)
……(举其中的几例来说:)
……(1.在GameCache初始化之前,就已经运行了有StoreXX的代码,此时GameCache中还是没有任何数据,由于)
……(是比较热门的存储结构,所以由于这个原因引发的种种Bug就不一一数来了)
……(2.脑子进水的时候犯的问题,比如在获得Data的索引之前就清0了什么的…………或者别的什么由于顺序不对会招来麻烦的情况……)
……(3.比较简单的例子)
……(takes unit u1, unit u2 returns nothing)
……(如果你不看它的代码段,你可能猜出u1和u2的含义是什么呢?)
……(这会在代码维护阶段给你带来极大的麻烦。)
……(如果写成)
……(takes unit Attacker, unit Target returns nothing)
……(这就让人一目了然这是干什么的)
……(4.嗯…………这种错是属于那种不太会用转换Trigger为jass代码的人犯的…………我不太会犯这种错误…………所以略过)
……(5.考虑真实情况…………嗯…………这跟魔兽的RPBug基本很相似……很难说的………………看情况有不同的解决办法)
……(魔兽的RPBug解决办法…………不…………重点在于能不能发现这是你的代码问题还是魔兽的问题。)
……(不过根据我的经验,如果有魔兽RPBug出现,一般还会伴随几个代码上的问题)
……(所以不要把出Bug的错先怪在魔兽本身上,先把你的………………)
……(嗯…………好吧………………还是把我的查Bug的一个大致流程跟大家说一下,这样大家才能大约知道什么时候才去找RPBug比较好)
……(第一就是找到与Bug直接相关的代码块,将于这个代码块,怀疑有问题的地方全部查一遍,如果发现了Bug)
……(立即改正,然后保存地图,测试一遍如果还是有Bug的话,退出,继续查找)
……(如果觉得代码方面确定没有问题,此时就可以怀疑是魔兽RPBug)
……(一般来说,怀疑是RPBug的话,首先创建一个新的地图,再将你怀疑的最简RPBug的环境移植到新图中)
……(这里说的最简是将多余和没有直接关系的代码、触发全部删掉,留下的“骨头”部分)
……(如果此时表现出Bug的情况,那么就可以判定为RPBug)
……(如果没有,可能是你移植的不完全或者没有RPBug,再次确定是不是参与测试Bug的内容与原先的作品内容)
……(完全一样,尽量从原先的内容直接copy过来,如果确定完全一样,就再去查查自己的代码问题吧)
……(不过我是从来没有遇到这种情况,基本怀疑是RPBug的就是RPBug…………嗯…………还有就是RPBug带有一定的特征性)
……(嗯…………总是一些比较奇怪的平常想不到的地方出现的,而且RPBug出现的几率随你的作品的难度增加而加大)
……(所以新手只要不是雄心勃勃的新手,一般不用担心这种悲剧的发生~~~)
……(第二类非常BT,是区分一个好的编译员和坏的编译员的重点)
……(好的编译员会尽自己所能的将这类Bug发掘出来,但坏的编译员只会让它走出“家门”)
……(这些Bug我更喜欢称其为“边界”Bug,就是在一些极端情况下出现的Bug。)
……(比较常见的是,使用GUITrigger的同学们使用全局变量存储数据)
……(然后设定的是5秒后读取,但是如果在这5秒内这个触发又被触发了一次,此时这些数据就被覆盖了)
……(这种Bug出现在技能里比较多…………)
……(这种Bug重点就在于能否被查出来,这种Bug并不存在与代码中,而是在代码以外的“空白”区域)
……(必须将这种空白区域填补成有色区域,才能防止这类Bug的产生)
……(一般来说,要想发现这类Bug,都需要在编译员大脑中进行不断地查漏补缺,想象可能会遇到什么)
……(极端情况,玩家出现什么样的BT操作都需要考虑进去,或者出现了百年不遇的情况也要考虑进去。)
……(比如编技能时,像环绕技能,如果被环绕的单位中途被杀死时,那么此时就应该将环绕的马甲单位全部杀死)
……(否则就会出现马甲单位会环绕单位尸体的囧Bug…………)
……(随着系统大小的增大,此类Bug的数量会成指数上升,3000行的系统我是在写出源代码1个月后才解决它的一些边界问题)
……(当然还有我比较偷懒的原因………………)
……(其实新手不太用注意这类极端Bug,因为这种极端Bug触发几率全部都在10%以下,而且解决起来比较费劲)
……(所以新手们就可以先不找极端Bug,但是如果作品超过7、8件还不去考虑这件事情的话,就有点……)
……(对于走出“家门”的Bug,解决方法与解决编译阶段的Bug一样。)
……(嗯…………没什么说的,发现渠道是测试员和玩家)
……(令人感到不愉快的Bug………………)
……(这类Bug如果是放在地图里说,新手做的图有很多是跳出/无法继续游戏,打击人玩游戏的信心)
……(高手做出来的图发现这类Bug看起来更像RPBug,比如Dota里的跳出就毫无预见性)
……(2.冥思苦想出来的一些通用的错误及Bug…………)
……(其实我觉得这才是最有用的地方)
……(各种各样的handle在使用时比如:单位组等,根本没有……嗯…………应该说的是变量指向的是null)
……(对于时间的越界处理,时间冲突等等,使用局部动态timer可以解决…………新手就用timer+gc+returnbug)
……(循环用的timer暂停后,需重新开启。还是说ResumeTimer就没用呢……)
……(GC使用null当key或missionkey会直接跳出游戏)
……(设置单位属性如碰撞体积不考虑时间的叠加问题)
……(马甲单位该隐藏的属性没有隐藏,比如人口等)
……(触发器百年都用不太上的功能,一般贸然看着字面意思就用的话,30%以上几率不管用)
……(让马甲单位释放技能,目标类型考虑不全)
……(触发器内的内容和单位编辑器的内容不符)
……(使用等待——基本所有人都知道这有Bug的,局域网下使用等待会导致掉线什么的)
……(使用一些很复杂的WE或编译器,如NewGen WE,当然这也可能是我个人的错觉,经常会觉得NewGen查不出来语法错误)
……(在真正初始化GC之前没写InitGameCache( FlushGameCache( "XXX.w3v" ) ))
……(SetUnitX和SetUnitY将单位弄到地图外头去了,游戏跳出)
……(以下Bug为我从QQ好友中获取的一些信息)
……(因为偷懒复制如:GetUnitX,GetUnitX而不是GetX,GetY等等)
……(在触发中不小心某些会再次触发Trigger的动作而导致死循环,如单位受到伤害中再次造成伤害而没有暂时关闭触发器)
……(在Condition里删除触发器)
……(function H2I takes integer h returns handle......)
……(function xxx takes nothing returns nothing
local integer a = 1
loop
exitwhen a >= 1
//actions
endloop
endfunction)
……(对循环终止值没有设置好以及没有递增代码)
……(还有强烈建议大家把exitwhen XXX写在set XX = XX + 1之前……)
……(使用WEHelper时,ctrl+c复制触发器后,再复制jass文本,会直接卡WE/创建一个触发器副本,至于没保存的jass文本自然是要不回来了)
……(解决这个Bug的方法是,每次复制完触发器后,就找一个触发器【动作】按ctrl+c,然后就行了……这算Bug吗?)
……(好吧…………就想到这儿………………)
……(如果有人在下面的回帖中补充了上面没有说的错误/Bug,看情况每个错误/Bug+5~10GAB,注意,是每个错误/Bug)
……(如果一次性提供大量错误/Bug,而且大多数是比较通用的,视数量可以额外加威望)
……(这里说的错误/Bug,都是不可利用的对编译员无用/其负面作用的,如ReturnBug自然不算在内)
……(嗯………………实在没什么可写的了。就先到这里吧。)
……(这会为了大家方便看,把字号设成了3,应该可以了)
……(还有这种不说话的表达方式是因为受到心理打击才这样的)
……(如果觉得很碍眼的话,抱歉了各位。)
……(以后我好了就不会用这种方式表达了。)
……(不知道这贴算不算是综合区的第一次活动了…………)
……(揉揉自己的小手指……居然篇幅不长,写了4000字)
……(话说QQ音乐很好方便嘛~~) |
评分
-
查看全部评分
|