Русский
Русский
English
Статистика
Реклама

Google sheets

Как работать тестировщику выстраиваем планирование, общаемся с командой разработки и проверяем сайты на безопасность

03.03.2021 14:04:54 | Автор: admin

Мы собрали митап, где трое экспертов по QA рассказали, о чем тестировщику нужно говорить с командой разработки, какими инструментами пользоваться для планирования и тестирования, а также что нужно учесть, чтобы сделать сайты безопасными.Внутри есть видео и текстовая выжимка по каждому докладу.

Современные паттерны тестирования

Рассказывает директор по развитию бизнеса в IT-компании @BSL_Dev и ex-руководитель отдела обеспечения качества Redmadrobot Марина Куликова @Marishunya_QA.

Коротко в чем суть.

Бывает, что в командах разработки забывают о принципе раннего тестирования. Существует миф, что тестирование продукта должно проходить в конце спринта или разработки. При такой организации процесса проекта могут возникать ошибки (как процессные, так и технические).

Чтобы такого не случалось, тестирование продукта должно быть в самом начале разработки. Кроме того, тестовые активности должны идти параллельно с ней. Это помогает тестировщикам оповещать команду о рисках заранее и давать обратную связь на каждом этапе, начиная от анализа требований до финальных релизных отчетов и поддержки.

Основная цель тестирования своевременно оповещать команду о реальном состоянии системы или продукта

Основные точки опоры для построения тестирования

  1. Анализ требований или технического задания.

  2. Инфраструктура важно настроить окружение, выбрать целевые устройства, какие тестовые данные потребуются.

  3. Процесс коммуникации нужно договориться, в каком формате мы выстраиваем обратную связь с командой (например, делаем отчеты о тестировании в Jira).

  4. Разбираемся, как именно организовываем тестирование: какие виды тестирования, на каких этапах применяем, как распределяем ресурсы, планирование и так далее.

  5. Уделяем время написанию отчетности и договариваемся, какая отчетность и в каком виде нужна.

  6. Постоянно внедряем улучшения и анализируем изменения.

О чем тестировщик должен сообщать команде

  • Что нужно автоматизировать. В процессе коммуникации с разработчиками и менеджерами тестировщику нужно определить и рассказать, какие тесты должны быть автоматизированы и на каком уровне.

  • Как оптимизировать работу. Нужно делать постоянную оптимизацию тестов, чтобы они затрачивали меньше времени. Задача тестировщика минимизировать время выполнения тестов, оптимизировать фича тесты и регресс. Это нужно, для того чтобы быстро получать информацию о состоянии продукта.

  • Обеспечить полезные метрики для бизнеса. Например, количество багов на продакшене, количество активностей, как двигается процесс написания документации, время, затраченное на тестирование и т.д. Такие метрики будут сигнализировать, всё ли у проекта хорошо. Кроме того, с помощью них тестировщик может показать результаты работы всей команды. Но стоит помнить, что не стоит закапываться в метриках, а нужно использовать скорее их как опорные точки. Ведь, помимо метрик, есть и другие системы отчетности.

  • Напоминать о новых инструментах. Важно говорить об инструментах тестирования, потому что сейчас они постоянно меняются. Стоит постоянно мониторить, как изменяются инструменты, и добавлять себе самые лучшие.

Тестирование это как круговая оборона. Весь продукт охранять очень сложно, поэтому тестировщики создают датчики (некие красные флажки), которые в нужный момент сообщают: alarm! И подобные датчики это метрики, а также автотесты, различные приемы и т.д. Задача команды тестирования выстроить многослойную систему защиты, состоящую из нужных датчиков. Также стоит помнить, что помимо того, что QA тестирует, команда ещё сообщает реальное состояние системы, где все окей, где начинает рваться, а где все плохо и нужно срочно исправлять.

Как тестировщику обеспечивать обратную связь для команды

  1. С помощью парного тестирования или программирования. Автоматизацию тестирования полезно делать при поддержке разработчиков. На этом этапе должно происходить взаимное ревью, это помогает тестировщику глубже узнать систему и уже на этом этапе обнаружить какие-то проблемы.

  2. С помощью Code Reviews. Это не совсем работа тестировщика, но в проекте через Code Reviews можно получить обратную связь. Например, если у нас фича автоматизации типовая, и она долго ревьюится на разных проектах, то нужно выяснить причину.

  3. Через модульные тесты (Unit tests).

  4. С помощью автоматизированных интеграционных тестов (Automated Integration Test).

  5. С помощью автоматизированных Acceptance Tests. Эту активность можно разделить с продакт-менеджерами.

  6. По возможности следует автоматизировать Regression Test.

  7. Постоянный Exploratory Testing.

  8. Обратная связь от пользователей или бизнес-юзеров.

  9. Постоянное UAT-тестирование + DEMO-сессии.

