找回密码
 点一下
查看: 11279|回复: 38

您的地图 有掉线情况么。。那么进来看看吧。。

  [复制链接]
发表于 2008-5-10 10:48:39 | 显示全部楼层 |阅读模式
呵呵。。。我的观点就是大部分掉线都是   等待时间    这个条件造成的
以下引用多位前辈的研究成果

先是KOOK的魔兽的同步机制初探

一张魔兽地图的运行流程可以分两部分,本身就定义好的,和玩家在其间的操作影响。本身定义好的内容包括很多,比如一个攻击1-100的单位,在一个时刻做出的具体攻击必然是个确定值,这个确定值必然要在不同机器上都是一样的,如果不一致,就会产生不同步,通俗的说叫掉线。

单人、局域网条件下这个最小时隙是25ms,就是说,在这一条件下所有可能的操作延迟均为25毫秒的整数倍。嗯,很好理解吧;主机的延迟往往是最低的,不过即使如此也有平均100ms,而网络条件差的需要更多的时隙来同步该次操作。战网情况下,最小时隙是250ms,就是说即使是主机也会有250ms的操作延迟,实际上由于最小时隙的增大,获得更大的空间进行同步,表现出来就更稳定,可就是”不卡“,付出的代价是可能延迟的程度越高  

对于TriggerSleepAction这个函数,是对实际时间的,同样对于不同机器有同步的要求,据此我们也可以了解到它的实际运行机制了:在出现这条命令开始后,触发被挂起,而每过一个可能同步的时隙进行一次检测,如果符合了到期条件,那么就触发就重新返回运作~这也就决定了为何TriggerSleepAction如此的不稳定,而且最小值还依靠着本地的延迟~在战网环境下,你是不能指望TriggerSleepAction能够做250ms以下的停顿的。


名称:[研究]Wait与Timer计时精度研究
作者:zyl910
版本:V1.0.0
日期:2006-5-9


  一直听说Timer比Wait精度高,但是具体精度是多少,没人知道。于是我做了个这个测试。

  我的电脑配置:
CPU: AMD Athlon XP 1700+(实际频率:1463 MHz (11 x 133))
内存: Kingston DDR266 256MB *2(两根)
显卡: nVIDIA GeForce2 MX/MX 400(AGP 4X,显存32MB)


  测试结果如下:

[Test]
Time: 0.00001
Wait[0]: 0.250
Wait[1]: 0.375
Wait[2]: 0.500
Wait[3]: 0.625
Wait[4]: 0.750
Wait[5]: 0.875
Wait[6]: 1.125
Wait[7]: 1.250
Wait[8]: 1.375
Wait[9]: 1.500
WaitGT[0]: 0.250
WaitGT[1]: 0.500
WaitGT[2]: 0.625
WaitGT[3]: 0.875
WaitGT[4]: 1.125
WaitGT[5]: 1.250
WaitGT[6]: 1.625
WaitGT[7]: 1.875
WaitGT[8]: 2.000
WaitGT[9]: 2.250
Timer[0]: 0.125
Timer[1]: 0.125
Timer[2]: 0.125
Timer[3]: 0.125
Timer[4]: 0.125
Timer[5]: 0.125
Timer[6]: 0.125
Timer[7]: 0.125
Timer[8]: 0.125
Timer[9]: 0.125
Timer per Second: 8824

[Test]
Time: 0.00010
Wait[0]: 0.250
Wait[1]: 0.375
Wait[2]: 0.500
Wait[3]: 0.625
Wait[4]: 0.750
Wait[5]: 0.875
Wait[6]: 1.125
Wait[7]: 1.250
Wait[8]: 1.375
Wait[9]: 1.500
WaitGT[0]: 0.250
WaitGT[1]: 0.500
WaitGT[2]: 0.625
WaitGT[3]: 0.875
WaitGT[4]: 1.125
WaitGT[5]: 1.250
WaitGT[6]: 1.625
WaitGT[7]: 1.875
WaitGT[8]: 2.000
WaitGT[9]: 2.250
Timer[0]: 0.125
Timer[1]: 0.125
Timer[2]: 0.125
Timer[3]: 0.125
Timer[4]: 0.125
Timer[5]: 0.125
Timer[6]: 0.125
Timer[7]: 0.125
Timer[8]: 0.125
Timer[9]: 0.125
Timer per Second: 8824

