找回密码
 点一下
查看: 1020|回复: 10

魔兽缓慢的同步速度导致触发停顿的BUG

[复制链接]
发表于 2012-1-18 22:06:06 | 显示全部楼层 |阅读模式
魔兽中提供了Sync系列函数用来同步不同玩家的数据
但是也许是这些函数效率太低的缘故,只要执行的同步达到了一定的数量,就会导致魔兽出现触发停顿的BUG
所谓触发停顿,其实是我自己起的名字……
这种“触发停顿”不是卡,但又很像卡,具体表现在:
游戏能完全正常的运行,所有你的单位都会受你的控制,且并没有延迟。
但是触发在发生了事件的情况下却不会运行动作,而是加入队列。
比如:
正常情况下,我输入load后直接就会有Loading...显示出来
但是实际上什么都不会显示……
直到差不多一分钟后,所有触发会一瞬间全部同时运行
以前输入了多少个load就会同时显示多少个Loading...
[jass]
function test takes nothing returns nothing
    local integer i
    if(GetLocalPlayer()!=Player(0))then
        return
    endif
    set i = 0
    loop
        exitwhen(i>5000)
        set udg_index = udg_index + 1
        call StoreInteger(udg_gc,"test",I2S(udg_index),udg_index)
        call SyncStoredInteger(udg_gc,"test",I2S(udg_index))
        set i = i + 1
    endloop
endfunction
[/jass]
[trigger]对战初始化
    事件
        时间 - Elapsed game time is 0.00 seconds
    环境
    动作
        游戏缓存 - Create a game cache from MapName.w3v
        Set gc = (Last created game cache)
        Wait 0.00 seconds
        For each (Integer A) from 1 to 10, do (Actions)
            Loop - 动作
                Custom script:   call ExecuteFunc("test")
[/trigger]
[trigger]未命名触发器 001
    事件
        玩家 - 玩家 1 (红色) 按下 the 向左箭头 key
        玩家 - 玩家 2 (蓝色) 按下 the 向左箭头 key
    环境
    动作
        游戏 - Display to (All players) the text: (String(index))
        游戏 - Display to (All players) the text: (String((Load 30000 of test from gc)))
        游戏 - Display to (All players) the text: Press Left.
[/trigger]
测试触发停顿.w3x (12 KB, 下载次数: 11)
就像这样,执行触发之后,玩家一就卡住了……
但是玩家二还是完全没有问题…………
当然,单机测试时肯定是什么问题都没有啦,问题只出在多人游戏时。

那么,Sync除了用来做存档系统之外,很少会被用到,这个BUG有什么好说的呢?
实际上,除了Sync还有很多东西可以导致这种“触发停顿”,具体是什么我也不知道……
以前遇到过一些做大图和改DOTA的同学也一样遇到过这个问题,所以随便说一下自己的发现,希望对以后遇到同样问题的童鞋有所帮助吧……

这幅地图至少可以说明两个问题吧……
1)数据的同步和事件的反馈是一个队列里面的,这个队列里面肯定还有其他家伙~!
2)Jass真的是一个很@#¥……&&*的语言,限制太多了……
 楼主| 发表于 2012-1-18 22:28:05 | 显示全部楼层
好吧,其实我也不知道到底是BUG还是我自己的代码写得不对,是不是另有写法……
召唤头目大人解答……
回复

使用道具 举报

发表于 2012-1-19 00:38:37 | 显示全部楼层
神奇的BUG。。。
马克下~~
回复

使用道具 举报

 楼主| 发表于 2012-1-19 14:26:46 | 显示全部楼层
嗯,魔兽的同步机制还真是奇怪
同步完1000个数据只需要1.9秒
同步完3000个数据竟然需要35秒
测试同步时间.w3x (13 KB, 下载次数: 14)
具体就是这样
无标题.png
测试同步速度.w3x (12 KB, 下载次数: 13)
进一步的研究表明,当有许多数据需要同步的时候。
用等待打断触发也无法加快同步的速度,而且
[trigger]等待 0.00 秒[/trigger]也会用掉很多秒钟的时间,可能触发停顿也和这个有一定的关系。
测试同步速度 (2).w3x (13 KB, 下载次数: 14)
看来魔兽段时间内发送的数据量是有极限的,超过了就会堆积起来……

很多人遇到的多人游戏中“触发失效”问题可能就是长时间的“触发停顿”吧……
回复

使用道具 举报

 楼主| 发表于 2012-1-19 15:13:44 | 显示全部楼层
进一步推断,多人游戏时,如果同时发生的事件太多也会导致等待延长,甚至触发停顿。
单人测试时则不会。
测试触发停顿V2.w3x (12 KB, 下载次数: 9)

对了,忘记说了,我用的是1.24的夜天UI
http://bbs.islga.org/read-htm-tid-30850.html
使用了"BJDebugMsg"函数,可能其他UI打不开
回复

使用道具 举报

发表于 2012-1-19 15:53:25 | 显示全部楼层
话说触发的函数里面还有一个触发队列的东西,同样不知道是干啥用的呢.
回复

使用道具 举报

 楼主| 发表于 2012-1-19 16:59:23 | 显示全部楼层
触发队列和这个没关系,它是暴雪用来做战役任务的东西。
作用是:
触发队列中的,第一个触发还未执行完毕时,下一个触发便不能使用。

可以打开某些战役地图看看应用的示例。
回复

使用道具 举报

发表于 2012-1-20 11:06:26 | 显示全部楼层
是你自己写得有问题吧,对同一个位置同时写3000次和对3000个位置写一次能一样么
回复

使用道具 举报

发表于 2012-1-20 11:10:26 | 显示全部楼层
说实话,进步最快的方法就是学习别人的代码,不过看起来GA的人都不屑这一套,总以为自己天下无敌
回复

使用道具 举报

 楼主| 发表于 2012-1-20 13:13:56 | 显示全部楼层
拜托你来吐槽我之前先自己测试一遍好不好??
既然没测试过,你怎么知道“对同一个位置同时写3000次和对3000个位置写一次能一样么”
我既然敢这么写,自然是之前做过测试,证明了两种方法都能反映这种现象,只是这样更直观而已。
实践出真知,不过看起来你挺不屑打开你的魔兽,总以为自己天下无敌。
回复

使用道具 举报

发表于 2012-1-21 16:44:08 | 显示全部楼层
... 我表示我遇到过各种类似的Bug...
  我是想不通原因的......
  Jass真的是一种匪夷所思的东西........
    ....
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-4 06:38 , Processed in 0.120024 second(s), 21 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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