骑马与砍杀吧 关注:732,020贴子:14,763,706

抛砖引玉:一步一步接近骑砍2远程武器(弓弩投掷)的物理模型

只看楼主收藏回复

吧里刚对完线,就来发一点有用的东西供各位有兴趣的汽油继续研究。
目标:发现骑砍2远程武器背后的物理模拟算法
砍1维基镇楼


IP属地:新加坡1楼2020-04-23 15:57回复
    先说下这代的武器系统。
    骑砍2设计的时候考虑了mod制作可扩展性,所有的物品数据都放在了xml文件下。
    这里列出几个关键文件:
    spitems.xml - 所有物品的数据
    crafting_templates.xml - 铁匠打造模板数据
    crafting_pieces.xml - 铁匠配件数据
    由于铁匠系统的引入,弓弩/盔甲和可打造武器是不一样的:弓弩数据和盔甲全部存放在spitems.xml内;而可打造武器只会在spitems.xml里存配件列表,最终的数据由所有配件决定(具体是加算还是如何需要进游戏实验)。
    贵族弓在spitems.xml的数据 -

    竞技箭数据 -

    重弩数据 -

    弩箭数据 -

    可打造武器“简易标枪”在spitems.xml内的数据 -

    这里我们看到有四个配件,其中两个guard和pommel尚未实装,矛头和矛杆可在crafting_pieces.xml 找到数据 -


    另外这些打造武器还有一些基础数据储存在crafting_templates.xml 中,以标枪为例 -


    IP属地:新加坡2楼2020-04-23 16:19
    回复
      从楼上的贴图中,我们可以找出一些关键的与远程武器计算相关的数据:
      thrust_damage: 武器伤害,和弓/弩/弹药均挂钩。
      thrust_speed: 字面理解是“推力速度”,仅和弓/弩挂钩,不与弹药挂钩。功能不明,猜测可能和伤害的速度加成有关?
      speed_rate : 专填速度,也是游戏内显示的“速度”。仅和弓/弩挂钩,不与弹药挂钩。轻弩专填速度是61,贵族弓专填速度为94.
      missile_speed: 初始弹道速度。和弓/弩/弹药均挂钩。最终弹道速度猜测是加算,比如“贵族弓+竞技箭”的弹道速度就是90+10=100.
      center_of_mass: 重心位置。已有采访表明武器的伤害在实际计算与重心有关,所以我们有理由推断重心也和弹道计算挂钩。竞技箭的重心是(0,0,-0.1),草原箭的重心是(-0.00,0.05,-0.00)。
      向量的三维对应的是(x,y,z)。z是箭杆方向,我们可以通过观察武器皮套位置default_item_holster_position可以推断。如果把z当成水平方向的话,y应该是竖直方向,否则草原箭的重心偏移有点诡异(难不成会左右射偏?)。故此x是左右方向。因为负值的存在,我们有理由相信这个值是相对于几何中心的偏移量的百分比。
      综上,竞技箭的重心处于箭杆中间偏后10%处,草原箭的重心处于箭杆中间偏上5%处。
      值得一提的是,我在武器铸造数据里并没有看到重心位置的数据,很有可能是根据模板文件里的item_holsters,default_item_holster_position_offset,piece_type_to_scale_holster_with,hidden_piece_types_on_holster等参数计算出来的,这里暂时就先忽略标枪不提了。


      IP属地:新加坡3楼2020-04-23 16:45
      回复
        到这里,我们可以根据楼上的数据图来设计一些实验:
        1. 弓/弩 的弹道模型一样吗? 贵族长弓+竞技箭 和 重弩+弩箭 的速度均为85+10=95。如果两者弹道算法一致,它们平射的落地距离也应该一致。
        2. 伤害速度加成的公式具体是如何?最终伤害可以看成函数f(thrust_damage, thrust_speed, speed),speed可以从游戏伤害面板内看到。
        这里推荐一组弓箭:西方紫杉弓 105 thrust_speed 61 thrust_damage 76 missle speed, 游牧弓 97 thrust speed 63 thrust_damage 77 missle speed, 游牧弓配西方箭 2 thrust_damage 正好能和 西方紫衫弓+竞技箭 达到相同的面板伤害和接近的弹道速度(86 vs 87), 通过游戏内实验我们可以很容易看出thrust_damage的影响。
        通过修改spitems.xml,我们甚至可以将无关变量永远保持在定值,从而在游戏中测出某个变量对伤害面板的影响。想要测试某些数据对弹道的影响的话也可以通过此方法。
        我懒,就只打嘴炮不做实验了


        IP属地:新加坡4楼2020-04-23 17:10
        回复
          那么我们怎么来衡量弹道模型呢? 容我睡一觉明天再来补。


          IP属地:新加坡5楼2020-04-23 17:18
          回复
            感覺還是得圖解才好懂


            IP属地:中国台湾6楼2020-04-23 17:22
            回复
              那弹道算法和伤害结算他应该也写在里面啊 不试试直接找他的算法吗


              IP属地:天津7楼2020-04-23 17:27
              收起回复
                第一个实验开始:
                自定义草原战场射己方步兵后背。装备是游击弓 thrust damage 42 missile speed 65 thrust speed 75 +远程箭 thrust damage 1 missile speed 10,
                贴脸伤害图:




                爆头造成伤害为86,其他部位固定伤害为43,通过这几张图可以得出几个结论:
                1. 爆头系数是原伤害乘2,相当于暴击了。
                2. 不仅头算爆头,脖子也算爆头。
                3. 初始速度仅和武器的missile speed挂钩,和弹药不挂钩。这个结论推翻了之前的猜测,小朋友又有了新的问号:那弹药里的10 missile speed又有什么用呢?
                现在我们离伤害计算公式又近了一步,因为我们知道了F(thrust_damage, thrust_speed, speed)的一个点:F(42, 75, 65)=43


                IP属地:新加坡8楼2020-04-24 01:03
                收起回复
                  把距离拉到16米再做实验:

                  多次实验发现对腿伤害是31,对腹部胸部肩部是39,所以腿部伤害还有个衰减系数!贴脸射腿走一波:

                  基础伤害43时腿部造成伤害为34, 基础伤害为39时腿部造成伤害为31,掏出计算器发现修正系数约为0.8,得出结论:
                  1. 同速度下,腿部造成的伤害是胸腹的0.8倍。
                  现在我们离伤害计算公式又近了一步,因为我们知道了F(thrust_damage, thrust_speed, speed)的又一个点:
                  F(43, 75, 62.49)=39
                  (注意8L错把43打成了42,因为忘记了远程箭的1点穿刺伤害)


                  IP属地:新加坡9楼2020-04-24 01:16
                  回复
                    距离继续拉远:

                    这里首先继续印证了腿部伤害的0.8系数, 其次我们又得到了一个数据点:
                    F(43, 75, 61.18)=38
                    继续拉远:

                    因为精度舍入的问题,我们对两次数据取一下平均: F(43, 75, 58.70) = 34.5
                    之后我还拉远距离做了一些测试,图就不上了,数据补在后面。
                    在thrust_speed和thrust_damage不变时,我们可以把最终伤害看成速度的函数G(speed), 那么我们现在已知的数据点如下:
                    G(65) = 43
                    G(62.49) = 39
                    G(61.18) = 38
                    G(58.70) = 34.5
                    G(57.99) = 34
                    G(57.15) = 33
                    G(53.96) = 29
                    把速度标准化一下(定义1为初始速度65)画个图:

                    因为精度问题(所有伤害均为整数)结果会存在误差,但是整体上我们看得到伤害和速度是呈线性关系的。所以跑个拟合:

                    这里用先验知识稍微修改了一下函数的形式。把系数都取个整,最终得出估算的伤害公式:
                    弓箭最终伤害 = 面板伤害 - 80 * 速度衰退
                    速度衰退 = (初始速度-当前速度) / 初始速度


                    IP属地:新加坡10楼2020-04-24 01:49
                    回复
                      插眼,坐等楼主更新弩的数据,话说投石机的数据楼主找到了吗?


                      IP属地:浙江11楼2020-04-24 01:53
                      收起回复
                        所以说 护甲有多大用


                        IP属地:江苏来自Android客户端12楼2020-04-24 02:00
                        收起回复
                          那thrust_speed到底是个什么鬼呢???
                          这里就得魔改数据了, 我把游击弓的thrust_speed从75改到37, 顺便把missile speed 改到5,然后在自定义中贴脸射箭。

                          (这个图同样验证了之前的伤害公式,即使投射物速度只有5,总伤害依然是面板伤害43。)
                          在这次实验中,体感发现拉弓速度明显变慢,所以thrust_speed其实是拉弓的速度,那speed_rate呢?于是我又做了一次实验,把thrust_speed和missile_speed复原然后把speed_rate从86改成43。
                          这次没感觉到任何变化本来猜测是从箭袋里拿箭装填的速度,但是我感觉不到任何差别。


                          IP属地:新加坡13楼2020-04-24 02:10
                          回复
                            先更到这,总结并修正一下目前的结论:
                            1. 爆头伤害是原伤害乘2,相当于暴击。
                            2. 不仅头算爆头,脖子也算爆头。
                            3. 初始速度仅和武器的missile speed挂钩,和弹药不挂钩。
                            4. 弓箭伤害计算公式为:
                            弓箭最终伤害 = 面板伤害 - 80 * 速度衰退
                            速度衰退 = (初始速度-当前速度) / 初始速度
                            5. thrust_speed决定了拉弓速度,作用非常明显。
                            以下是所有弓的thrust_speed数据:
                            草原弓72,山地猎弓76,猎弓82,长弓70,游击弓75,简易短弓90,草原复合弓95,重型反曲弓84,诺德短弓94,西方长弓84,南方部落弓98,草原战弓100,林地紫杉弓110,林地长弓90,南方硬长弓88,游牧弓97,西方紫杉弓105, 贵族弓135, 贵族长弓110
                            站定射击时,该值决定了弓手的攻击速度。
                            用这个值搭配伤害值来看,其实贵族弓的理论DPS上限比贵族长弓高(两者精度几乎一样)。
                            6. speed_rate作为商店显示的“速度”值,目前作用不明,但是已确认和弓箭伤害公式无关。


                            IP属地:新加坡14楼2020-04-24 02:31
                            回复
                              我又回来了,接下来我们就要研究弹道了!首先是观察空气阻力的影响 -
                              基本思路是把missile_speed调整到一个很小的值,然后观察下落轨迹。
                              我试了一下改成0.5, 然后游戏就崩了(T社的防崩机制做的很差啊),无奈,只能设为1了。


                              IP属地:新加坡15楼2020-04-24 03:06
                              回复