Амазонка.
Игры.
Звучит необычно? Как протестировать продукт как разработчикам, так и геймерам? Под катом тестирование игрового движка Amazon Lumberyard, подходов как к ручному тестированию, так и к автоматизации, а также инструментов, используемых в проекте.
Lumberyard — кроссплатформенный игровой движок, на котором можно бесплатно создавать игры для большинства современных платформ: ПК, Mac, iOS/Android, всех консолей, включая очки виртуальной реальности.
Он также довольно глубоко интегрирован с Amazon Web Services и сервисом потоковой передачи игр Twitch. Ниже под катом видео и расшифровка доклада Артёма Несиоловского с конференции.
О спикере: Окончил МИФИ, факультет кибернетики, более 8 лет в разработке и тестировании.
Работал как над десктопными проектами, такими как GeForce Experience, онлайн-MMORPG Lineage II, так и над мобильными — игра Cut the Rope, а также над веб-проектом Яндекс.
Изображения.
В настоящее время он работает инженером по автоматизации в Amazon в проекте Amazon Lumberyard.
Структура поста
- Игровой движок: особенности, а также различия между тестированием движка и игровым тестированием.
- Ручное тестирование: как мы пытались выяснить покрытие особенностей проекта функциональными тестами.
- Автоматизация: ошибки и неровности, которые мы исправили и впоследствии исправили.
- Инструменты, с помощью которых мы автоматизируем наш движок.
- Интересные баги нашего проекта, с которыми вы наверняка сталкивались, когда сами играли в игры.
Почему Amazon вообще занимается играми? В 2014 году Amazon, как и многие технологические гиганты, заметила, что игры становятся вторым по популярности видом развлечений для человечества.
Первое, как ни странно, это телевидение, а точнее все, что связано с потоковым видео (YouTube, Netflix и все остальное).
Разработчики игр также начинают все чаще использовать сервисы AWS для своих онлайн-игр.
Amazon решает построить экосистему на трех столпах: открыть свою игровую студию для создания игр, которые люди затем будут транслировать и смотреть на Twitch. Эти игры также покажут, какие интересные идеи геймплея можно реализовать с помощью облака AWS.
Как все началось?
В 2004 году немецкая компания Crytek выпустила игру под названием FarCry. Через некоторое время Crytek начинает лицензировать свой движок, на котором построена игра, чтобы сторонние компании могли взять готовый движок и начать создавать игру, геймплей и наполнять его контентом без больших вложений в технологии.Когда Amazon занялась играми, она также открыла несколько студий и начала разработку нескольких игр.
Чтобы каждая студия не изобретала велосипед — свой движок рендеринга, свою систему анимации, физику и так далее, Amazon лицензирует «CryEngine» версии 3 и начинает разработку сразу нескольких игр.
Grand Tour уже вышел на консолях Xbox и PlayStation. Еще две находятся в разработке: MMORPG «Новый мир» и онлайн-шутер «Горнило».
Как только разработка этих игр началась, Amazon начинает бесплатно предоставлять движок, на котором разрабатываются эти игры.
Поскольку он тесно интегрирован с облачными сервисами Amazon, он может привлечь больше людей к использованию AWS.
Игровой движок — это набор API, игровой движок для создания будущей игры.
Чтобы разработчикам не нужно было писать свои собственные игровые системы, они могут просто взять набор API, т.е.
движок, и начать писать собственную игровую логику, добавляя туда контент и креативить, вместо того, чтобы разрабатывать технологию с нуля.
Также в некоторых движках есть редактор.
Это десктопная программа, в которой вы можете создавать уровни, то есть открывать свой уровень и добавлять туда контент и игровую логику.
Вместо того, чтобы долго говорить, иногда проще показать одно видео: Ссылка на видео 8:33-9:53 Здесь показан наш редактор и его интерфейс.
Внутри него запущена игра, которую мы предоставляем вместе с движком.
«Стартовая игра» существует для того, чтобы люди могли зайти, поиграть, что-то изменить и разобраться, как это работает. В целом 3D-игры можно рассматривать как набор трехмерных объектов, которые перемещаются в трехмерном мире и каким-то образом взаимодействуют друг с другом.
В этом видео вы можете увидеть:
- статическая геометрия с текстурами: земля, камни, трава, деревья;
- динамическая геометрия – персонаж анимирован и реагирует на действия игрока;
- пользовательский интерфейс: представление задач в верхнем левом углу.
Про физику: персонаж начнет стрелять по бочкам, они будут двигаться от столкновения с выстрелами и от взаимодействия с персонажем.
В редакторе в любой момент вы можете выйти из режима игры и вернуться в режим редактирования, в котором вы сможете сразу менять свойства объектов, перемещать их, и это сразу же отразится на игровом процессе.
Вы представляли себе примерное количество мест, где что-то может пойти не так, сломаться и перестать корректно работать?
Как проверить двигатель?
Тестирование двигателя основано на трех основных моментах.Первое — тестирование редактора и инструментов: корректная работа, инструменты должны открываться, ничего не должно вылетать, всё должно отображаться корректно, пользовательские скрипты должны выполняться без ошибок, процесс создания игры без сопутствующих ошибок.
Редактор будет использоваться только создателями игр.
Второй — тестирование самого движка или API движка.
Игровой движок, в свою очередь, — это та часть кода, которая также будет работать на компьютерах игроков.
Эта часть проекта тестируется посредством предварительного создания уровней и игр.
В дальнейшем созданные уровни можно тестировать на каждой новой сборке движка, чтобы убедиться, что все игровые элементы, использованные в том или ином уровне, работают как надо.
И третий компонент — тестирование инфраструктуры и совместимости: движок можно настроить и собрать с разными параметрами, игру можно развернуть на разные устройства, и везде она будет выглядеть и работать примерно одинаково.
Особенности проекта Первая особенность заключается в том, что мы поддерживаем большинство существующих игровых платформ.
Несмотря на то, что сам редактор работает только на ПК, во время выполнения, т. е.
игру можно построить на Mac, смартфонах, консолях и даже очках виртуальной реальности.
Вторая особенность в том, что наши пользователи — это два типа людей с совершенно разными потребностями.
С одной стороны, это разработчики, программисты, художники и дизайнеры, которые будут работать над созданием игры.
С другой стороны, это геймеры, на чьих машинах потом будет запускаться игра.
У этих двух групп совершенно разные требования.
Третья особенность заключается в том, что в таких программах, которые позволяют создавать что-то новое, заранее предполагается максимально широкий набор возможных продуктов этого приложения.
На нашем движке вы можете построить абсолютно любую игру: от чего-то простого типа тетриса до сложного онлайн-проекта, в который одновременно играют тысячи людей.
Все три эти функции сильно влияют на количество пользовательских сценариев, каждый из которых необходимо протестировать.
Посмотрите на этот скриншот и представьте, сколько тест-кейсов можно было бы написать только для этой части функционала? Итого по нашему проекту более 11 тысяч тест-кейсов и эта база данных увеличивается примерно на 3-4 тысячи тест-кейсов каждый год. Ссылка на видео 13:20-13:54
Больше всего ошибок мы находим при взаимодействии нескольких компонентов друг с другом.
В этом видео снег в обычном состоянии отображается на кубе как и положено, но как только персонаж начинает с ним взаимодействовать, снег начинает исчезать.
Большинство ошибок, которые мы находим, находятся в таких местах, где соединены несколько компонентов.
Ссылка на видео 14:08-14:41 Однако ошибки не всегда появляются при наличии только двух условий.
Часто бывает, что баги появляются, когда сходятся сразу несколько компонентов.
В данном случае мы рассматриваем баг, при котором в обычной ситуации персонаж просто стоит на земле.
Стоит добавить еще одну степень свободы — поднятие персонажа над землей: при падении начинает проигрываться анимация и камера приближается/отдаляется — текстура начинает пропадать.
Здесь взаимодействуют три компонента: высота, анимация персонажа и расстояние до камеры.
Заранее продумать все эти варианты невозможно, и зачастую мы обнаруживаем такие ошибки только во время специального тестирования.
Ссылка на видео 15:02-15:49 Есть еще одна особенность — у нас много недетерминированных систем.
Это системы, в которых при одних и тех же входных данных конечный результат может отличаться.
Простой пример: в системе есть случайные величины.
В нашем случае это физические системы, которые включают в себя множество вычислений с плавающей запятой.
Операции с плавающей запятой могут выполняться немного по-разному на разных процессорах или компиляторах.
Из-за этого конечная функциональность всегда будет немного отличаться.
В результате такие системы довольно сложно автоматизировать, поскольку сложно объяснить машине, в каком случае это ошибка, а в каком случае это допустимые различия.
Ссылка на видео 16:03-17:14 В движке и в самом редакторе довольно много нетривиальных взаимодействий.
Пользователи часто взаимодействуют в трехмерном пространстве с помощью мыши и клавиатуры.
В этом видео будет показана функция под названием «Имитируемый объект».
Предметы, которые носит персонаж, должны двигаться по законам физики при движении персонажа, на котором эти предметы надеты.
Например, одежду или портфель.
В качестве такого элемента в видеоролике используется рука персонажа.
Когда персонаж движется, рука тоже начинает реагировать.
Часто для тестирования такого функционала нужно совершать нетривиальные действия: что-то переключать в пользовательском интерфейсе, перемещать объекты в трехмерном пространстве, делать перетаскивание, также смотреть графики анимации, расположенные ниже, и делать все в реальное время.
Эта особенность влияет на сложность автоматизации.
Как определить покрытие?
В какой-то момент мы поняли, что написали много тест-кейсов, но сложно было определить, какое у нас покрытие.Наиболее критичные ошибки мы обнаружили не во время полного регрессионного теста, а во время специального тестирования, которое проводилось в конце цикла выпуска.
Мы начали думать: у нас есть движок с большим разнообразием функционала, у нас есть репозиторий на 12 000 кейсов — как понять, в каких местах покрытие достаточно и в каких областях стоит добавить тест-кейсы? Мы обратились к теории тестирования и начали читать о том, как люди определяют покрытие тестами.
Один из способов — определить его через исходный код. В нашем случае это сделать сложно.
У нас есть несколько миллионов строк кода и выполнить эту проверку за короткое время оказалось невозможно.
Второй метод заключается в оценке покрытия посредством оценки требований.
В гибких процессах требования часто хранятся только в головах людей, а не в документации, поэтому оценить покрытие требованиями тоже оказалось нереально.
В результате мы обратились к единственно возможному для нас методу — определению покрытия путем написания модели.
Мы выбрали модель под названием ACC — Attribute, Component, Capability. ACC — одна из самых простых моделей, которая довольно распространена в Amazon для моделирования работы программного обеспечения.
Модель построена на трех основных столпах.
Во-первых, это компоненты, существительные – основные рабочие части системы.
Для нас это вьюпорт, текстура, суть игры.
Далее идут возможности — глаголы — что могут делать эти компоненты.
Например, они могут отображать на экране, что-то рассчитывать, что-то перемещать и так далее.
И третья часть — атрибуты — прилагательные или наречия, которые относятся как к компонентам, так и к их возможностям.
Атрибуты описывают параметры возможностей: быстро, безопасно, масштабируемо, безопасно и т. д. Все это можно свести к трем вопросам: кто? что он делает? И как? Давайте рассмотрим эту модель на небольшом примере.
Ниже приведена демо небольшой части функционала: Ссылка на видео 19:59-21:02 Вьюпорт — это часть редактора, в которой виден уровень.
Видео демонстрирует, что можно вращать камеру, перемещаться по уровню, а также можно добавить персонажа из локального обозревателя игровых объектов.
Персонажа можно переместить, или создать новую игровую сущность, щелкнув правой кнопкой мыши, можно выбрать все текущие сущности на уровне и переместить их все вместе.
Вы также можете добавить еще один геометрический элемент и (как во всех трехмерных редакторах) изменить не только его положение в пространстве, но и изменить его угол и изменить размер.
Окно под названием «Viewport» имеет разные режимы рендеринга.
Например, отключены тени или отключены некоторые графические эффекты постобработки.
Вы можете войти в игровой режим, чтобы немедленно протестировать только что внесенные вами изменения.
Давайте посмотрим на саму модель ACC. Мы быстро поняли, что очень удобно создавать эти модели с помощью Mindmaps, а затем переводить их либо в планшеты, либо напрямую в структуру в TestRail или любой другой репозиторий для тест-кейсов.
На схеме в центре виден сам основной компонент - Viewport - а далее вверху красная ветка - функция Viewport, которая позволяет перемещаться по уровню: можно вращать камеру, можно летать с помощью кнопки «W», «A», «S», «D».
Его вторая функция (оранжевая ветка) — создавать игровые объекты либо через область просмотра, либо с помощью перетаскивания из обозревателя игры.
И в-третьих, игровыми сущностями можно манипулировать: их можно выбирать, менять их расположение, вращать и так далее.
Зеленая ветка слева — это конфигурация видового экрана при переключении режимов рендеринга.
Синяя ветвь выделяет атрибут, указывающий, что область просмотра также должна соответствовать определенным параметрам производительности.
Если он будет тормозить, разработчикам будет сложно что-либо сделать.
Вся древовидная структура затем передается в TestRail. Когда мы перенесли тест-кейсы из нашей предыдущей системы в новую структуру, сразу стало понятно, где не хватает тест-кейсов — кое-где появились пустые папки.
Ссылка на видео 23:01-24:10
Эти структуры растут довольно быстро.
Viewport на самом деле относится к редактору, который является лишь частью движка.
Две основные части: сам редактор и сам игровой движок.
В правой части изображения выше вы можете увидеть несколько компонентов, которые не являются деревянными.
Например, система рендеринга или скриптинга, анимации — это отдельно, потому что они относятся одновременно и к редактору, и к движку.
То есть система рендеринга будет работать в рантайме на конечных устройствах, но в самом редакторе можно будет менять некоторые параметры: время дня и ночи, редактирование материалов, систему частиц.
Результаты и выводы
Моделирование ACC помогло выявить области, в которых пострадало покрытие тестированием.Благодаря заполнению пробелов в охвате количество ошибок, обнаруженных после полной регрессии, сократилось примерно на 70%.
Модели ACC, которые легко построить, также оказались хорошим источником документации.
Новые люди, пришедшие в проект, изучили их и быстро смогли получить некоторое представление о движке.
Создание/обновление моделей ACC тесно интегрировано в наш процесс разработки новых функций.
Мы начали автоматизировать движок через автоматизацию пользовательского интерфейса.
Интерфейс редактора написан на библиотеке QT. Это библиотека для написания кроссплатформенного пользовательского интерфейса для настольных приложений, которые могут работать как на Mac, так и на Windows. Мы использовали инструмент Squish от Froglogic, который работает в системе, аналогичной WebDriver, и адаптирован для среды рабочего стола.
Этот инструмент использует подход, аналогичный Page Object (из мира WebDriver), называемый по-другому — Composite Elements Architecture. На основных компонентах (таких как «окно» или «кнопка») делаются селекторы и прописываются функции, которые можно выполнять с помощью этих элементов.
Например, «щелкнуть правой кнопкой мыши», «щелкнуть левой кнопкой мыши», «сохранить», «закрыть», «выйти».
Затем эти элементы собираются в единую структуру, вы можете получить к ним доступ внутри вашего скрипта, использовать их, сделать скриншот и сравнить.
Проблемы и решения
Первая проблема – стабильность.Мы написали тесты, проверяющие бизнес-логику через пользовательский интерфейс — в чем проблема? Когда бизнес-логика не меняется, но меняется интерфейс, тесты проваливаются, нужно загружать новые скриншоты.
Следующая проблема – отсутствие функциональности.
Многие варианты использования предполагают не просто нажатие кнопки, а взаимодействие с трехмерным миром.
Эта библиотека не позволяла этого; были необходимы новые решения.
Третья проблема — скорость.
Для любых UI-тестов вам необходимо полностью визуализировать весь движок.
Это требует времени; машины для этих испытаний должны быть достаточно мощными.
Решение пришло в виде библиотеки Сибокен.
Эта библиотека предоставляет привязки кода C++ к Python, что позволяет напрямую вызывать функции, предоставляемые редактором или движком, без рендеринга редактора пользовательского интерфейса.
Аналогом из веб-мира является Headless-автоматизация (что-то вроде PhantomJS) — можно автоматизировать веб-приложение без запуска браузера.
В данном случае аналогичная система, только для десктопного приложения, написанного на C++.
Начав инвестировать в этот фреймворк, мы поняли, что с его помощью можно не только автоматизировать тестирование, но и автоматизировать любые процессы внутри движка.
Например, дизайнеру нужно разместить 100 источников освещения в ряд (например, он строит дорогу и ему нужно установить фонари).
Вместо того, чтобы вручную представлять все эти источники света, вы просто пишете скрипт, который создаёт игровую сущность, добавляет туда точечный источник света и утверждает, что каждые 10 метров нужно копировать ранее созданный точечный свет. Бонус для наших пользователей в виде инструмента для автоматизации рутинных задач.
Вторая часть решения проблемы.
Мы очень быстро поняли, что для автоматизации разных частей нашего движка, например, графики и сети, нам нужны совершенно разные фреймворки.
Невозможно создать единый чудовищный фреймворк, который поможет автоматизировать все сразу.
Поэтому мы начали разработку фреймворка под названием Lumberyard Test Tools (сокращенно LyTestTools).
Он основан на Pytest (достаточно большая часть движка написана на Python).
Мы решили использовать так называемую архитектуру Plug-and-play — центральная группа инженеров по автоматизации пишет основную часть фреймворка, который сможет загружать, настраивать движок, развертывать его на различных платформах, запускать тесты и собирать журналы, загружать отчеты в нашу базу данных или S3 и рисовать графику в Quicksight. Plug-and-play достигается с помощью Test Helpers, которые будут написаны местными командами, занимающимися разработкой функций.
То есть команда разработчиков графики будет тестировать по скриншотам, а команда сетевого взаимодействия проверит отправленные пакеты.
Все они будут подключены к нашему единому фреймворку (поскольку обе команды разрабатывают и тестируют модули одного движка), чтобы у всех были одинаковые интерфейсы для запуска тестов и формирования отчетов, чтобы все было более-менее стандартно и корректно работало.
с нашим CI/CD.
Взаимодействие с Lumberyard
Какими могут быть способы взаимодействия/автоматизации настольного приложения? Первый тип взаимодействия фреймворка и движка заключается в том, что процесс запускается непосредственно из Python с помощью функции Subprocess, если приложение запускается через командную строку.Вы можете читать ввод/вывод из стандартного ввода/вывода и таким образом делать утверждения.
Следующий тип — взаимодействие через анализ логов — вы можете читать и анализировать логи, оставленные приложением.
Третий — через сеть.
В лаунчерах игр есть модуль под названием Remote console. Когда на устройстве открыт определенный порт, наша платформа может отправлять пакеты/определенные команды.
Например, сделать скриншот или открыть определенный уровень.
Еще один метод — взаимодействие через сравнение визуальной информации, т.е.
скриншотов.
Также ранее упоминался способ вызова функционала приложения напрямую через API продукта (в нашем случае это вызов через Python-привязки к C++ функционалу редактора/движка) .
Перейдем к примерам использования нашего фреймворка для автоматизации движка.
Посмотрите на этот скриншот.
Детализация в этой области довольно высокая — здесь большое количество растительности.
В современных играх уровни могут занимать до нескольких десятков и сотен игровых километров.
Естественно, каждый из этих игровых кустов не вводится вручную, иначе разработчики просто сошли бы с ума.
В нашем движке для них есть специальные инструменты.
Один из них называется Vegetation Tool. Небольшая демонстрация: Ссылка на видео 32:18-34:06 Видим стандартное начало уровня.
Есть рельеф и можно очень быстро создать рельеф: сделать горы на заднем плане, а также выделить небольшой холм в центральной части.
Саму землю можно покрасить в зеленый цвет с текстурой травы.
Ниже демонстрируется процесс добавления растительности, в данном случае деревьев.
В инструмент добавляется геометрия — деревья, выбирается их подмножество, и с помощью этих деревьев можно нарисовать любой необходимый дизайн.
Это довольно простой пример; этот инструмент имеет множество настраиваемых параметров.
Например, вы можете выбрать не одно дерево, а сразу несколько и задать параметр, чтобы они стояли на определенном расстоянии друг от друга, или задать случайные параметры размера или поворота этих деревьев.
Вы можете добавить игрового персонажа и сразу бегать по уровню, тестируя то, что вы только что вырастили в собственном игровом саду.
Давайте теперь посмотрим, как мы автоматизировали эту функцию с помощью нашей платформы, на примере пары тестов.
Ссылка на видео 34:20-34:58 Здесь стандартный ландшафт и на нем растет много однотипной травы.
Этот тип рендеринга очень ресурсоемок.
Если таких элементов много, можно провести нагрузочный тест. Сюда добавлен игровой скрипт, который при запуске игрового режима просто будет летать по этому уровню.
Задача — протестировать этот функционал и убедиться, что лаунчер игры работает стабильно и не вылетает.
Это пример того, как команда, разработавшая функцию выращивания растительности, написала Test Helper, позволяющий работать с этой функциональностью.
Это пример использования нашей структуры.
Класс запуска выделен зеленым цветом.
При запуске теста лаунчер разворачивается, запускается с параметрами таймаута, и мы делаем утверждение, чтобы проверить, что лаунчер не выйдет из строя через некоторое время.
Затем мы его отключаем.
Приведенный выше код параметризации показывает, что мы можем повторно использовать один и тот же код на разных платформах.
Более того, мы можем повторно использовать один и тот же код на разных уровнях или в разных проектах.
Например, красным цветом выделены платформы: в одном случае это Windows, в другом случае Mac; Проект выделен желтым цветом; Название уровня выделено светло-желтым цветом.
Ссылка на видео 36:07-36:47 Теперь о том, как работает тест — в данном случае мы запускаем его через командную строку.
Откроется программа под названием Asset Processor, одна из основных частей движка.
Эта программа обрабатывает исходные ресурсы (например, модели и текстуры, созданные художниками) в понятные для движка форматы и записывает все в базу данных (SQLite), чтобы движок мог быстро ориентироваться и загружать необходимые данные во время игры.
Далее запускается сам лаунчер, запускается игровой режим, камера несколько секунд летает над уровнем и тест заканчивается.
Мы видим, что один тест пройден успешно, а два теста пропущены.
Это произошло потому, что во время записи видео тест запускался на Windows, а в параметризации присутствуют ещё две платформы, которые соответственно были пропущены при этом запуске.
Есть более сложный вариант. Мы не просто запускаем лаунчер с готовым уровнем, а скрипт напрямую взаимодействует с редактором.
Синим цветом выделено название отдельного скрипта, который будет работать с редактором и выдавать различные команды через API.
Выше находится тестовый уровень.
В данном случае улыбка рисуется на стандартном ландшафте с использованием заранее подготовленной текстуры (маски).
Необходимо проверить, что при использовании маски покраска будет осуществляться только по заранее выбранному контуру и не выходить за его пределы.
Команда, работающая с игровым миром, написала собственное расширение для работы с ландшафтом, которое затем вставляется в наш фреймворк.
Создается новая кисть, которая будет рисовать по маске «Булыжники», цвет кисти устанавливается на красный и выбранный слой закрашивается.
В продолжении создается новая кисть и ей выставляется другая интенсивность.
Маска больше не используется, и в цикле рисуется новый элемент в другой части уровня.
Давайте посмотрим, как работает этот скрипт. Ссылка на видео 38:42-39:35 Сначала запустится процессор активов, который проверит состояние базы данных активов и при необходимости обработает вновь добавленные элементы.
Далее запустится редактор.
Откроется уровень со смайлом, и начнет выполняться скрипт, работающий с редактором.
Он закрасит слой поверх маски, затем создаст синий круг и начнет делать снимки экрана.
В дальнейшем скриншоты будут сравниваться с эталонными, и если все в порядке, тест будет завершен.
Тест делает такие скриншоты для сравнения со стандартами.
Здесь видно, что рисунок пошел четко по границе.
Графика
Мы также используем нашу платформу для графического тестирования.Ссылка на видео 40:04-40:56 Графика — одна из самых сложных частей движка, занимающая большую часть кода.
Проверять можно и нужно всё — от простых вещей вроде геометрии и текстур, до более сложных функций — динамических теней, освещения, эффектов постобработки.
На видео в правом углу видно отражение в луже — на нашем движке все это работает в реальном времени.
Когда камера летит внутрь, вы можете увидеть более сложные элементы рендеринга, такие как отражения, прозрачные элементы, такие как стекло, и рендеринг таких элементов, как металлические поверхности.
Как эта функциональность тестируется с помощью скриншотов?
Это наш персонаж, Рин.
Мы часто используем его для тестирования конвейеров исполнителей.
Художники создают что-то в своем редакторе (например, персонажа), а затем рисуют на нем текстуры.
Процессор активов обрабатывает исходные данные для их развертывания на различных платформах, а графический движок обрабатывает отображение.
Наверняка вы часто сталкивались с ошибкой, когда «текстуры не загружались».
На самом деле проблем, когда что-то случается с отображением текстур, возникает очень много.
Но хорошо бы их всех отловить, сравнив скриншоты.
На первом скриншоте виден баг - некоторые материалы плохо загружались.
На этих скриншотах показан тот самый уровень, где стоял мотоцикл и летала камера внутри кафе, что было продемонстрировано ранее на видео.
Почему здесь все выглядит намного скучнее? Потому что скриншоты делаются не на самом последнем этапе рендеринга, когда графический движок выложил все свои эффекты, а поэтапно.
Сначала берется только рендеринг Теги: #тестирование #Тестирование игры #heisenbug #heisenbug #heisenbug2020piter #heisenbug2020piter
-
Сглаживание Шрифтов
19 Oct, 24 -
Оригинальная Контекстная Реклама
19 Oct, 24 -
Идея Стартапа: Сервис Реализации Идеи
19 Oct, 24 -
Опубликованы Доклады К Конференции Www2007.
19 Oct, 24 -
Почему Иногда Не Стоит Изобретать Велосипед
19 Oct, 24