Статья
Раздел:
Разное
Приветствую, Вас - хейтеры рефорджа, сегодня на вашей улице праздник, ибо недавно мною был обнаружен просто отвратительный баг, баг связанный с замедлением времени внутренних таймеров спустя реально пройденное время.

Суть бага

Как видите через 10 минут таймеры стрелок начинают отставать, вы подумаете, что это невозможно, а вот возможно, скажу я и построил таблицу ускорения всех таймеров она приблизительная, но что я могу сказать, что время замедляется практически равномерно до 30 минуты, потом происходит резкое выравнивание и опять замедление
раскрыть
function BugSpeed()
    local table = {
        1,
        0.998,
        0.997,
        0.996,
        0.995,
        0.994,
        0.993,
        0.992,
        0.991,
        0.99, --10
        0.989,
        0.988,
        0.987,
        0.986,
        0.985,
        0.98,
        0.978,
        0.978,
        0.978,
        0.978, --20
        0.976,
        0.975,
        0.975,
        0.975,
        0.975,
        0.975,
        0.975,
        0.98,
        0.99,
        1, --30
        0.997,
        0.995,
        0.994,
        0.993,
        0.992,
        0.991,
        0.99,
        0.99,
        0.99,
        0.989, -- 40
        0.988,
        0.987,
        0.986,
        0.985, --45
    }
    local t = 0
    local k = 1
    TimerStart(CreateTimer(), TIMER_PERIOD64, true, function()
        t = t + TIMER_PERIOD64
        if t >= 60 then
            --print("скорость игры изменена на "..table[k])
            t=0
            DelayPerTime=table[k]
            k=k+1
        end
    end)
end
Я очень надеялся, что дело в моих кривых руках, но как бы я не переделывал систему, всё так же замедлялось, я проверял:
  • на одиночных таймерах
  • складывал инты на математическом таймере
  • делал да вейтах
  • проверял на джассе
  • проверял на сд графике
  • делал на полностью чистой карте
ПРОБЛЕМА НЕ НАБЛЮДАЛАСЬ ТОЛЬКО НА 1.26
не проверял только на промежуточных патчах типа 127, 128, 129, 131, они слишком не ходовые чтобы вообще их трогать.

График замедления всегда разный