Через что тестировщик может организовать обратную связь с командой

  • С помощью работы с дефектами (багами) нужно определить формат их заведения и оповещения о них, например, делать это в Jira или другом удобном инструменте. Разработчикам не всегда хватает информации в дефекте, чтобы приступить к фиксу, поэтому иногда требуется дополнительная коммуникация с багрепортером.

  • Организовать коммуникацию по сборкам и состояниям тестовых сред. Это понадобится, если вдруг с ними что-то пойдет не так или они задерживаются.

  • Кросс-обучение внутри тестирования. Все специалисты разные, они могут учиться друг у друга, поэтому важно иногда собираться и обсуждать результаты работы и делиться лайфхаками и знаниями продукта. Это некий knowledge transfer.

  • Тест-документация собирать отчетность по фичам, сборкам и по приемке. Для составления отчетности поможет изучение ГОСТов: в них описаны градации дефектов, как с ними быть и так далее. Для проектов, связанных с государственным подрядом, поможет изучение ГОСТ 34.603-92.

Как тестировщикам работать с Google-таблицами (и зачем)

Руководитель отдела тестирования Redmadrobot Саша Строкин собрал собственные Google-таблицы, с помощью которых он выстраивает работу, начиная от планирования и заканчивая аналитикой для тестировщиков.

На нескольких примерах Саша рассказал об инструментах и формулах, которые он использует в работе.

Google-таблицы при планировании подготовка к процессу тестирования

В тестировании есть четыре главных процесса:

  1. Планирование подготовка к самим работам по тестированию,

  2. Test development крафтинг артефактов, разработка сценариев тестирования,

  3. Test execution само выполнение тестирования,

  4. Test analysis оценка результатов тестирования, выделение процессов, которые нужно улучшать или, наоборот, не стоит менять.

Планирование в Google-таблицах это инструмент, необходимый в первую очередь для лидов, чтобы вовремя подключать и отключать нужных людей, проводить ротации, отслеживать нагрузку сотрудников.

Чтобы облегчить процесс планирования, в Sheets можно создать вкладку Dictionary, где описываются все существующие проекты для работы, список участников, роль инженера на проекте и так далее.

Стоит отметить, что Google Sheet позволяет добавлять отдельные срезы, если мы говорим про фильтрацию данных, ее можно делать как на уровне всей таблицы, так и по отдельным критериям. Например, если нажать на вкладку с указанием определенного проекта, то увидим, сколько инженеров на данный момент в нём задействовано и процент их загрузки.

Интеграция Google-таблиц с Jira

Интеграция Excel c рабочим инструментом большинства команд разработки и тестирования Jira возможна через специальный плагин Jira Cloud of Sheets.

C помощью этого плагина можно вытаскивать любые данные из бэклога Jira по тому же фильтру, по которому обычно тестировщики фильтруют дефекты, только с переводом не на графическое изображение, а на JQL.

На примере Саша показал, как решил проверить все свои дефекты и собрать на этом фоне статистику. За время работы над проектом в общей сложности было заведено 1500 дефектов и по ним была сформирована статистика. Можно посмотреть, например, какие из них обладают уровнем приоритетности. Также можно в виде графиков формировать статистику по практически любым показателям.

Кроме того, с помощью плагина можно выгрузить статистику по отдельным проектам и посмотреть статистику по нему. Можно проанализировать, как проекты обрастают дефектами в динамике и увидеть, что, например, в июне и июле на проекте было заведено больше всего багов.

Для формирования такой статистики нужно воспользоваться вкладкой MounthStat (она вытягивает данные о дате создания из общей выгрузки, где мы можем выбрать дату создания дефекта). С помощью функции Trim даты можно рассортировать по месяцам.

Все готовые таблицы для работы из презентации Саши.

Тестирование и безопасность web-сайтов для начинающих тестировщиков

Рассказала и показала QA-инженер Redmadrobot Вика Бегенчева @vikusti.

Основные уловки мошенников, как они могут навредить пользователям или системам:

С помощью cookies

Вика рассказала, что такое cookies на примере интернет-магазина. Допустим, мы открываем браузер, заходим на сайт и кладем в корзину печеньки, которые нам понравились. Если мы закроем окно браузера, а затем откроем заново, то вся информация про начавшиеся покупки сохранится. Это происходит с помощью cookies различной информации о пользователе, которая хранится в браузере локально.

Эта информация нужна для удобства пользователя, чтобы сайт запоминал определенные данные и нам не приходилось постоянно их указывать. Cookies бывают двух видов: временные (cookies-сессии) и постоянные. Cookies-сессии хранятся определенное ограниченное время и могут меняться, когда пользователь перелогинился. Постоянные сookies хранятся всегда, пока вы их не сотрете.

Как хакеры могут использовать cookies

