阿荣社区采集员3 发表于 2024-7-12 20:40:46

【教程贴】从0开始修复神迹字体

鸽到了四月份,还是准备把之前说的nut终伤详解和神迹字体详解帖子写完。
吧里现在有一个非常优秀的楼主正在持续更新神迹的版本优化,参与一起优化的吧友也非常多,修复了很多细节方面的内容,那我之前的“从0开始优化版本”的帖子就不再更新了吧,有兴趣的可以直接出门右转他的帖子。
我还是做好自己的部分,把nut相关的问题修一修,讲一讲。
这次就以修复神迹字体的典型问题:异常伤害卡退,为例子带大家读懂神迹字体的工作流程并修复高频bug。
最终的修复方法非常简单(并不完美),不想看流程解读就直接跳到最后。


原文地址:https://tieba.baidu.com/p/7790985215 -----EoLux小光
由阿荣社区 https://bbs.vul7.com/    转录

阿荣社区采集员2 发表于 2024-7-12 20:41:20



阿荣社区采集员1 发表于 2024-7-12 20:42:12

顶!


阿荣社区采集员3 发表于 2024-7-12 20:43:09

既然是从0开始分析,那么就要先搞明白几个问题,这个字体相关的nut功能在哪定义的?怎么调用的?搞明白这两个问题,基本也就搞明白整个工作流程了。
首先找到最直观的三个nut文件sqr/ui/damagefont/下的cache,function,header
根据名字判断类别并稍微浏览一下,function中是字体相关的函数功能实现,header定义了部分常量,cache声明了一个DamageFont的类。
搞清楚门路之后就要决定从哪里入手,既然我们是要修复异常状态导致的高频卡退bug,自然是从异常相关的部分去入手。
直接在function.nut中搜索一下异常状态的关键字“active”


首先是两个create函数,分别创建异常伤害和异常附加伤害的ani
也就是下图中的紫色和蓝色字体


顺着这个函数,遍历一下sqr看看什么地方调用了这个函数,也就能找到创建ani的地方
(贪图方便我这里随手拿python写了个遍历)


发现除了function.nut中的定义,还在cache.nut中进行了调用(preload是预读,不管它)

阿荣社区采集员1 发表于 2024-7-12 20:43:14

“吧里现在有一个非常优秀的楼主正在持续更新神迹的版本优化”
劳烦您私发我一下帖子的链接吗?
感谢。
想玩玩。
再次感谢。

阿荣社区采集员3 发表于 2024-7-12 20:43:53

转到cache.nut中定位调用createActiveNumberAni的函数


写两句注释方便大家阅读
可以看到,这个initDamageActiveCache函数直接把0-9的数字ani先给他全部创建出来,设置完颜色和大小之后存到DamgeFont这个自定义的类里边,最后统一存到DamageActiveCache这个总容器里边去,以供之后直接绘制。
(没有面对对象编程经验的小伙伴可以不用深入去看DamgeFont这个类是如何定义的)
这就好办了,我们已经知道新建的数字ani都存到这个容器里边去了,那么只需要继续去找是什么函数动了这个DamageActiveCache容器,就能找到绘制的部分。
同样的,拿python遍历一下,找找什么地方用到了DamageActiveCache


好家伙,又回到了function.nut

阿荣社区采集员3 发表于 2024-7-12 20:44:24

虽然看不懂但是大晚上的更贴辛苦了

阿荣社区采集员1 发表于 2024-7-12 20:44:42

大佬,神迹端进副本读条和出副本再次挑战或者选择其他副本的时候闪退或者卡死是什么原因导致的呢,麻烦你了!

阿荣社区采集员3 发表于 2024-7-12 20:44:55

回到function.nut中看看是什么函数用到了这个cache
一共有两个函数用到了,第一个是applyActiveDamage


稍微阅读一下,可以知道这是一个计算异常伤害加成的函数
读取169号技能的静态数据然后加成到异常伤害中,好像跟我们要修的东西关系不大。
继续看第二个函数drawActiveDamageNumber,看名字,异常伤害字体绘制


其实里面有很多心思,感兴趣的可以自己去细读一下,需要结合cache.nut中的自定义类去解读
找了半天,还是没找到问题所在啊,楼主你是不是在逗我?
嘿嘿,就当学习了嘛,没有坏处!
后来去看了一下header.nut中的一些常量名,然后顺着找到了真正的问题所在(运气也是实力的一部分!)

阿荣社区采集员3 发表于 2024-7-12 20:45:22

然后呢

阿荣社区采集员3 发表于 2024-7-12 20:45:38

看一看header.nut中的常量定义,发现有一个很显眼的名字


启动异常伤害?抓紧遍历一下看看是啥用处


豁然开朗,绘制相关的函数应该是正常运作的,实际的问题可能出在控制怪物的ap里边
如此,慢慢挖掘到真正的问题所在是非常有成就感的,不知道大家是不是也这样觉得

抓紧去看看ap_minster.nut中的相关函数


芜湖,找到问题所在了,原来是这里在控制异常伤害的最终结果
往下看,观察一下他的几个条件从句


非常清晰的可以看到,当存在攻击者并且造成感电的时候,会调用applyActiveDamage函数,
这个函数很巧妙的设计了两个功能,首先调用之后会根据参数绘制异常伤害字体,然后返回的结果是之前讲到的,计算了各种加成之后的异常伤害,然后再与原先要设置的hp做计算,就能得到最终要设置的hp。
是不是都串起来了?现在应该都能明白神迹字体的工作原理了吧?
说了这么多,问题到底出在哪里?怎么修复?
可以发现,他将感电和中毒出血的判断分开来写了
我们上游戏实验一下,发现通常都是感电的前提下,再中毒或者出血就会导致高频的伤害然后炸掉
看了这段代码之后就大概就能明白是什么问题了
感电之后再中其他的异常状态,就会无限进入第一个判断分支,然后无限计算加成后的异常状态伤害,并且没有计时器约束,伤害能跳多块就跳多块,左脚踩右脚,导致最终爆炸
该怎么解决呢?非常简单,上述两端代码全部注释掉,然后重新写一个自己的判断函数


333代表我想让他间隔多长时间跳一次异常数字,333也就大概是一秒三跳,帧数也算稳定,如果你电脑一般,设置成1000ms也就是一秒一跳也没问题,当然3090ti直接设置成100就行
至此,我们修复了异常伤害的高频卡退bug,当然,细心的小伙伴也能发现,这个是一个“不完美”的办法
它违背了作者的初衷,因为这里并没有再计算加成后的异常伤害,而是改为了不吃加成的异常伤害
如果追求完美的小伙伴,想让异常状态也吃到属性加成,那建议根据上述函数稍微改改就行

阿荣社区采集员1 发表于 2024-7-12 20:45:46

不睡觉蹲大佬!这个bug困扰我很久了,自己技术太差修不好

阿荣社区采集员3 发表于 2024-7-12 20:46:21

感谢大佬带我

阿荣社区采集员1 发表于 2024-7-12 20:46:45

虽然小白什么都不懂,但是为楼主精神点赞

阿荣社区采集员3 发表于 2024-7-12 20:47:16



页: [1]
查看完整版本: 【教程贴】从0开始修复神迹字体