Это не возможно адекватно использовать, потому что замедление происходит в сотых или же тысячных и оно абсолютно рандомно, с этим никак нельзя работать, мне пришлось сделать среднее ускорение, и это порою может сломать игру, потому что я никак внутренними средства варкарфта не могу просчитать это.
Примерно на 27 минуте замедление находится на своём пике и составляет 2,5% это нереально много, таймер в 600 секунд запущенный на 17 минуте, зазвонит не на 27 минуте а на 27 минуте 15 секунде реального времени, хотя Варкрафт будет думать, что всё норм. это колоссально много ЭТО НЕРЕАЛЬНО ПЛОХО.
Но опять таки, если бы не музыка, скорость которой не меняется, баг бы не был обнаружен, и угораздило меня делать музыкальную игру в рефе =(, всем спасибо.
`
ОЖИДАНИЕ РЕКЛАМЫ...
38
Сколько ещё сюрпризов надо обнаружить, чтоб ты бросил вц3)
33
ScorpioT1000, это да, но я бы никогда бы не стал делать эту игру на юнити, я и в оригинал (fnf) то не играл даже, тут суть была просто упороться и сделал игру-прикол именно в варкрафте
17
Что, если сделать испытания на компьютерах разной конфигурации?
33
SNART, и это делал, проверял на "новом" пк 2019 года и на ноуте 2010,

Так же этот баг получал и ageron в аскадии, когда звук диалогов, не соответствовал субтитрам
17
Ну, с рефом может быть..
А вот интересен такой вопос: Есть синематик, который сделан под музыку, то есть видео-эфекты совпадают с подходящими к нему звуками в соответ... Ну, в общем понятно.
На разных конфигурациях, или на разных версиях игры, не вспомнить, - музыка не соответствовала заданному времени.. Это то или другое?
33
ну скажем процент замедления будет 1%, ты делаешь триггер где будет таймер или вейт "ждать длительность музыки", ты продребажешь звук тебе скажу всё ок 180 сек. а в итоге 180*1.01=181.8, звук закончится, 1,8 сек будет тишина, а потом только только произойдёт отложенное действие. В принципе это нигде не критично, и в реалиях даже сложно заметить, вот я заметил считай через 3 года
38
Я ещё на конкурсе ланда хти беды с аудио и таймерами наблюдал, кстати
33
ScorpioT1000, Но думал что показалось? Я просто поздно заметил слишком, знал бы заранее, даже рыпаться бы не стал музыкальную игру делать
38
Нет, думал, что это баговый вц3 и забил, сделал на вейтах вроде с запасом смещения времени
22
Идея костыля. Пустить по определённому участку юнита пустышку с определённой скоростью. Настроить его скорость и маршрут так, чтобы его движение каждые 0.01 сек реального времени вызывало срабатывание триггера Юнит вошёл (покидает) регион.
Можно использовать несколько юнитов, создавая новых под каждый конкретный случай использования времени. Задавать расстояние и скорость заранее, и посылать юнита в регион, чтобы он доходил до точки в строго нужное время. В этом событии ввести учёт таймеров, которые должны срабатывать.
Вместо движения можно использовать отлов переодических уронов от яда каждые 0.01 сек на специально выбранном для этого юните. Или регенерация + отлов хп....
Для больших проектов костыль не подойдёт, но этой карте может помочь.
33
У этой карты есть свой рабочий костыль, просто так как замедляются именно внутренние таймеры, то скорее всего и движение, регенерация, урон тиков яда любого юнита тоже привязано к этому времени, но попробовать стоит, я правда ничего не понял, надо более вдумчиво покурить эту тему, спасибо
22
Bergi_Bear:
У этой карты есть свой рабочий костыль, просто так как замедляются именно внутренние таймеры, то скорее всего и движение, регенерация, урон тиков яда любого юнита тоже привязано к этому времени, но попробовать стоит, я правда ничего не понял, надо более вдумчиво покурить эту тему, спасибо
Т.е. возможно замедляется всё, кроме воспроизведения звуков? А какой либо отлов окончания воспроизведения звука есть?
33
Т.е. возможно замедляется всё, кроме воспроизведения звуков? А какой либо отлов окончания воспроизведения звука есть?
Возможно да что замедляется всё кроме звуков, я проверял только таймеры и вейты (одинаковое поведение). Прямого отлова окончания звука нет, только если основываться на его длительности GetSoundDuration
10
с разной памятью, разными ОС, с разными процами всегда так?
график всегда разный, но все же представлен какой-то график. значит общая тенденция к замедлению и дальнейшему выравниванию есть всегда?
Реф вроде может получать локальное время на компьютере? можно ли триггерить длительные таймеры, используя его?
38
Slonick, таймеры, как правило, работают от прерывания тикера на мат плате, а не от локальных часов

Ясное дело, что там конкуренция процессов, потоков и подпрограмм луа и жасс, но изначальный луп явно на тикере работает
33
с разной памятью, разными ОС, с разными процами всегда так?
Да на разном железе тестили.
Да график разный, но есть общая тенденция на 10, 20 и 30 минутах, см код из шапки, тестов было слишком мало (150 где-то), потому что это нереально сложно ловить.
6
Загруженная карта только на 1.32+ будет работать... зачем так? :(
Bergi а я думаю наконец-то докопалась до сверхточного таймера. То же, что и ты ищешь. Он должен быть основан на изменениях внутриигрового времени. Т.е. триггер срабатывает каждый раз, когда внутриигровое время меняется.
Посмотри на девятый пост в "Using game events as a clock source instead of timers?" на Hive и "High speed triggers or a slow TriggerRegisterTimerEventPeriodic()" - надо использовать TimerStart() и сверять GetTimeOfDay()
38
Lasto4ka, норм идея, а что во время паузы, норм работает?
33
Была идея сравнивать с реальным os.time там число и это работает на луа в рефе, скорее всего сравнение с GetTimeOfDay тоже фигня полная, но я это так и не проверил, потому что утратил интерес к данной теме.
24
А это все еще воспроизводится? Вроде что-то такое чинили как один из сточников десинков в долгих матчах.
В целом, как я понимаю, это шалит внутренний счетчик тактов для игровой логики, который по какой-то причине (догадываюсь по какой, но не скажу) перестал попадать в реальное время с достаточной точностью. А музыка воспроизводится без привязки к тактам игровой логики и вобще скорее всего в отдельном потоке, вот и обнаруживается несоответствие.
33
А это все еще воспроизводится?
Да кто его знает, нет необходимости проверять это
25
Была идея сравнивать с реальным os.time там число и это работает на луа в рефе, скорее всего сравнение с GetTimeOfDay тоже фигня полная, но я это так и не проверил, потому что утратил интерес к данной теме.
os.time() же в секундах возвращает, тогда уж лучше os.clock(), перспективный вариант для фикса мог бы быть
Чтобы оставить комментарий, пожалуйста, войдите на сайт.