Хакер может угнать ваши cookies и с помощью этого доказать системе, что он это вы. Тогда он сможет переиспользовать их и продолжить сессию. Это происходит так:

Через протоколы: HTTP и HTTPS

Копаясь на просторах интернета, мы до сих пор можем попадать на сайты, о небезопасности которых нас предупреждает браузер.

Почему так? Потому что браузер умный, и он считает ненадежным сайты, в которых происходит соединение по HTTP, а не HTTPS. В протоколе HTTPS есть последняя буква S, это значит, что добавляются повышенные требования к безопасности. В этом протоколе при общении браузера с сервером по протоколу https добавляется сертификат безопасности: если хакер попробует перехватить такие запросы, он получит лишь набор символов и не сможет их расшифровать.

Подбор пароля Brute force

Это атака перебора мошенник может знать логин и с помощью специального скрипта подбирать пароль. Обычно подбор пароля с помощью скрипта занимает около 10 часов.

Как проверять сайты на безопасность

  1. Посмотреть, как устроена безопасность хранения cookies: открываем Инспектор в браузере, заходим в вкладку application и видим свои cookies для сайта. Для проверки безопасности нужно обратить внимание на столбцы под названием httpOnly и secure. Если галочки стоят, то на сайте предусмотрена защита от угона cookies.

  2. Нужно проверять, чтобы все запросы шли через протокол HTTPS. Например, работаем с сайтом диванынадом.ру. Нужно убрать букву S из протокола и проверить, можно ли зайти только по ссылке с HTTP. Если да, то это плохо, мошенник может создать такую ссылку и перехватывать запросы пользователей. Чтобы этого избежать, нужно создать редирект автоматически перебрасывать пользователей на безопасную страницу.

  3. При введении логина/пароля нужно использовать ограничение на количество неправильных попыток, а также использовать таймаут, например, после трех неудачных попыток введения пароля попробовать ввести пароль в четвертый раз можно лишь через час. Это поможет избежать взлома с помощью автоматического подбора паролей.

Вика написала отдельную статью, где подробно рассказала про все пункты и дала еще больше советов для начинающих тестировщиков.

Полезные ссылки

  • Telegram-канал Google Таблицы: много информации о фишках Google Sheets;

  • YouTube STM Solutions: видеоуроки Google Docs, Google Sheets, Google Apps Script;

  • Jira Cloud for Sheets: плагин для интеграции Google Sheets с основным рабочим инструментом большинства команд Jira;

  • owasp.org: некоммерческий фонд, который работает над повышением уровня безопасности ПО;

  • hackthebox.eu: тренировочная онлайн-платформа, на которой можно проверить навыки тестирования в сфере безопасности сайтов;

  • xss-game.appspot.com: тренировочная игра для обнаружения и устранения ошибок XSS.

Подробнее..

Автоматизация или смерть как управлять тысячами единиц игрового контента с помощью гугл-таблиц

10.06.2021 18:12:02 | Автор: admin

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

Звучит сложно, но на деле хватило обычных гугл-таблиц. Ну, как обычных с тысячами строк и формулами, которые не помещаются на экран монитора. Пришлось немного повозиться с их организацией, зато теперь всей игрой мы управляем из нескольких документов.

Под катом на примерах расскажу, как автоматизировать работу с контентом, если в проекте его уже свыше тысячи единиц, как внедрить новые механики и фичи, не ломая при этом баланс и игровой опыт, и даже, как избавить QA-отдел и программистов от лишней работы.

Баланс в онлайн-шутере крайне важная штука. Нужно, чтобы геймплей нравился всем игрокам не было тех, кто не может вообще никого убить или, наоборот, тех, кто доминирует и фрустрирует всех остальных.

На первых годах жизни Pixel Gun 3D использовалась простая схема: весь контент добавлялся и редактировался вручную. Нужно поменять урон пушке? Заходишь в Unity, открываешь нужный файл и правишь руками. Дело на пару минут.

Потом индустрия начала переходить на freemium. От рынка отставать не стали и проект тоже изменил модель монетизации переработали экономику, прогрессию и многое другое, но сейчас не об этом. В результате DAU полетело вверх, а мы усиленно начали добавляли больше режимов, оружия, персонажей и так далее.

Проблемы начались, когда только оружия в каждой категории накопилось по 20-30 единиц, появились гибридные механики, а данных стало так много, что их уже невозможно было разобрать руками. Вместе с этим повысился порог входа в процессы для новых сотрудников только что пришедший в команду геймдизайнер не мог ориентироваться в контенте, так как банально не знал его на уровне названий.

Нужно было глобально что-то менять.

Сначала просто хотели сэкономить немного времени на балансировке контента, а в итоге автоматизировали большинство процессов, избавились от лишней ручной работы и разгрузили сотрудников. И все это с помощью гугл-таблиц.

Из гугл-таблиц в Unity