[Test]
Time: 0.00100
Wait[0]: 0.250
Wait[1]: 0.375
Wait[2]: 0.500
Wait[3]: 0.625
Wait[4]: 0.750
Wait[5]: 0.875
Wait[6]: 1.125
Wait[7]: 1.250
Wait[8]: 1.375
Wait[9]: 1.500
WaitGT[0]: 0.250
WaitGT[1]: 0.500
WaitGT[2]: 0.625
WaitGT[3]: 0.875
WaitGT[4]: 1.125
WaitGT[5]: 1.250
WaitGT[6]: 1.625
WaitGT[7]: 1.875
WaitGT[8]: 2.000
WaitGT[9]: 2.250
Timer[0]: 0.125
Timer[1]: 0.125
Timer[2]: 0.125
Timer[3]: 0.125
Timer[4]: 0.125
Timer[5]: 0.125
Timer[6]: 0.125
Timer[7]: 0.125
Timer[8]: 0.125
Timer[9]: 0.125
Timer per Second: 877

[Test]
Time: 0.01000
Wait[0]: 0.250
Wait[1]: 0.375
Wait[2]: 0.500
Wait[3]: 0.625
Wait[4]: 0.750
Wait[5]: 0.875
Wait[6]: 1.125
Wait[7]: 1.250
Wait[8]: 1.375
Wait[9]: 1.500
WaitGT[0]: 0.250
WaitGT[1]: 0.500
WaitGT[2]: 0.625
WaitGT[3]: 0.875
WaitGT[4]: 1.125
WaitGT[5]: 1.250
WaitGT[6]: 1.625
WaitGT[7]: 1.875
WaitGT[8]: 2.000
WaitGT[9]: 2.250
Timer[0]: 0.125
Timer[1]: 0.125
Timer[2]: 0.125
Timer[3]: 0.125
Timer[4]: 0.125
Timer[5]: 0.125
Timer[6]: 0.125
Timer[7]: 0.125
Timer[8]: 0.125
Timer[9]: 0.125
Timer per Second: 89

[Test]
Time: 0.10000
Wait[0]: 0.375
Wait[1]: 0.625
Wait[2]: 1.000
Wait[3]: 1.250
Wait[4]: 1.625
Wait[5]: 1.875
Wait[6]: 2.250
Wait[7]: 2.500
Wait[8]: 2.750
Wait[9]: 3.125
WaitGT[0]: 0.375
WaitGT[1]: 0.625
WaitGT[2]: 0.875
WaitGT[3]: 1.250
WaitGT[4]: 1.625
WaitGT[5]: 1.875
WaitGT[6]: 2.125
WaitGT[7]: 2.500
WaitGT[8]: 2.750
WaitGT[9]: 3.125
Timer[0]: 0.125
Timer[1]: 0.250
Timer[2]: 0.375
Timer[3]: 0.500
Timer[4]: 0.500
Timer[5]: 0.625
Timer[6]: 0.750
Timer[7]: 0.875
Timer[8]: 1.000
Timer[9]: 1.000
Timer per Second: 10




  可以看出:
一、Wait的精度是0.15s左右,Wait(game-time)的精度更是惨不容睹。
二、Timer的精度是0.0001s,但由于各方面原因,速度会稍微慢一点。

  Wait用于秒级的延时。对于 小于0.15s 的延时,必须得用Timer。

“等待”是以秒为单位的
但是可以调节游戏速度
所以现实的1秒 不等于 游戏中的1秒

于是提供了等待(游戏时间)这个触发器
“等待(游戏时间)”实际上是靠“等待”实现的,所以精度差不多

“等待(游戏时间)”对应的BJ函数是:
    constant real      bj_POLLED_WAIT_INTERVAL          =  0.10
    constant real      bj_POLLED_WAIT_SKIP_THRESHOLD    =  2.00

