У нас есть и модульные тесты, и интеграционные тесты, и приемочные (на ферме из девайсов). Да, случаи бывают, что тесты ломаются :) Но ведь это нормально. Самое главное, чтобы тесты никогда не были "обузой", из-за которых не поднимается рука что-то менять.
На счет ассерта.... ну да, тест не показывает напрямую ошибку, но по контексту довольно быстро понятно, где она произошла, так что это никогда не было проблемой.
Да, все верно, ускорение зашито в симуляцию конфигурационным параметром. Фишки начинают падать, как только во время тика гравитации определяется, что им можно падать. Т.к. во время симуляции может происходить множество разных событий из-за действий игрока, сказать на каком тике это произойдет точно невозможно.
Т.к. в симуляции потенциально все может измениться в следующий тик, мы не пытаемся просчитать "глубоко". Учитываются текущие, актуальные для этого тика препятствия/фишки.
У вас есть какие-то особенные механики, связанные с воздействием на фишки во время полета?
Да. Например, где-то взрывается бомба и ее взрывная волна, которая у нас распространяется не мгновенно, повреждает фишки в полете. И это лишь один из примеров.
А как часта сменяются этапы: после движения на одну клетку, или после более крупных логических шагов?
Симуляция просчитывает потенциальное воздействие гравитации каждый тик, т.е. постоянно.
Порядок обхода в любом случае играет роль, так как с ним связаны логика проверок и формат хранения промежуточных состояний.
Как я выше написал, предварительный этап потенциального просчета вариантов падения фишки делают порядок обхода произвольным. Учитывая, что гравитация может быть расставлена на поле как угодно, для нас это было крайне важным условием.
К сожалению, когда искал, не нашел вообще никаких публикаций на эту тему. Вы тоже все сами изобретали?
Если не сложно, опишите, пожалуйста, пример нагруженного микросервиса на Ruby, который переписали на Rust, чтобы избавиться от бутылочного горлышка. Подход интересный, хочется услышать детали :)
А в чем, собственно, проблема? Есть логика, она выдает «результат хода» в виде «фишка #32 перемещается из [1,1] в [1,2]», есть визуализатор, который знает как нужно анимировать перемещение – он его и анимирует.
Проблема была в том и, наверное, в статье следовало бы на этом сделать акцент, что симуляция у нас не блокируется после ввода от игрока. Игрок потенциально может влиять на перемещающиеся фишки, поэтому мы не знаем на 100%, что фишка гарантированно переместиться из [1,1] в [1,2]: где-то в промежутке с фишкой может случиться все, что угодно. Именно поэтому симуляция "тикает" мелкими шагами и на каждом шаге обновляет свое состояние.
Да, вот и мы, по сути, решили использовать привычное и понятное нам решение :)
А можете рассказать, как вы реализуете гравитацию? Она работает для поля в общем виде, или считается/задается для каждой клетки индивидуально? Обрабатывать начинаете снизу-вверх, или сверху-вниз?
Гравитация может задаваться индивидуально для каждой фишки. У нас гравитация высчитывается в несколько этапов: 1) проверка на потенциальные "падения" фишек 2) собственно "падение". Несколько этапов нивелируют проблему порядка обхода фишек.
Интересно, как разруливаются ситуации, когда, например, верхушка столбика, заблокирована и заполнение идет из соседних.
Для этого у нас есть специальная довольно замороченная эвристика "скатывания со склона". Когда мы ее реализовывали, то смотрели на уже существующие игры на Youtube с замедлением времени :)
вы переизобрели уровневую архитектуру игрового приложения где на нижнем слое менеджеры общего назначения-> выше жанровое ядро-> логика представления -> арт. Ну и назвали это детернимированным движком. Забыли ещё про жанровый плагинный редактор упомянуть тогда повестрование было закончено.
Переизобретать мы ничего не хотели, а просто следовали устоявшимся best practices в индустрии.
"Детерминированность"(нормальная архитектура) не имеет никакого отношения к воспроизводимости реплея.
У меня стойкое ощущение, что мы говорим о разных вещах. В статье "детерминированность" является переводом термина "deterministic". Предлагаю ознакомиться со следующим материалом - https://gafferongames.com/post/deterministic_lockstep/ , послужившим источником вдохновения для упомянутых выше решений.
Вам достаточно добавить в архитектуру паттерн "команда" для управляющих сообщений и перед вами откроются бездны сериализации и прокрутки вперёд и назад с логированием перед эксепшеном или крашем.
Да, с подобным паттерном я знаком и в какой-то степени мы его используем, записывая ввод игрока, однако сам паттерн "команда" не сделает магическим образом симуляцию детерминированной. Статья говорит о более низкоуровневых проблемах.
Господи Карл гравитация в М3? рукалицо. В М3 для перемещения плиток со времён угля и пара используют динамическую анимацию(кокос) или твины(юнити, годо).
Перечисленные выше решения могут использоваться, но не являются единственно возможными. И, да, мы тоже используем твины, только не для гравитации, где требуется более гранулированный контроль.
"Активация" эффектов - логика инитится из конфигурационного файла. а не реализуется в коде.
Я предлагаю еще раз внимательнее прочитать статью. Использование скриптового языка как раз и дает нам возможность реализовать геймплейную логику, если в ваших терминах, через "конфигурационные файлы".
Мы поизучали немного фермы на Amazon. Как-то нас и цены напугали, и какой-то не сразу очевидный API....больше смотреть не стали. Но, кто знает, если понадобится более 50 девайсов...
Мы так пробовали, но не стали. Я в статье описал способ: мы эмулируем ввод на уровне Activity. Т.е сами тестовые скрипты пробрасывают через C# в Activity события ввода. Но для приложения все происходит так, как если бы реально пользователь тапал и свайпил по экрану.
Когда я говорил про видео, я имел в виду реальную стороннюю камеру, которая бы записывала работу всей фермы :) С самих телефонов не хочется снимать видео, т.к это потенциально может негативно влиять на процесс тестирования.
В свое время смотрели на Appium, но так и не придумали, как его прикрутить к Unity приложению, поэтому "нагородили" свое.
Да, снимать отдельно видео всего процесса у нас стоит в планах, т.к. не всегда можно воссоздать "картину преступления" по последнему скриншоту и логам. Кстати, а каким образом вы все это подружили с iOS?
На данный момент в качестве "жаропрочного короба" выступает бывший системый блок от старого PC, из которого изъяли все внутренности. Да, в нем просто находится хаб с работающими телефонами. Охлаждение в нем пассивное, но если кто-то соберется делать что-то посерьезнее, рекомендую присмотреться к более интересным вариантам.
Почему вспучило - сказать конкретно сложно, может и брак. Тем не менее, прецедент был довольно тревожный.
У нас есть и модульные тесты, и интеграционные тесты, и приемочные (на ферме из девайсов). Да, случаи бывают, что тесты ломаются :) Но ведь это нормально. Самое главное, чтобы тесты никогда не были "обузой", из-за которых не поднимается рука что-то менять.
На счет ассерта.... ну да, тест не показывает напрямую ошибку, но по контексту довольно быстро понятно, где она произошла, так что это никогда не было проблемой.
Да, есть. Но деталей я не могу раскрывать, надеюсь, по понятным причинам :)
Да, все верно, ускорение зашито в симуляцию конфигурационным параметром. Фишки начинают падать, как только во время тика гравитации определяется, что им можно падать. Т.к. во время симуляции может происходить множество разных событий из-за действий игрока, сказать на каком тике это произойдет точно невозможно.
Да, примерно так и произойдет
Т.к. в симуляции потенциально все может измениться в следующий тик, мы не пытаемся просчитать "глубоко". Учитываются текущие, актуальные для этого тика препятствия/фишки.
Да. Например, где-то взрывается бомба и ее взрывная волна, которая у нас распространяется не мгновенно, повреждает фишки в полете. И это лишь один из примеров.
Симуляция просчитывает потенциальное воздействие гравитации каждый тик, т.е. постоянно.
Как я выше написал, предварительный этап потенциального просчета вариантов падения фишки делают порядок обхода произвольным. Учитывая, что гравитация может быть расставлена на поле как угодно, для нас это было крайне важным условием.
К сожалению или к счастью, да :)
Если не сложно, опишите, пожалуйста, пример нагруженного микросервиса на Ruby, который переписали на Rust, чтобы избавиться от бутылочного горлышка. Подход интересный, хочется услышать детали :)
Проблема была в том и, наверное, в статье следовало бы на этом сделать акцент, что симуляция у нас не блокируется после ввода от игрока. Игрок потенциально может влиять на перемещающиеся фишки, поэтому мы не знаем на 100%, что фишка гарантированно переместиться из [1,1] в [1,2]: где-то в промежутке с фишкой может случиться все, что угодно. Именно поэтому симуляция "тикает" мелкими шагами и на каждом шаге обновляет свое состояние.
Да, вот и мы, по сути, решили использовать привычное и понятное нам решение :)
Гравитация может задаваться индивидуально для каждой фишки. У нас гравитация высчитывается в несколько этапов: 1) проверка на потенциальные "падения" фишек 2) собственно "падение". Несколько этапов нивелируют проблему порядка обхода фишек.
Для этого у нас есть специальная довольно замороченная эвристика "скатывания со склона". Когда мы ее реализовывали, то смотрели на уже существующие игры на Youtube с замедлением времени :)
Переизобретать мы ничего не хотели, а просто следовали устоявшимся best practices в индустрии.
У меня стойкое ощущение, что мы говорим о разных вещах. В статье "детерминированность" является переводом термина "deterministic". Предлагаю ознакомиться со следующим материалом - https://gafferongames.com/post/deterministic_lockstep/ , послужившим источником вдохновения для упомянутых выше решений.
Да, с подобным паттерном я знаком и в какой-то степени мы его используем, записывая ввод игрока, однако сам паттерн "команда" не сделает магическим образом симуляцию детерминированной. Статья говорит о более низкоуровневых проблемах.
Перечисленные выше решения могут использоваться, но не являются единственно возможными. И, да, мы тоже используем твины, только не для гравитации, где требуется более гранулированный контроль.
Я предлагаю еще раз внимательнее прочитать статью. Использование скриптового языка как раз и дает нам возможность реализовать геймплейную логику, если в ваших терминах, через "конфигурационные файлы".
Мы поизучали немного фермы на Amazon. Как-то нас и цены напугали, и какой-то не сразу очевидный API....больше смотреть не стали. Но, кто знает, если понадобится более 50 девайсов...
Мы так пробовали, но не стали. Я в статье описал способ: мы эмулируем ввод на уровне Activity. Т.е сами тестовые скрипты пробрасывают через C# в Activity события ввода. Но для приложения все происходит так, как если бы реально пользователь тапал и свайпил по экрану.
Когда я говорил про видео, я имел в виду реальную стороннюю камеру, которая бы записывала работу всей фермы :) С самих телефонов не хочется снимать видео, т.к это потенциально может негативно влиять на процесс тестирования.
В свое время смотрели на Appium, но так и не придумали, как его прикрутить к Unity приложению, поэтому "нагородили" свое.
Да, снимать отдельно видео всего процесса у нас стоит в планах, т.к. не всегда можно воссоздать "картину преступления" по последнему скриншоту и логам. Кстати, а каким образом вы все это подружили с iOS?
Спасибо :) Данный "короб" - временное решение.
На данный момент в качестве "жаропрочного короба" выступает бывший системый блок от старого PC, из которого изъяли все внутренности. Да, в нем просто находится хаб с работающими телефонами. Охлаждение в нем пассивное, но если кто-то соберется делать что-то посерьезнее, рекомендую присмотреться к более интересным вариантам.
Почему вспучило - сказать конкретно сложно, может и брак. Тем не менее, прецедент был довольно тревожный.