В первую очередь стали разбираться, как упростить работу с данными и можно ли их загружать в Unity из обычных гугл-таблиц. Оказалось, можно. Это был ключевой момент и первый шаг на пути к автоматизации назвали его удаленным контролем.

Для получения данных с таблиц мы используем Google Apps Script. Первое время заводили отдельные скрипты на каждую таблицу, в которых обрабатывали данные в JSON. Затем, получая в редакторе JSON, применяли их по назначению.

Сейчас пришли к тому, что опубликовали один скрипт. С его помощью получаем сырые данные с таблиц и уже в проекте конвертируем их в необходимый формат на С#. Этот подход более быстр и удобен.

Так выглядит наш скрипт:
function doGet(e){ if (e === undefined || e.parameter === undefined) {   return FailWithMessage("nullable parameters"); } var tableId = e.parameter["table"]; var listName = e.parameter["list"]; if (listName !== undefined && listName !== "" && listName !== "null") {   var startRow = parseInt(e.parameter["startRow"]);   var startColumn = parseInt(e.parameter["startColumn"]);   var numRow = parseInt(e.parameter["numRow"]);   var numColumn = parseInt(e.parameter["numCol"]);   return GetSigleList(tableId, listName, startRow, startColumn, numRow, numColumn); } else {   return GetAllTable(tableId); }}  function GetSigleList(tableId, listName, startRow, startColumn, numRow, numColumn){ var ss = SpreadsheetApp.openById(tableId); if (ss == null) {   return FailWithMessage("table with name: " + tableId + "not found"); } var sheet = ss.getSheetByName(listName); if (sheet == null) {   return FailWithMessage("list with name: " + listName + "not found"); }  if (numRow < 1) numRow = sheet.getLastRow(); if (numColumn < 1) numColumn = sheet.getLastColumn(); var range = sheet.getRange(startRow, startColumn, numRow, numColumn); var data = range.getValues(); var str = JSON.stringify(data);  var resultObject = {   "resultCode": 2,   "message": str }; var result = JSON.stringify(resultObject); return ContentService.createTextOutput(result);}  function GetAllTable(tableId){ var ss = SpreadsheetApp.openById(tableId); if (ss == null) {   return FailWithMessage("table with name: " + tableId + "not found"); }  var result = {};  var listModes = ss.getSheets(); for(var i = 0; i< listModes.length; i++) {   var sheet = listModes[i];   var sheetName = sheet.getSheetName();     var range = sheet.getRange(1, 1, sheet.getLastRow(), sheet.getLastColumn());   var data = range.getValues();   result[sheetName] = data; }  var str = JSON.stringify(result);  var resultObject = {   "resultCode": 2,   "message": str };  var result = JSON.stringify(resultObject); return ContentService.createTextOutput(result);} function FailWithMessage(message){ var result = {   "resultCode": 1,   "message": message };   var str = JSON.stringify(result);  return ContentService.createTextOutput(str);}

Для его использования необходимо создать новый скрипт, вставить содержимое из примера, опубликовать и в разрешениях указать, что запускать могут все, даже анонимные пользователи.

После публикации получится ссылка такого формата:

https://script.google.com/macros/s/WwlCZODTDRXJaHhdjfwFRcKtHRQOHqzYisjndduZzDihMpXehLrNxdi/exec

Ее нужно использовать для запуска скрипта. Чтобы скрипт знал, с какой таблицы нужны данные, в get-запрос подставляем ID таблицы. Получить его можно из URL таблицы. Например, в https://docs.google.com/spreadsheets/d/example_habr/edit#gid=0, ID будет example_habr.

Если нужно получить данные с конкретного листа, можно в запрос добавить его название тогда данные вернутся только по нему. То же самое и с диапазоном интересующих ячеек.

Полный запрос будет выглядеть так:

https://script.google.com/macros/s/WwlCZODTDRXJaHhdjfwFRcKtHRQOHqzYisjndduZzDihMpXehLrNxdi/exec?table=example_habr&list=MyList&startRow=1&startColumn=2&numRow=10&numCol=5

У Google есть ограничения на количество запросов и время выполнения. Поэтому нельзя использовать этот инструмент, например, для подтягивание конфигов напрямую в клиент у пользователей при превышении лимита скрипт начнет выдавать ошибку.

Теперь большинство параметров контента редактируется не внутри проекта, а во вне. Движок просто получает данные из таблицы в реальном времени. Например, нужно всем пушкам добавить 5 урона: вбиваем в ячейку, протягиваем по столбцу и нажимаем загрузить. Готово все данные ушли в клиент. По сути, мы с помощью нескольких гугл-таблиц управляем всей игрой.

Сейчас таких таблиц баланса уже много, все с закрытыми доступами на нужных специалистов. Отдельно по оружию, питомцам, гаджетам, экономике уровней и другим вещам. Но принцип работы один ничего не делается по отдельности руками на клиенте.

