返回列表 发帖

揭开ASPD的面纱(修改版)

本文by snowloveyz 转载麻烦注明作者出处

再未有其他游戏像RO一样用aspd这个参数表述人物的攻击速度
最近终于在日本各网站凑齐了aspd的公式 可以发表一篇全面的文章了

先贴公式
ASPD = 200 - {[(250 - AGI - DEX/4)/250] x (200 - BaseASPD)}

APS(attack per second每秒攻击次数)=50/(200-ASPD)

ASPD'(使用加速技能如加速药后)=ASPD+(200-ASPD)*t%(加速因子如波水为15%)

第三个是凭记忆的 若有不对敬请谅解

一部分日服网站认为 aspd保留至小数点后一位 且RO一次最短攻击时间需要0.02秒
另外 目前官服最高aspd锁定为190

很明显的看出 攻击威力是跟APS直接相关的 而且是线性关系
我们改写一下公式 为什么改写看完就明白了

APS=1/[(200-ASPD)*0.02]

在此 我们改写全部公式 令ADT(attack delay time)=200-ASPD
因为AGI和DEX/4的作用相当 且不管配点可能与否
一个agi100 dex100的人 就当作是agi125来计算是相同的
令AGI'(等效AGI)=AGI+DEX/4

全部公式变成

ADT=(1-AGI'*1/250)* BaseADT  (1)

APS=1/(ADT*0.02)             (2)

使用加速技能/道具后 ADT'=ADT(1-t%)   t为加速因子 (3)

看看上边 公式是不是简单多了

引入ADT的意义是什么呢?
写过计算机程序的人应该有这个概念
如果你是gravity的程序员 我现在要你写一个决定攻击频率的程序
你如何写呢? 你可以直接写某个函数让电脑1秒钟演算15次还是20次攻击么?
实现起来很困难吧 正常人类大概都会使用一个延时的函数或者循环
你要0.1秒攻击一次? ok我写一个函数造成延时0.02秒
每循环或者调用5次就调用一次演算攻击的函数就是了 很简单的方法

若RO最小时间单元设定为0.02秒
那么每次攻击延迟过后隔 ADT个循环之后发出一次攻击动作
也就是每ADT*0.02秒发出一次攻击

熟悉法师的人再仔细看看公式(1) 有没有似曾相识?

ADT=(1-AGI'*1/250)* BaseADT  (1)

施法时间=(1-DEX*1/150)*基础施法时间 (4)

这并不是巧合 同一个小组在设计一个系统的时候往往使用类似形式的公式
或许因为ADT跟攻击速度正好是反比的 gravity认为不够直观
才取了200-ADT作为ASPD的代表吧 总之ASPD看着越大 攻击速度就越高

彻底抛弃ASPD而采用ADT的概念 能使很多事情变得清晰而自然
你的aspd175 我的aspd180比你高5点 嗯 不错 爽
但是高5点aspd差了多少呢? 你能说出来么?
现在好了 看看公式(2) ADT和攻击速度是完全反比的
你的ADT25 我的ADT20 我的攻击频率或者说攻击速度是你的25/20=1.25倍
也就是 单位时间造成的伤害是你1.25倍
BINGO!

再来看看武器的选择
把公式(1)带入公式(2)
APS=1/{0.02*[(1-AGI'*1/250)* BaseADT]}
在人物一定的情况下 APS=1/(k*BaseADT)
换句话说 APS也跟武器的基础ADT成反比
拿常见的铁匠武器选择问题来说
单手斧BaseASPD=135         BaseADT=65
炼锤 BaseASPD=132.5       BaseADT=67.5
因此 无论体铁敏铁均铁打造铁 攻击力相同的情况下单位时间内造成的伤害
使用单手斧是炼锤的67.5/65=1.04倍 比较两种武器直接攻击力再乘这个系数就可以了
次式也同时清楚的说明武器的选择与agi无关

接着看看加速药
喝了波水之后单位时间内伤害增加了多少呢? 15%?
APS'=1/ADT*(1-t%)*0.02 
t=15代入得 APS'=APS*1/0.85=1.18*APS
也就是说 单位时间伤害约增加了18%
而2HQ和速度激发则实际增加了约43%的单位时间伤害
你现在明白铁匠练级该开凶砍还是速度激发了么?
(一般铁匠只能常驻一样且不考虑怪物减算防御)

最后我们来讨论aspd取整问题
大家都知道gravity设计程序很爱取整的 在这一项上也不例外
由公式 APS=1/(ADT*0.02) 和 APS=1/[(200-ASPD)*0.02]          
可以看到 延时函数的调用次数ADT 必须是整数
(以前有人提出过 施法时间=(1-DEX*1/150)*基础施法时间 的最小可分辨时间单元也是0.02秒 所以dex也要凑整5的理论 但是没有验证
个人认为重力社实在没有必要写两个延时函数 除非有特殊理由好的程序员一般不会这么做
所以有可能施法和攻击的最小时间单元相同 考虑到零偷的最小几率0.02%....重力社实在很喜欢0.02这个数 不过有什么内在联系也说不定)


感谢点点滴滴给出的实测和其他网友提供的KE封包
我个人现在基本认为APS=1(ADT*10*0.002)
也就是说 ADT或者是ASPD小数点后保留一位有效数字
从KE的封包来看系统间传送的数据就是ADT*10=(200-ASPD)*10
ASPD只是一个显示数据 很可能运算中根本不碍它的事
ASPD=200-ADT 这个公式里的200实际上是随意定的罢了
如果有一天gravity的程序员心血来潮把所有公式里的200改成300
各位的aspd会显示成275这样 但实际的攻击速度根本没有任何改变
起作用的是锁定ASPD190 或者说是锁定ADT为10 也就锁定了攻击速度的极限是每秒5下
这也从侧面说明了ASPD的数字基本上就是一无用的概念 仅仅拿来看的


若ADT如KE封包和实测中描述的那样是精确到小数点后一位的话
那么实际上可能性比较大的就是运算中对10*ADT那个变量取整
配人物点的时候仍然还要凑整
即是对ADT=BaseADT*(1-AGI'/250) 两边都乘10凑整
也即是 10*ADT=BaseADT*(10-AGI'/25)凑整
对盗贼拿短剑的情形 Base ADT=50 右边为500-2AGI'=500-2AGI-DEX/2
DEX是偶数刚好为整数
而对炼金拿钝器的情形 右边写成
10*ADT=135*(10-AGI'/25)=1350-27*(4agi+dex)/20
也就是说 dex+4agi需要是20的倍数

但是这里略有不同,我们需要ADT尽量小,若在整数的基础上再增加一点dex
则10*ADT则会变成 1799.9XXX这样 小数部分将要舍去
所以在炼金的例子里有可能dex+4agi除20余1是最合算的
重力社确实在给我们发红利 但这个红利实在是太小了
以aspd189.9-aspd190.0来算
增加的0.1aspd提升了0.1/(200-190)=1%的每秒伤害
由于常见的aspd大约是180上下 这时的额外伤害就只有0.5%
估计还不如网络延迟的影响大 基本可以忽略掉
因此结论就是 配点的时候agi和dex随便点就好了 <han2>
这里的问题是0.002秒的时间单元太小了 程序里基本体现不出来
一个比较合理的做法是如点点所说用不均匀的攻击把"丢掉"的攻击次数补回来
这个似乎跟我们平时练功的直观也比较吻合

本文主要是为了提出ADT的概念 让攻击速度的概念更加直观和容易比较而已
其他的有待证实

gdd,2004-06-20, 21:45:35
“考虑到零偷的最小几率0.02%”

这个是真的?
这里说的不清楚
我的意思是零偷的基础是建立在最小偷窃几率为0.02%基础上的
所以0.02这个数字确实很受gravity钟爱
赫赫

TOP

点点滴滴,2004-06-20, 21:51:59
BTW:ADT的概念早就是公认的了。。。。一直都没去想过ASPD的问题。。只是个相对比较直观的观赏数字而已。。
关键是0.02,真的确认是0.02吗。。。。。——+
0.02是按照公式和日本网站公布的数字推算的
还需要实测支持 呵呵

TOP

点点滴滴,2004-06-20, 23:36:37
记得有个地方说到Ro的动作是分成50个frame每秒的……
似乎……
这倒有可能
而且我觉得ro绝大多数时候肯定没有50fps......

TOP

呵呵
偶怎么能不给飞雪大大面子?

TOP

那一部分是推测....缺乏实际根据
如果纯按以前的"实测"来说应该是aspd有效到小数点后一位
也就是说 是否整数都无所谓
但这种测试跟测攻击力不同 没保证双盲的情况下结果很难有说服力
因为aspd=188 和aspd=189也只相差约9%而已
而一般测试的aspd是选180左右 180和181只差5%
已经在统计学误差范围之内了 所以偶觉得以前这方面的实测都有些缺陷

TOP

如果真如点点所说和我以前所知
RO每秒能表示的动作不超过50桢
那程序不可能均匀的表示出小数点一位后aspd的动作
aspd不是整数时我们将可以看到时快时慢的攻击

TOP

唉...不明白为什么写出来都关注在后边
偶都说了是按照日版公式做的推测
不过 偶实在看不明白飞雪贴过来的那个网友想说什么
VC里的接口函数timeGetTime()本身可精确至1ms
写一个循环 不停调用此函数至增加20ms跳出循环即可实现0.02s延时了
干该死的CMOS什么事情
或者说 gravity可能是在执行本次攻击动作的相关程序前开始计时
执行完之后检查时钟 不到20ms的就loop去补足20ms
这样攻击速度不会随服务器配置而变化
某些很古老的单机游戏拿到现在的电脑和操作系统上运行
游戏速度会变得特别快 游戏设计者不可能允许这种情况发生
这个20ms的上限很可能是放宽了他服务器和网络条件的最低配置而设定的
当然上限可能根本就不是20ms 这个0.02是日本的funs实测或者估计出来的
他也有可能是0.019秒这样 靠爱好者肉眼的计数已经区别不出了

TOP

吉吉降头仔,2004-06-21, 08:48:51
好像从来都是有时快时慢的啊~
还有这文章有什么意义?
是不是AGI超过一定数值就浪费了呢?
这个就要考虑是网络通信条件造成的还是程序本身就这么写的了
呵呵

TOP

点点滴滴,2004-06-21, 09:03:47
楼主,那个函数是精确到毫秒级,但是做不到1毫秒的时间间隔的……

timeGetTime

The timeGetTime function retrieves the system time, in milliseconds. The system time is the time elapsed since Windows was started.

DWORD timeGetTime(VOID);
Parameters
This function does not take parameters.

Return Values
Returns the system time, in milliseconds.
只要一个延时循环的执行速度小过1ms就可以了
然后每个循环check一次时钟 到时间就跳出循环来

TOP

点点滴滴,2004-06-21, 09:14:13
[QUOTE]
我并不是说各位有伪造数据的倾向 由于我本人是搞学术的
这是一个人类心理学的问题 记数和记时类实验不象测攻击力 电脑给个清楚的数字在那里
是多少就是多少 需要人工记录频率和时间的实验受心理因素影响比各位想象的要大的多

哎呀哎呀。。。。听起来像是在说我呢
从上次某人提供的ke封包代码来看,我们需要知道的,仅仅是aspd精确到小数点后1位
而加1agi和dex都可以提供在这个精度之内的aspd提升,不用特意去控制agi和dex来取整aspd。
一般玩游戏,到这个程度就可以了 [/QUOTE]
呵呵 偶是对事不对人
但是我不知道KE封包的那回事.....
你说的从封包里看出aspd包括小数后一位是说客户端送出的aspd信息包括小数点后一位
还是说决定封包里含有攻击指令的频率可以精确到aspd小数点后一位?

TOP

如你所说 这样系统资源开销很大
所以需要有一个RO程序的系统周期 每次所有人物的运算都随这个周期的开始而同步开始
所以只需要有一个全局控制程序在那里数timer
只要每个人物的运算都小过系统周期 先运算完的自然结束并且在下一个RO周期到来之前不发出动作就可以了
至于有人物的运算大过系统周期怎么补这个除了把ro服务器端反汇编出来估计看不出

TOP

偶像啊
KE封包那段明显看出来ASPD只是一个显示值
所谓的val即是ADT 那么系统攻击间隔应当是写成ADT*10*0.002
最小可区分的间隔2ms........

TOP

如果ADT是精确到小数点后一位的话
那么配人物点的时候就还是要凑 只不过是要把
ADT=BaseADT*(1-AGI'/250) 两边都乘10凑整
也即是 10*ADT=BaseADT*(10-AGI'/25)凑整
对盗贼拿短剑的情形 Base ADT=50 右边为500-2AGI'=500-2AGI-DEX/2
DEX是偶数刚好
而对炼金拿钝器的情形 右边写成
10*ADT=135*(10-AGI'/25)=1350-27*(4agi+dex)/20
也就是说 dex+4agi需要是20的倍数

但我觉得从封包里看是对10*ADT取整 因为我们需要ADT尽量小
所以在炼金的例子里dex+4agi除20余1是最合算的?????

TOP

直观感觉就是补回来丢掉的攻击次数 呵呵

TOP

返回列表