// We can't do game-time waits, so this simulates one by starting a timer
// and polling until the timer expires.
function PolledWait takes real duration returns nothing
    local timer t
    local real  timeRemaining

    if (duration > 0) then
        set t = CreateTimer()
        call TimerStart(t, duration, false, null)
        loop
            set timeRemaining = TimerGetRemaining(t)
            exitwhen timeRemaining <= 0

            // If we have a bit of time left, skip past 10% of the remaining
            // duration instead of checking every interval, to minimize the
            // polling on long waits.
            if (timeRemaining > bj_POLLED_WAIT_SKIP_THRESHOLD) then
                call TriggerSleepAction(0.1 * timeRemaining)
            else
                call TriggerSleepAction(bj_POLLED_WAIT_INTERVAL)
            endif
        endloop
        call DestroyTimer(t)
    endif
endfunction


那么 我们 可以推断在一个持续性反复性判断事件的触发里
用到了等待时间     
每台机器最终执行操作的结果的时间误差必然存在
而联机情况下    我一直认为传送的数据只是操作   
而操作包括了操作发生的时间
这个误差由多种原因造成     
那么误差比较小的   操作就执行了
误差大了   有可能判断操作为无效而再次验证操作  或者 就直接掉线

评分

参与人数 1威望 +3 收起 理由
kook + 3 支持研究

查看全部评分

发表于 2008-5-10 12:00:06 | 显示全部楼层
学习中…………很不错的东东。
回复

使用道具 举报

发表于 2008-5-10 12:09:38 | 显示全部楼层
不知道有没有人连机试过呢
回复

使用道具 举报

发表于 2008-5-10 12:44:21 | 显示全部楼层
楼主的东西完全不用从其它地方转来。
作者本身就是在GA发表的。
回复

使用道具 举报

 楼主| 发表于 2008-5-10 12:50:57 | 显示全部楼层
我不太清楚  
KOOK是GA的我知道。。。
后面那位就不清楚了。。。
GA是埋坟的地方。。。。。可能我没看到吧
回复

使用道具 举报

traxex 该用户已被删除
发表于 2008-5-10 12:58:07 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

发表于 2008-5-10 12:59:06 | 显示全部楼层
http://bbs.islga.org/read.php?tid=1138
而且复制来复制去,连排版都没掉了,别人看起来不舒服呀。
回复

使用道具 举报

发表于 2008-5-10 13:08:46 | 显示全部楼层
而且经常有人以为是老外的发明也出自与GA.....何等失态!
回复

使用道具 举报

 楼主| 发表于 2008-5-10 13:09:36 | 显示全部楼层
我只是想引用一下。。。。。排版没考虑。。。。 [s:186]
回5楼的  我只想列点数据  证明一下
每人机器不一样   数据是不一样的   尤其是连网后
回复

使用道具 举报

发表于 2008-5-10 13:25:10 | 显示全部楼层
,哦,也就是说
掉线的原因有
1:用了本地玩家
2:用了等待时间的问题?

还有没?
回复

使用道具 举报

 楼主| 发表于 2008-5-10 13:32:36 | 显示全部楼层
其他的我不知道
LS说的本地玩家不一定会造成掉线   请不要有这种误区
只是返回值的问题
回复

使用道具 举报

发表于 2008-5-10 13:36:58 | 显示全部楼层
其实那某A。可以考虑做坟区老。
回复

使用道具 举报

发表于 2008-5-10 13:49:16 | 显示全部楼层
哦,上次我就主机不掉其他掉光 是因为加了条本地玩家金钱为XX 我把这个改了就不掉了

这个本地玩家 不会用 所以在我新手的理解中就是不要用他最好啦
呵呵
回复

使用道具 举报

发表于 2008-5-10 14:44:50 | 显示全部楼层
我不同意lz的说法,等待虽然不准确,但同样是经严格的同步实行的。不同机器联机时同时执行等待命令,实际等待或许并非预设值,但是同一值。
首先,这里的掉线是指不同步。假设等待是不能同步的,比如预设的等待0.2秒--创造一个单位,那么实际两台机器执行起来会不会一个是等待0.1秒--创造单位,另一个因为速度慢等待了0.3秒才创造单位呢。

以下是一些未经验证的试验设想:
1.在用精度高的timer,而计时器的到期时间不同,预设玩家a 0.1秒,玩家b 0.2秒,到期的计时器什么也不做或是一个空函数

2.timer到期接上会改变全局的操作---比如创造一个单位

[codes=jass]
function nothing takes nothing returns nothing
endfunction