Но мы пошли дальше.

Из Unity в гугл-таблицы

Когда пользователь играет матч, вся статистика отправляется на наш сервер: по ID игрока в базу данных сохраняется, с какой пушкой он ходил, какие результаты показал и прочее. Таких необработанных данных очень много по каждому пользователю и единице контента: киллрейты, результаты матчей, частота взятие пушек и другое. Их мы давно использовали для аналитики но все было вручную, долго и сложно.

Почему бы не использовать таблицы не просто для загрузки данных в Unity, но и в обратную для обработки собираемой статистики и метрик или поиска проблемных мест? Да и вообще для генерации самого контента.

Начали с простеньких задачек. Например, мы часто превышали лимит в 500 символов на описание апдейта в Google Play. Стор такое отклоняет, нужно переписывать и отправлять заново. Задались вопросом, а есть ли формула для подсчета символов в ячейке? Разумеется, в гугл-таблицах большой перечень базовых формул, которые можно комбинировать как угодно и решать практически любые задачи. Написали в ячейке, чтобы описание апдейта автоматически проверялось на количество символов =ДЛСТР(номер ячейки). Теперь проблемы нет.

Гугл-таблицы закрывают большинство наших потребностей. Формулы состоят из простых операторов, но сочетания такие, что иногда не помещаются на экран 27-дюймового монитора. Есть отдельные специалисты, которые их составляют, знают разные фишки, специальные округления, сложные погрешности, выборки.

В гугл-таблицах огромное количество функций, ознакомиться со всеми можно на сайте саппорта Google.

Например, решили составить коллекции для галереи оружия (это такие подборки оружия по схожим признакам: цвет, сеттинг, сезон). Чтобы составить одну коллекцию, нужно оценить визуал, смотрятся ли они вместе, схожий ли у них класс и другие детали. Для этого сделали таблицу, в которую из базы данных выгрузили список всех пушек, написали формулу и подгрузили превьюшки, с которыми можно визуально работать. А уже из таблиц по балансу подтягиваем названия, теги и остальную информацию.

В результате получили таблицу, которую можно подгрузить в любую другую и взаимодействовать с пушками наглядно они автоматом подтягиваются по тегу. Например, по тегу Weapon970 сразу подгружается ее название, превью и так далее. С этим уже можно спокойно работать.

Еще пример. Решили поменять баланс дробовиков (скорострельность, дальность и так далее). Надо понимать, что механик много, а позиций еще больше. Каждую нужно учитывать в формулах в виде отдельных коэффициентов. Геймдизайнер не может зайти и перепечатать параметры руками их придется менять у каждого дробовика, которых может быть несколько десятков.

В формулах есть множество коэффициентов. Есть даже коэффициент крутости добавляем его, если, например, текстура пушки получилась особенно красивой. В таком подходе мы уже думаем через переменные, а не через частные случаи. Уже не хочется вручную переделывать руками 40 позиций, хочется иметь один коэффициент, который сделает все сам.

В итоге таблицы экономят колоссальное количество времени. На подготовку уйдет максимум пару часов (если совсем что-то нестандартное), зато потом можно ворочать огромным количеством данных или сущностей. Вручную те же задачи могут спокойно занять неделю.

Где используем автоматизацию

Мы применяем ее практически везде, где это возможно. И всегда ищем новые способы, чтобы сделать себе жизнь проще и переложить часть работы на формулы.

Балансировка контента

Самые базовый способ применения, о котором уже упоминали выше. Так мы ищем проблемные места, добавляем новый контент, не ломая старый, нерфим или бафаем оружие и так далее.

Если есть ошибка в балансе пушки, то апдейтим ее прямо на сервере, после того, как пересчитали в таблице. Такие правки стараемся переводить в формат удаленного контроля, чтобы не выпускать отдельные патчи в сторы.

Например, если на сервере не контролируется размер обоймы, а в коде добавили лишний нолик и у пулемета стало 50 тысяч патронов без патча такое не пофиксить. Пока он выйдет, пулемет купит большинство, баланс посыпется, появится куча негатива в соцсетях. Но если сделать это на сервере, то достаточно убрать одну цифру все наладится, а игроки даже не заметят. По максимуму вводить удаленный контроль очень хорошая практика.

Генерация сущностей

Автоматизацию можно использовать не только для баланса, но и для генерации нового контента. Так, в каждом батлпассе у нас есть порядка 140 разных челленджей (например, сыграть 10 игр в определенном режиме или убить 30 противников из пистолета). Каждый раз придумывать это вручную долго и нудно, поэтому сделали генерацию. Собрали подробный список условий и прямо из гугл-таблицы создаем квесты теперь одна формула придумывает нам все задачи на каждый сезон.