function dosth takes nothing returns nothing
call CreatSth
endfunction

function deplayer  takes player p1,player p2 returns nothing
local timer t=CreateTimer()
local real ext=0
if GetLocalPlayer()==p1 then
set ext=0.1
elseif GetLocalPlayer()==p2 then
set ext=0.2
endif
call TimerStart(t,ext,false,function nothing or null?)
endfunction

function deplayer2 takes player p1,player p2 returns nothing
local timer t=CreateTimer()
local real ext=0
if GetLocalPlayer()==p1 then
set ext=0.1
elseif GetLocalPlayer()==p2 then
set ext=0.2
endif
call TimerStart(t,ext,false,function dosth)
endfunction

[/codes]
更直接的可以看看如果
[codes=jass]
function debugTriggerSleepTime takes nothing returs nothing
local timer t =CreateTimer()
call TimerStart(t,GetRandomReal(1,2),false,null)
call TriggerSleepAction(GetRandomReal(0,1))
call PauseTimer(t)
call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,10,R2S(TimerGetElapsed(t)))
endfunction
[/codes]
以上,如果在两边机器能显示不同的等待时间,那么就可以支持lz的观点了

补充:
等待与游戏时间等待
由于等待经过的时间可以认为不受游戏本身影响(比如游戏速度),像是暂停游戏过一段时间之后恢复游戏,能用在这里的就只有等待(了吧)。
两个测试的目的, 我将lz提出的等待不同步产生掉线的观点分解为两步
1.等待对不同机器联机执行上会有差异,同一个等待命令在两者上实际时间可能不同
2.在实际执行时刻不同的情况下将会有两种结果:掉线,不掉线。。。
掉不掉线由差异是否过大决定

偶的看法
1.同一等待命令执行结果相同,预设0.2秒的话,也许实际执行是0.175,也许是0.25,也许是1.5,但不同机器将得出同步的结果。
2.对于涉及全局数据内容的,哪怕存在的执行差异时间再小,也会掉线(或者有一个允许偏差存在?)
回复

使用道具 举报

 楼主| 发表于 2008-5-10 15:03:11 | 显示全部楼层
魔兽内的所有数据 应该 不可能是真正的随机值
所有游戏 也一样     都有一系列的预定算法
作为时间精度   理所当然也有个允许的范围
或者进行再次判定
要不然  启不是随随便便就会掉线?
我的猜想是  预设的时间越小  精度就越小
比如  网络对战时的延迟 往往时间很长    很明显的会造成操作无效   并不会掉线
      但是往往在触发里 有等待1秒左右的   很容易就会出现掉线情况
      当然这和事件也有一定关系    有些事件  无法重新判定  那么又是强制执行
      结果就是一个    掉线
回复

使用道具 举报

发表于 2008-5-10 15:39:34 | 显示全部楼层
您所说的掉线是指数据不同导致的没有任何提示的与其它玩家断开吗?
还是指读秒的掉线呢?
回复

使用道具 举报

 楼主| 发表于 2008-5-10 15:46:18 | 显示全部楼层
是秒退        高手都来了。。。偶要要出糗了。。。。
回复

使用道具 举报

发表于 2008-5-10 15:53:12 | 显示全部楼层
魔兽客户端的时间流逝由主机决定(除了掉线部分,用变速精灵知道的),所以我觉得魔兽的同步可能精确到循环次数,如主机每发一个“循环一次”消息,客户端就循环执行一次,
循环可能有{
将玩家操作或接到的其他玩家操作放入队列或发送
对每个单位的当前命令执行(如走一步)
检测每个触发器是否应执行(没有WAIT,SLEEP等的触发器可能一次就执行完)
效验
}
这些都是个人猜想除了第一条外,大家不要见怪,呵呵。



1
回复

使用道具 举报

发表于 2008-5-10 16:05:10 | 显示全部楼层
不知道什么叫秒退啊。就是读秒,然后过一阵掉线么?
回复

使用道具 举报

 楼主| 发表于 2008-5-10 16:06:31 | 显示全部楼层
就素直接退出程序 的说。。。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 点一下

本版积分规则

Archiver|移动端|小黑屋|地精研究院

GMT+8, 2024-5-2 10:27 , Processed in 0.240423 second(s), 23 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表