Естественно, со сгенерированным пулом работает уже человек и настраивает кривую сложности. Игрок должен плавно войти в ивент, тем самым повысив конвертацию в платеж или в более длинную игровую сессию.

Подобным образом мы генерируем задачи и для клановых войн.

Пример формулы:

=ifs(I2="EndMatch";ifs(AE2<=TasksData!$O$34+TasksData!$N$34;"TeamDuel";AE2<=TasksData!$O$34+TasksData!$N$34+TasksData!$M$34;ЕСЛИ(A2=0;"TeamDuel";"Spleef");AE2<=TasksData!$O$34+TasksData!$N$34+TasksData!$M$34+TasksData!$L$34;"Duel";AE2<=TasksData!$O$34+TasksData!$N$34+TasksData!$M$34+TasksData!$L$34+TasksData!$K$34;ЕСЛИ(A2=0;"Duel";"BattleRoyale");AE2<=TasksData!$O$34+TasksData!$N$34+TasksData!$M$34+TasksData!$L$34+TasksData!$K$34+TasksData!$J$34;ЕСЛИ(A2=0;"TeamFight";"DeadlyGames");AE2<=TasksData!$O$34+TasksData!$N$34+TasksData!$M$34+TasksData!$L$34+TasksData!$K$34+TasksData!$J$34+TasksData!$I$34;"CapturePoints";AE2<=TasksData!$O$34+TasksData!$N$34+TasksData!$M$34+TasksData!$L$34+TasksData!$K$34+TasksData!$J$34+TasksData!$I$34+TasksData!$H$34;"FlagCapture";AE2<=TasksData!$O$34+TasksData!$N$34+TasksData!$M$34+TasksData!$L$34+TasksData!$K$34+TasksData!$J$34+TasksData!$I$34+TasksData!$H$34+TasksData!$G$34;"Deathmatch";AE2>TasksData!$O$34+TasksData!$N$34+TasksData!$M$34+TasksData!$L$34+TasksData!$K$34+TasksData!$J$34+TasksData!$I$34+TasksData!$H$34+TasksData!$G$34;"TeamFight"); I2="killPlayer";ifs(AE2<=TasksData!$N$35;"TeamDuel";AE2<=TasksData!$N$35+TasksData!$L$35;"Duel";AE2<=TasksData!$N$35+TasksData!$L$35+TasksData!$K$35;ЕСЛИ(A2=0;"TeamFight";"BattleRoyale");AE2<=TasksData!$N$35+TasksData!$L$35+TasksData!$K$35+TasksData!$J$35;"DeadlyGames";AE2<=TasksData!$N$35+TasksData!$L$35+TasksData!$K$35+TasksData!$J$35+TasksData!$I$35;"CapturePoints";AE2<=TasksData!$N$35+TasksData!$L$35+TasksData!$K$35+TasksData!$J$35+TasksData!$I$35+TasksData!$H$35;"FlagCapture";AE2<=TasksData!$N$35+TasksData!$L$35+TasksData!$K$35+TasksData!$J$35+TasksData!$I$35+TasksData!$H$35+TasksData!$G$35;"Deathmatch";AE2>TasksData!$N$35+TasksData!$L$35+TasksData!$K$35+TasksData!$J$35+TasksData!$I$35+TasksData!$H$35+TasksData!$G$35;"TeamFight"); I2="killPet";ifs(AE2<=TasksData!$G$36;"Deathmatch";AE2>TasksData!$G$36;"TeamFight"); I2="killPlayerThroughWall";ifs(AE2<=TasksData!$I$37;"CapturePoints";AE2<=TasksData!$I$37+TasksData!$H$37;"FlagCapture";AE2<=TasksData!$I$37+TasksData!$H$37+TasksData!$G$37;"Deathmatch";AE2>TasksData!$I$37+TasksData!$H$37+TasksData!$G$37;"TeamFight"); I2="killPlayerFlying";ifs(AE2<=TasksData!$I$38;"CapturePoints";AE2<=TasksData!$I$38+TasksData!$H$38;"FlagCapture";AE2<=TasksData!$I$38+TasksData!$H$38+TasksData!$G$38;"Deathmatch";AE2>TasksData!$I$38+TasksData!$H$38+TasksData!$G$38;"TeamFight");I2="ramEscort";"Siege";I2="escortDestroyGate";"Siege";I2="winBrNoChest";"BattleRoyale";I2="crashChest";"BattleRoyale";I2="winBrInParty";"BattleRoyale";I2="flagCapture";"FlagCapture";I2="pointCapture";"CapturePoints")

Пример таблицы с вводными для генератора:

Пример формулы (в ней представлена часть с генерацией описаний задач, Key_номер это ключи локализаций, из которых составляются задачи):

=IFS(I2="endMatch";(ЕСЛИ(T2=0;"Key_7220";"Key_7234"));I2="killPet";ЕСЛИ(W2="None";"Key_7228";"Key_7224");I2="killPlayer";ЕСЛИ(Q2=1;"Key_7227";(ЕСЛИ(W2="NONE";ЕСЛИ(R2=1;"Key_7232";ЕСЛИ(S2=1;"Key_7233";"Key_7221"));"Key_7216")));I2="killPlayerFlying";"Key_7225";I2="killPlayerThroughWall";"Key_7226";I2="ramEscort";"Key_7235";I2="escortDestroyGate";"Key_7236";I2="winBrNoChest";"Key_7229";I2="crashChest";"Key_7230";I2="winBrInParty";"Key_7231";I2="flagCapture";"Key_7237";I2="pointCapture";"Key_7238";I2="";"")

И еще более эпичная, уже проходящая через ячейки параметров и рандомайзеров:

=ifs(L3="DeadlyGames";0;L3="BattleRoyale";0;L3="TeamDuel";0;1=1;ЕСЛИ(I3="killPlayer";ifs(A3=0;ЕСЛИ(СЧЁТЕСЛИ($I$2:I2;"killPlayer")>=(TasksData!$B$34+TasksData!$B$36+TasksData!$B$38)*6;ЕСЛИ(СЧЁТЕСЛИ($I$2:I2;"killPlayer")<(TasksData!$B$34+TasksData!$B$36+TasksData!$B$38+TasksData!$B$47)*6;1;0);0);A3=1;ЕСЛИ(СЧЁТЕСЛИ($I$2:I2;"killPlayer")>=(TasksData!$B$34+TasksData!$B$36+TasksData!$B$38+TasksData!$B$47+TasksData!$B$48+TasksData!$C$34+TasksData!$C$36+TasksData!$C$38)*6;ЕСЛИ(СЧЁТЕСЛИ($I$2:I2;"killPlayer")<(TasksData!$B$34+TasksData!$B$36+TasksData!$B$38+TasksData!$C$34+TasksData!$C$36+TasksData!$C$38+TasksData!$B$47+TasksData!$B$48+TasksData!$C$47)*6;1;0);0);A3=2;ЕСЛИ(СЧЁТЕСЛИ($I$2:I2;"killPlayer")>=(TasksData!$B$34+TasksData!$B$36+TasksData!$B$38+TasksData!$B$47+TasksData!$B$48+TasksData!$C$34+TasksData!$C$36+TasksData!$C$38+TasksData!$C$47+TasksData!$C$48+TasksData!$D$34+TasksData!$D$36+TasksData!$D$38)*6;ЕСЛИ(СЧЁТЕСЛИ($I$2:I2;"killPlayer")<(TasksData!$B$34+TasksData!$B$36+TasksData!$B$38+TasksData!$B$48+TasksData!$C$34+TasksData!$C$36+TasksData!$C$38+TasksData!$D$34+TasksData!$D$36+TasksData!$D$38+TasksData!$B$47+TasksData!$C$47+TasksData!$C$48+TasksData!$D$47)*6;1;0);0));0))

Симуляция процессов

Другой пример. Добавляем в игру сундук с предметами: игрок открывает и получает приз. У сундука есть множество правил, как и что будет выпадать. Можно написать код и отдать QA-отделу, чтобы это проверить, но есть способ лучше. Прямо в гугл-таблице делаем симулятор дропа: вносим правила, условия, открываем 1000 сундуков и корректируем всю модель под нужный исход. Для этого не нужен ни код, ни программист достаточно таблицы и самой концепции.

Пример части вводных данных:

Пример использованных формул в ячейках:

=СЛУЧМЕЖДУ(1;100)
=СРЗНАЧ(13;15)*6
=СУММ(B4:F4)
=IFS($A32<=G32;"Mythic";$A32<=F32;"Legend";$A32<=E32;"Epic";$A32<=D32;"Rare";$A32<=C32;"Common")

Сами по себе формулы простые, но при правильном построении связей ячеек и порядка выполнения действий получается нужный результат.

Пример результатов дропа по номерам открытий:

Разумеется, в самом проекте все пишет программист, но проверить это можно заранее. По сути все, что есть в игре, можно симулировать в таблице. И если результаты устраивают передавать в разработку.

Воркфлоу создания таблицы

Рассказать, как именно происходит работа с данными и создание таблиц, лучше всего на примере. Допустим, мы решили выяснить, какие пушки сейчас самые популярные в игре. А для этого нужно подтянуть множество дополнительных данных.

Расскажу подробнее по шагам (цифры в примере изменены в рамках конфиденциальности):

Эти же данные можно брать из таблицы баланса. Разница в том, что таблица баланса дает актуальные параметры (и не дает метрики), а на сервере информация хранится с пометкой даты ее можно выгрузить за нужный период (и вместе с метриками).

2. Затем создается гугл-таблица, в которой будет происходить основная работа. И в нее загружается полученный CSV-файл.

3. Для удобства из другой таблицы с помощью формулы подтягиваются картинки пушек. Арты предварительно загружены на сервис для получения прямой ссылки в формате (важно именно расширение в конце ссылки):

http://адрес_сервиса/путь/номер/имя картинки.jpg

Для добавления в таблицу используем простую функцию:

=IMAGE("https://files.fm/u/wdrhemgnk#/view/special_offer_pixelman_reward_big.png")

Пример формулы для подтягивания артов с перебором:

=ЕСЛИ(ЕНД(ВПР(A4;importrange(имя_таблицы;Лист1!B:F);5;ЛОЖЬ))=ЛОЖЬ;ВПР(A4;importrange(имя_таблицы;Лист1!B:F);5;ЛОЖЬ); ЕСЛИ(ЕНД(ВПР(A4;importrange(имя_таблицы;Лист1!C:F);4;ЛОЖЬ))=ЛОЖЬ;ВПР(A4;importrange(имя_таблицы;Лист1!C:F);4;ЛОЖЬ); ЕСЛИ(ЕНД(ВПР(A4;importrange(имя_таблицы;Лист1!D:F);3;ЛОЖЬ))=ЛОЖЬ;ВПР(A4;importrange(имя_таблицы;Лист1!D:F);3;ЛОЖЬ); ЕСЛИ(ЕНД(ВПР(A4;importrange(имя_таблицы;Лист1!E:F);2;ЛОЖЬ))=ЛОЖЬ;ВПР(A4;importrange(имя_таблицы;Лист1!E:F);2;ЛОЖЬ);НИМА ТАКОГО))))

Теперь можно работать не с абстрактными строками, а наглядно. Если пушек 30 штук, можно зайти в игру и посмотреть, но когда их 700 так уже не сделаешь.

Важный момент: после подгрузки данных мы их вырезаем (ctrl+x) и вставляем без привязки к формуле (ctrl+x+v). Формулу затем удаляем, иначе после каждого обновления страницы она будет пересчитывать все строки. В данном случае более 800.

Далее одну базу можно использовать для всех задач, где требуется отображение картинок оружия.

4. При желании можно выгрузить название пушки в игровом магазине (а также все необходимые для задачи параметры, например, дополнительные свойства).

5. Также используем форматирование ячеек. Оно может выполнить множество полезных преобразований. Например, покрасить ячейки, в которых значение больше 2 или меньше 1.

В применении к данным о киллрейте пушки (соотношение числа убийств из пушки к смертям игрока с ней) видно превышение обозначенного предела, а также низкие значения, которые явно являются поводом передать эти данные в отдел балансирования.

6. Добавляем столбец с категориями оружия (у нас их 6) и прибегая к тому же условному форматированию красим каждый в свой цвет. Стало видно, что в топе нет пушек категории Special, что уже наталкивает на анализ механик этой категории оружия.

В итоге, чтобы собрать такую таблицу с категориями, свойствами, превью и прочим пришлось вытащить эту информацию из нескольких разных мест. И на это ушло около 15 минут, а не весь день. Так как формулы операций типовые, а таблицы с рендерами и данными есть уже готовые.

Теперь можно сортировать, строить графики, добавлять продажи или другую информацию, чтобы быстро и обоснованно сделать нужные выводы или проверить теории.

Для наглядности на основе данных можно построить и график. Делается это через простую операцию добавления: добавить диаграмма (сразу можно выделить нужный диапазон ячеек).

График популярности оружияГрафик популярности оружия

Жизнь после автоматизации

На самом деле сплошные профиты. Проблемы дисбаланса значительно сократились, стало проще следить за контентом и предугадывать возможные проблемы, потому что общая картина всегда перед глазами, а проблемные места подсвечиваются.

Теперь легче что-то поменять, перезалить или вообще обновить целый класс оружия, в котором 100+ позиций. Достаточно вбить новые параметры все автоматически и с учетом механик пересчитается под норму (а часть параметров пересчитаются сами под новые вводные).

Мы избавились от мелкого ручного менеджмента, освободили время сотрудников для более интересных задач, сняли дополнительную нагрузку на технический отдел и теперь программисты не отвлекаются от написания кода. И что еще важно новички в команде теперь легко вливаются в процессы и намного быстрее разбираются с проектом на реальных задачах.

Переход к автоматизации непрерывный эволюционный процесс, и во многом непаханное поле. Теперь постоянно думаем, как оптимизировать ресурсы и упростить задачи, пробуем новые варианты, формулы и всегда ищем более удобные решения. Например, сейчас работаем над добавлением всех этих процессов прямо в админку.

P.S. Данный подход меняет сам принцип работы с различными инструментами. Например, в том же Slack можно видеть BB-коды наглядно с помощью простой команды #:

Полезные ссылки

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru