Разработчики о самых грязных программных трюках в играх

https://www.gamasutra.com/view/news/310570/Developers_share_their_most_memorable_dirty_coding_tricks.php
  • Перевод
image


Когда время заканчивается, разработчики выдохлись, а загадочные проблемы продолжают появляться, иногда требуются нестандартные решения. Когда вам любой ценой нужно завершить проект, то на кону стоит всё… В паре классических статей, изначально опубликованных в дружественном журнале Game Developer magazine, мы изучили несколько потрясающих примеров таких решений из реальной жизни. Эти нестареющие шедевры можно прочитать здесь (перевод на Хабре) и здесь.

Gamasutra ещё раз решила рассмотреть эту тему. Мы собрали со всей игровой индустрии необычные решения необычных проблем. Те, кто поделился с нами этими решениями, могут и не гордиться такими «исправлениями», но на самом деле гордиться им стоит. Им удалось выпустить игру, они ничего не испортили и, что важнее всего, никто ничего не заметил. По крайней мере, до этой статьи.

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

Если вы хотите поделиться своими удивительными решениями, придуманными для выпуска игр, то мы с радостью о них узнаем! Присылайте свои грязные трюки в Gamasutra (с темой письма «dirty coding tricks») и, возможно, они будут представлены в следующей статье.

День, когда у Super Time Force сели батарейки




Может быть, этого и незаметно, но Super Time Force едва умещалась в пределы памяти Xbox 360. Из-за функции перемотки времени нам нужно было хранить всю информацию каждого активного объекта уровня в течение всей длительности перематываемой шкалы времени. Каждый новый игрок, враг, пуля, взрыв, платформа, куча мусора и оторванная часть тела отъедала память перемотки, и эта проблема отравляла весь процесс разработки игры.

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

«Начните любой уровень. Как можно быстрее нажимайте все кнопки на контроллере в течение двух минут. Перемотайте назад и повторите это ещё двадцать раз. Память исчерпана».

Быстрый «спамминг» кнопок съедал память перемотки быстрее, чем это ожидалось от ввода пользователя. Вместо того, чтобы возвращаться в самое начало и полностью менять баланс файлов уровней и размеров буферов, мы остановились на более простом решении: распознавать длительные интервалы неразумно быстрого нажатия кнопок и немедленно самоуничтожать игрока, а затем перематывать его обратно на начало уровня. Мы «притворились», что игрок при яростном нажатии на кнопки случайно включал функцию перемотки. Теперь баг превратился в фичу.

Несколько дней спустя мы получили ещё один отчёт об ошибке:

«Начните 199X уровень 2. Пройдите уровень, взрывая всё подряд и оставляя как можно больше обломков, непрерывно стреляя из пулемёта, пока не закончится время. Перемотайте назад и повторите так ещё двадцать раз. Память исчерпана».

Предел памяти перемотки оказалось можно достичь в неприлично редком случае появления на этом конкретном уровне определённого количества пуль и взрывов, создающих обломки. И снова, вместо изменения баланса файлов уровня и размеров буферов игры мы пришли к более простой идее: когда игра приближается к пределу памяти перемотки, мы просто ставим игру на паузу, выводим на экран огромный мигающий значок «низкого заряда батареи» и изящно выкидываем игрока в меню выбора уровня.

Нет, на самом деле у контроллера не разрядился аккумулятор. Нет, мы никому ничего не объясняли. Да, отдел контроля качества принял это исправление и мы прошли сертификацию.

Кеннет Юнг, технический директор Capy Games

Дополнительный тахометр


Я работал ведущим программистом гоночной игры для PS2 и PSP, параллельно разрабатываемой для PS3 и 360.

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

Мы попробовали сузить расхождения между сборкой для QA и нашей тестовой сборкой, и обнаружили, что различия в управлении были связаны со счётчиком частоты кадров, который мы выводили в углу экрана тестовой сборки. Отключив его, как в master-сборке, которую использовал отдел контроля качества, мы действительно почувствовали, что управление ощущается немного иначе. На самом деле, оно становится лучше. Мы потратили какое-то время на слепое тестирование (закрыли ту часть экрана, на которой выводился счётчик кадров и играли со включенным и выключенным счётчиком), чтобы самим убедиться, что дело было именно в этом. Разница казалась несущественной и её сложно было распознать. Одно было очевидно — вывод частоты кадров «исправлял» проблемы с управлением.

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

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

И только во время последнего теста, накануне сертификации игры мы догадались до решения проблемы — если не до её причины. Мы выпустили игру с постоянно включенным отладочным счётчиком частоты кадров, только выводили его слегка за правой границей экрана.

Мартин Тёртон, директор Clever Beans Ltd

Унесённые бе́лками




Самым бесспорно грязным трюком, запомнившимся из разработки Titan Quest, стало управление скриптингом событий. Технология квестов/событий имела серьёзную слабость — после срабатывания действия не было никаких способов его отложить. Поэтому если мы хотели, чтобы что-то произошло через пять секунд после того, как игрок пробежал через какой-нибудь ограничивающий объём, то мы никак не могли установить задержку. Действие всегда было мгновенным.

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

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

Артур Бруно, владелец/ведущий дизайнер Crate Entertainment

Рекламофобия


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

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

Правила оценивались по рефлексии. Например, при задании правила VideoAds.IsVideoAvailable = true с помощью рефлексии вызывалось это свойство и действие выполнялось, если свойство имело значение true.

К счастью для нас, эту систему можно было запросто взломать, поэтому мы добавили новой правило VideoAds.RefreshVideos = true. Это правило никогда не было равно true (поэтому действие никогда не выполнялось), но оно вызывало код, обновляющий видео, что позволило нам «заставить» систему использовать примитивный механизм исполнения удалённого кода. Проблема решена!

Лиор Тал, CEO Cyanogen

И… снято!


Мы работали над серьёзным обновлением для игры под Android за две недели до «выхода на золото». Отдел контроля качества сообщил нам, что на некоторых случайных устройствах после воспроизведения катсцены происходит сбой. Мой коллега потратил неделю, пытаясь изолировать ошибку или выяснить причину. Мы так её и не нашли. Но мы обнаружили, что при нажатии кнопки «назад» для пропуска видео сбой не происходит. Наш грязный маленький трюк состоял в том, чтобы поставить в катсцену таймер и за одну секунду до её завершения симулировать нажатие кнопки «назад». Мы использовали его как временное решение проблемы. Шесть месяцев спустя это «временное решение» по-прежнему было в коде.

Марлон Рувалкаба Муньос, Karaokulta

Чёрный лёд, белый шум




При работе над Black Ice я хотел создать небо, которое выглядело бы как бесконечная комната (как на скриншоте), но расположение сотен объектов в небе снижало производительность, а зеркала в играх с 90-х годов были не очень жизнеспособны. Поэтому я решил реализовать это с помощью частиц. Всё было довольно просто — я написал скрипт, чтобы расположить их в мире, но тут возникла проблема: частицы исчезали, когда игрок отворачивался от точки начала координат мира.

Мне понадобилось какое-то время на то, чтобы выяснить, что legacy-система частиц Unity отключала все частицы в системе, когда невидимый эмиттер частиц находился за пределами обзора камеры. (Все ведь знают, что такое отсечение по пирамиде видимости?) Я достаточно долго боролся с проблемой, но однажды ко мне пришло решение — я присоединил эмиттер к лицу игрока, примерно на шесть дюймов ниже. Таким образом игрок никак не мог бы отвернуться от эмиттера, в какую бы сторону не смотрел! Мне пришлось изменять испускание частиц на основе положения в мире и обновлять их при движении игрока, но это сработало!

На GIF ниже показано, как это выглядит в редакторе и в игре.

В редакторе




В игре


Гарретт Купер, создатель игр, Super Duper Game Company

Отправляйся прямиком в тюрьму


Когда я работал в Backbone Entertainment, мы с Кевином Уилсоном работали над крайне напряжённым проектом по переносу аркадных игр Midway на PSN. Это было самое начало эпохи PS3. Кажется, среди первых одиннадцати доступных для загрузки игр были наши: Joust, Championship Sprint, Rampage World Tour, Rampart и Mortal Kombat 2, и ещё какая-то подобная дичь.

Backbone ранее выпустила эти игры в XBox Live Arcade, но они были разработаны не очень кроссплатформенно. Проект необходимо было сворачивать буквально за несколько недель, поэтому мы сделали то, что сделал бы любой с такой временно́й нагрузкой: частично реализовали Direct X на PS3. Последнюю неделю проекта я потратил на сокрытие следов.

Иэн Шерман, программист Other Ocean

DLL-it yourself


Клиент, очень озабоченный сокрытием своего «ноу-хау», передал нам несколько DLL только для наших целевых консольных платформ, то есть библиотеки в сущности оказались «чёрным ящиком». Нам упорно не давали никаких библиотек для PC, как бы мы ни упрашивали. Весь фронтэнд игры выполнялся на PC, а в коде была только заготовка движка, достаточная для запуска геймплея, но мы не могли протестировать работу настоящей игры на PC, и это не устраивало нас по множеству причин.

Мы прошли таким образом весь цикл разработки для PS3/X360. Затем, для следующей итерации игры мы перешли на Xbox One и PS4, получив обновлённые версии библиотек движка, но по-прежнему без версии для PC, что очень осложнило нашу работу, особенно на PS4.

Но случилось волшебство — библиотеки для Xbox One на самом деле оказались полностью рабочим 64-битным кодом для PC, и их можно было просто подключить к исполняемому файлу Windows. Достаточно было иметь PC с довольно новым ЦП, содержавшим те же расширения наборов инструкций, что и ЦП на Xbox. Мы радовались, как дети, когда эту систему удалось заставить работать.

Эпилог — на следующем цикле, когда мы делали версию для Steam, клиенты наконец-то расщедрились на настоящую библиотеку для PC, поэтому хак оказался ненужным.

Дэн Филнер

Мост слишком далеко?




Это больше похоже на kit bash (прим. пер.: создание чего-то нового из стандартных заготовок, в том числе в трёхмерном моделировании), чем на программный трюк, но когда я начал работу над Grim Dawn, то практически работал в одиночку. Было несколько знакомых, которые помогали мне в свободное время (в основном бывшие коллеги по Iron Lore), но в полную силу работал я один. Несколько месяцев спустя ко мне присоединился программист, но до выхода на Kickstarter у нас не было собственного художника. В результате я потратил часть личных сбережений на найм художника, и одним из первых созданных мной объектов был деревянный мост. Он состоял из плоских деревянных досок, длинных скруглённых балок и металлических железнодорожных костылей, скрепляющих древесину, как гвозди.

Иногда в команду приходили волонтёры, оказывались слишком занятыми работой и семьёй, и потом пропадали. Я дошёл до этапа, на котором появлялось не так много новой графики. Я не художник, мои навыки ограничены созданием текстур из фотографий и простейшими основами «моделирования». На самом деле, у меня не было особого выбора, кроме как с переменным успехом изменять готовые объекты и исправлять UV-карты.

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

Артур Бруно, владелец/ведущий дизайнер Crate Entertainment

Звучит неплохо!




Работая над Mega Man Legacy Collection для 3DS, я обнаружил «баг» со звуком, который никак не мог отследить. Любой первый воспроизводимый звук или искажался, или проигрывался неправильно.

Я сам писал слой воспроизведения звука, но он был основан на звуковом API Nintendo для 3DS. Система воспроизведения должна была поддерживать непрерывное потоковое проигрывание таких вещей, как фоновая музыка или эмуляция звука NES (последнюю писал не я), плюс короткие небольшие единоразовые звуки для таких действий, как эффекты UI и демонстрация начального логотипа.

Каждый из звуковых «каналов» 3DS передавал с собой структуру данных, содержащую различные флаги и информацию для отслеживания текущего состояния. Одним из них флаг, определяющий, является ли канал активным или воспроизводящимся. В официальной документации Nintendo говорилось, что флаг имеет значение true, если канал что-нибудь воспроизводит, и false в противном случае.

С этим у меня появилась пара багов, корневую причину которых мне не удалось найти из-за нехватки времени. Говоря попросту, в девяти из десяти случаев при запуске игры мелодия, сопровождавшая логотип Digital Eclipse [разработчика коллекции игр] по-разному искажалась — она заикалась или вообще не воспроизводилась. Это был самый первый звук в игре, и я выяснил, что ошибка всегда происходит с первым воспроизводимым звуком — последующие звуки проигрываются без проблем.

Когда я принялся за отладку, то выяснилось, что в некоторых случаях этот флаг «воспроизведения» имел значение true, даже когда ничего не проигрывалось! Очевидно было, что мы не можем выпустить проект в таком состоянии, а у меня уже закончились все умные идеи. Так каким же стало моё решение?

При загрузке игры, перед воспроизведением этой первой мелодии, я проигрывал секунду тишины. И в таком состоянии проект был выпущен.

Кит Кэйзершот, программист Digital Eclipse
Поделиться публикацией
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

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


    Когда закостылил — и тебя повысили! *deal with it*
    • +5
      ну, с точки зрения продукта он все правильно сделал. Повысили его же не по технической лестнице, а по продуктовой
      • +3
        Когда делаешь игру — в срок выпущенный проект важнее идеальной архитектуры. Например, в недавно вышедшей игре «Distrust», к разработке которой я имею непосредственное отношение, имеется очень много таких «хаков», когда дизайнеры уровней придумывают хитрые системы из объектов, только чтобы реализовать свою логику, не отвлекая программистов, загруженных исправлением багов перед надвигающимся релизом. В этой игре, чтобы перейти на другой этап (перейти в другую зону), вам нужно выполнить квест, который уникален для каждой зоны. Например, дверь, которую нужно заминировать, на самом деле является печью, в которую мы «заправляем» топливо, когда устанавливаем бомбу. На этапе прототипирования квеста это возможно было сделать без программистов, с использованием уже готовых объектов. Тем не менее, мы не стали это трогать — оно работало и было протестировано, а мы просто добавили визуализацию «топлива» в виде таймера по специальной галочке внутри печи. Или, например, история про дверь с кодовым замком. Сначала мы делали квест с разорванным листом, на фрагментах которого написаны цифры кода, мы генерировали их в специальных местах, игрок собирал их все, узнавая код целиком. Но потом придумали квест, в котором эти листочки не требовались, т.к. игрок узнавал код из компьютера (или записки), тогда пришлось сгенерировать в зоне предмет, в котором «хранился» код, но для игрока этот предмет был бесполезен. Еще интересным примером может служить сама бомба, которая является таким же кодом. Сборка этой бомбы выглядела в прототипе как набор кода на домофоне, который уже был реализован. А генерируется листочек для этого кода внутри стенда с рецептом бомбы, только его невозможно оттуда достать, т.к. он находится в скрытом состоянии стенда, в которое никак нельзя переключить. И этот список можно продолжать до бесконечности. Конечно, если бы мы, как разработчики, заранее знали, какие квесты будут, мы бы все продумали. Но нам никто не расскзал, потому что разработка игры — процесс творческий, где все меняется каждый день.
        • –12
          потому что разработка игры — процесс творческий, где все меняется каждый день
          Диздок для слабаков, да?
          • +10
            Сразу видно, что вы не написали ни одного диздока, по которому потом делали игру.
            • –6
              Сразу видно, что между разработчиками и писателями плохо налажен контакт.
      • +17
        image
        Поезд в fallout 3 на самом деле не поезд, а шляпа NPC
      • +19
        Классика с баша:

        Ошибка: робот погибает при попадании в него гранаты (именно от попадания, а не от взрыва) Д — дизайнер, П — программист.
        Д: программисты всё сломали! почему так получается?!
        П: естественно так получается! потому, что у гранаты масса 100 кг! зачем вы это сделали?
        Д: да?! а чтобы граната в воде тонула!
        П: а почему она с нормальной массой не тонет?
        Д: а потому что у воды плотность большая! (прим.: больше, чем у ртути)
        П: а почему плотность такая большая?!
        Д: а чтобы ящики деревянные плавали!
        П: а почему они иначе не плавают?!
        Д: а потому что у них масса 50 кг!
        П: а зачем такая масса?!
        Д: а иначе они некрасиво разваливаются!
        • 0
          В HL2 эту проблему решили с помощью «кинематографиеской физики». ХЗ как они это сделали, но выглядит норм.
          • 0
            В момент когда ящик получает повреждение изменить массу, не? Помнится мне при некотором воздействии ящики неплохо так дрыгались.
          • 0
            Черт, мне кажется что-то такое есть и в UrbanTerror(на движке quake). Там если в тебя попали гранатой, то уже не отскочить
            • –1
              Это идеальный пример применения техники «пять почему». Спасибо.
            • 0
              мне отчаянно было нужно больше объектов окружения, чтобы можно было продвигаться дальше в построении мира. Поэтому мне пришлось открыть в редакторе этот мост и использовать его отдельные части для создания новых деревянных строений. В результате у меня получилось из него достаточно много объектов. Другие мосты, выложенные из досок тропинки, входы в дома, заборы, кучи мусора, виселица, которую видно на начальном экране, указатели, стол, крыши домов…

              Сам так поступил!
              Была модель Железного Орла оставшаяся от дизайнера.
              image


              Которую я использовал в других моделях:
              image image
              (подсказка: орлы на флагах)

              • +2
                Это прекрасно, спасибо.

                Кто-рассказывал, что игрок в шутере вырос как часть дробовика. То есть основной объект — пушка, а всё остально нарастало вокруг.
                • +7
                  нам нужно было хранить всю информацию каждого активного объекта уровня в течение всей длительности перематываемой шкалы времени. Каждый новый игрок, враг, пуля, взрыв, платформа, куча мусора и оторванная часть тела отъедала память перемотки,

                  Просто ужас!
                  Они не думали сохранять только действия игрока?
                  Все враги, пули, взрывы и кучи мусора прекрасно восстанавливаются из базового seed'a…
                  • 0
                    а у них небось качественый рандом прикручен
                    • +12
                      Значит, надо было использовать детерминированный ГСЧ.

                    • +1

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

                      • 0
                        У них скорее всего пишутся только изменения свойств(положение, поворот и т.д.) объектов. Если писать информацию полностью, совсем накладно получается.
                        Фикс все равно не очень красивый. Непонятно почему нельзя было ограничить размер буфера для хранения изменений.
                        • 0
                          Непонятно почему нельзя было ограничить размер буфера для хранения изменений.

                          Это не даст перемотать до начала уровня.
                    • +13
                      Мы «притворились», что игрок при яростном нажатии на кнопки случайно включал функцию перемотки.
                      Когда игра приближается к пределу памяти перемотки, мы просто ставим игру на паузу, выводим на экран огромный мигающий значок «низкого заряда батареи» и изящно выкидываем игрока в меню выбора уровня.
                      Поразительно некрасивая история. Вместо исправления бага пользователя мало того, что выкидывают из игры, так еще и делают вид что это он сам виноват.

                      Почему на воспроизведение бага влияет количество повторов? После обратной перемотки память, что, не освобождается?
                      • +3
                        Игрок в такую ситуацию не попадет. Это искусственная ситуация.
                        Падение ПО недопустимо даже в искусственных ситуациях. Поэтому им и дали фидбэк и потребовали исправлять.
                        • +5
                          Похожую историю я слышал. Консольная разработка. Падает очень редко и неуловимо. Сделали, чтобы обработчик page fault запускал какую-то примитивную игру, типа тетриса или пакмана. Отделу тестирования сказали, что это пасхалка, только её трудно выбить. QA издателя игру одобрил.
                    • +6
                      Спасибо! И как тут не вспомнить классику жанра.
                      • +31

                        Моя любимая история геймдева про Блицкриг 2, уж не знаю, правда или нет. Читал когда-то давно в каком-то бумажном журнале, недавно нашёл в сети.


                        Ну, сделали и мы в Блицкриге эту самую ракету. Как и немцы, сделали ее уже ближе к концу проекта и соорудили на базе объекта "самолет". Но программисты несколько схалтурили и не пооткручивали у бывшего самолета подозрительную для баллистической ракеты функциональность. Оказалость, что если во время полета к цели начинал идти дождь или снег, то во-первых ракета говорила человеческим голосом "Fliege zuruck"(нем. лечу назад), а во-вторых разворачивалась и летела обратно на базу. Фигли там, погода то нелетная.

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

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

                        И вот моё самое любимое:


                        Со свиньями был связан, кстати, еще один баг, из-за которого игра падала. В какой-то момент программисты что-то такое там подкрутили и свиньи перестали быть нейтральными, а обрели возможность принадлежать какому-то игроку. Управлять ими было нельзя, но формально они могли быть "наши" или "ненаши". Так вот свиньи роняли игру. Потому что видя неприятеля, патриотичная хавронья хотела дать врагу отпор и лезла за оружием, которого у нее естественно не было. Если мне не изменяет память, программисты исправили баг, просто выдав свинье пистолет Люгер без патронов. Визуально это никак не видно, но формально, теперь, видя врага, она лезет за оружием, видит что патронов нет и на этом успокаивается.
                        • +3
                          Интересно. Выше такая же ссылка, только без цитат, а рейтинг больше у второго коммента. Видимо лень людям по ссылкам ходить)
                          • +3
                            Все справедливо) Человек работу сделал за читателя — законспектировал статью. Получил плюсы.
                          • 0
                            Визуально это никак не видно, но формально, теперь, видя врага, она лезет за оружием, видит что патронов нет и на этом успокаивается.

                            А подобрать патроны на поле боя? Было бы феерично.
                            • 0
                              Насколько я знаю, в блитскриге (и играх на его движке, типа серии игр Caribbean Crisis) механ не предусматривает поднятие боеприпасов с трупов/остовов (там патроны/снаряды и т.п. раздают специально обученые юниты, которые вылезают из специального грузовика, который может загружать боеприпасы со склада и подвозить куда надо)
                              • 0
                                Понятно.
                                А специально обученые юниты из специального грузовика из каких-то особенных чувств не выдают боеприпасы хавроньям или из простой вредности характера?
                                • 0
                                  Да наверняка просто максимальное количество патронов поставили нулевым.
                              • 0
                                Где-то была такая тема с собаками. Мол у собак было оружие «кусалка», у которого тоже были патроны т.к. игровая механика не предусматривала бесконечного оружия ближнего боя. В итоге у собак могли кончиться патроны и они переставали кусаться. Но стоило им пробежать мимо ящика патронов как они начинали кусаться снова.
                                • 0
                                  ну так это в этой же игре и по ссылке можно прочитать ;)
                                  • 0

                                    В Арме (дейЗ) одно время топор перезаряжался. А у ее идейного предка — флешпоинта — из-за хардкода были велосипеды с дымом из несуществующей выхлопной трубы.

                                • +3
                                  Хм. А ведь если бы вместо Люгера свиньям выдали специальный пистолет «БезОружия» — то вместо некрасивого костыля получился бы паттерн Null Object.
                                  • –1
                                    его еще писать надо. а люгер уже есть, осталось патроны отломать
                                  • +3
                                    «Матерый хряк попался! Глаз подбил и кортик отобрал»
                                    • –1
                                      Свиненок твой мутантом оказался. Глаз мне подбил и кортичек отобрал!
                                  • +2

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


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

                                    • 0

                                      А создатели первой карты Mission: Dead City раскидали по карте невидимые деревья для защиты от мапхака. При клике на такое дерево — вылет.


                                      Но они забыли что некоторым юнитам сами же выдали способность видеть невидимых юнитов...

                                      • 0

                                        Насколько я помню возможности старки там не "невидимые деревья" а скорее всего нетипичные объекты которые крашили игру, надо бы карту в эдиторе потыкать — тогда будет понятнее.
                                        Вообще кастомные редакторы карт позволяли творить совсем безумные вещи — красить карту потайлово, ставить спеллы прямо на карте, использовать объекты из других ландшафтов (что как-раз могло вышибать игру), ставить недоделанных/декоративных юнитов, накручивать юнитам ХП больше максимального из-за чего их "картинка с повреждениями" из зеленой уходила в фиолетовую гамму, использовать 255 игроков, переназначать игрокам цвета даже за пределами 8 стандартных и 9-15 особенных (белый и коричневый цвета как помнится замещали друг друга на снежных картах) и что самое классное — ставить здания и юнитов не по сетке. И чуть не забыл — использовать непечатные спец-символу что-бы перекрашивать текст, даже в именах юнитов.

                                        • 0

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

                                          • 0

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

                                            • 0

                                              А разница? Суть в том, что защита от читеров сделанная через костыль срабатывала в основном на честных игроках...

                                      • 0

                                        Прямо вспомнил кучу всякого колхоза, что делалось в модмейкинге warcraft 3:
                                        Из-за ограниченности инструментов (или сложности реализации определенных моментов) можно вспомнить например:
                                        1) Нужен полноэкранный интерфейс рюкзака, карты, ещё чего-либо? Делаем декорации с видом рамок интерфейса, всех нужных кнопок. Размещаем на карте. При обращении к этому условному рюкзаку ставим камеру вертикально над нашими декорациями (и закрепляем ее, чтобы подвох не был заметен). Нужна кнопка на интерфейсе? Ставим юнита в позицию кнопки, при клике по ней отлавливаем событие выделения. (выделение незаметно убираем).
                                        Вон он и интерфейс, который обыватель посчитает простым.
                                        Такая штука вроде dgui называлась (decoration gui)
                                        2) Делаем античит. isedeadpeople? (полный обзор карты). Как и в примере выше, наш невидимый невыделяемый юнит убивает вражеского на горке и засчитываем поражение. whosyourdaddy? (урон х100 и неуязвимость). Другой наш невидимый юнит атакует вражеского, у которого регенерация покрывает урон, но стоит нам его убить с уроном х100 — поражение. thereisnospoon? (мана на способности не тратится). Теперь уже нашего юнита бьют, но он имеет способность исцеления, периодически расходуя свою ману. Неожиданно у него полная мана в связи с отсутствием трат? — поражение (тут же и отлавливается неуязвимость, когда у юнита становится полный запас хп.
                                        3) Хотим, чтобы наш "фаерболл" двигался по спирали? Невидимый юнит с моделью эффекта поможет нам, стандартные эффекты такого просто не умеют.
                                        4) Ограничение движка по скорости бега — 522. Хотим больше — двигаем юнита по координатам, включая ускоренную анимацию бега.
                                        5) Все касты способностей с задержками или иными условиями — те же невидимые юниты (dummy cast)

                                        • 0
                                          А зачем было колхозить таймеры, если они и так поддерживались нативно в редакторе? Хоть на экран выводи.
                                          • 0

                                            Так-как скрипты не функции а "события" — физический таймер позволял делать систему гораздо гибче (запустить в таймер второго юнита, запустить в таймер более быстрого юнита итд).


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

                                        • 0
                                          мини-хак — в одной игрушке под 3DS не получалось сделать корректный возврат в главное меню, уже не помню причины, поэтому за недостатком времени на дебаг просто прибивали всю игру целиком и стартовали заново, оставляя флаг «скипнуть легал скрин».
                                          • +1
                                            Написать GAPI прослойку которая выглядит как DirectX — это не то что не грязный хак, это вообще не хак.
                                            Вообще, вся кроссплатформа строится на создании универсальных интерфейсов, которые наружу светятся как одно, а на каждой платформе реализуются по своему. Здесь просто ребята выбрали в качестве высокгоуровневого интерфейса DirectX, потому что игра уже была написана с учетом такого интерфейса.

                                            А в остальном, за многие хаки надо бить ногами.
                                            Если у вас есть баг, который неизвестно откуда берется и убирается совершенно левым костылем — у вас в коде где-то серьезная беда. Например, запись по не валидному указателю.
                                            Маскировать такую ошибку — это очень и очень плохо. Потому что, вполне возможно, что у вас половина открытых багов в багтрэкере — результат этой ошибки. А вы, вместо того, чтобы использовать хорошо воспроизводимую ситуация для отлова ошибки — просто её замаскировали. Но запись в левый указатель никуда не делась! И она сломает вам еще что-то! Но у вас уже не будет возможности это отловить!
                                            Не удивительно, что сейчас игры релизятся в стадии беты. Закрыли что смогли недохаками, а остальное оставили, авось игрок и так купит.
                                            • 0
                                              Кто бы рассказал как появился «баг с драконами и жабками» в первом Старкрафте. Видимо ведь тоже какой-то костыль пытались всунуть.
                                              • +1

                                                А что за баг? Расскажите пожалуйста!

                                                • 0
                                                  Там можно было в обход игрового процесса из жабок делать сразу муталисков минуя путь дракончиков. Давно дело было. Могу ошибаться в деталях. Суть в том, что надо было быстро нажать определенные сочетания клавиш. Как-то было связано с возможностью биндить группы на кнопки 1-9.
                                                  • 0
                                                    Э… а кто такие жабки и дракончики? Сколько помню, муталиски всегда делались из личинок, а одну стадию.
                                                    • 0
                                                      Жабки — зерлинги.
                                                      Дракончики — муталиски, да.
                                                      Из муталисков делались утюги, но с багом их можно было делать в обход муталисков. И летали они со скоростью зерлингов.
                                                      • +3

                                                        Вроде как там не зерлинги были, а гидра, которую морфили в люркеров, но личинка получалась летучая и из неё вылуплялись guardians (которые не могли атаковать, т.к. они "типа" незакопанные люркеры). А если отменить морфинг, получались как раз таки муталиски.
                                                        Я про это читал, но повторить не удавалось, хотя даже специально накатывал старые версии до патчей.
                                                        P.S. Этот сленг с жабками хоть кто-то кроме вас знает? :)

                                                        • 0
                                                          зерлинги — линги — мясо
                                                          муталиски — муты
                                                          — какой-то такой был слег во времена моей старкрафтовой молодости.
                                                  • 0
                                                    Вот тут много инфы есть, но конкретно бага про зерлингов я не нашёл почему-то. Может из-за того что читал по диагонали. wiki.teamliquid.net/starcraft/Bugs
                                                • +1
                                                  Очень мне нравится история про две полоски на самолетах «Зеро» с авианосца «Дзуйкаку».
                                                  • 0
                                                    Странная какая-то история если начать думать. Вырезать полоски из текстуры брони эсминца — пожалуйста, а убрать коллизию из свойств материала — видите ли тяжело…
                                                    • 0
                                                      потому что это не реальная история, а сказка
                                                  • +1
                                                    Из заглушек зон, в которые игроку рано, в виде слишком сильных мобов, получился отличный челлендж-режим к «Проклятым землям» — «Геноцид».
                                                    • +2
                                                      Был у меня метод, аналогичный белкам. Называется розовый стул.
                                                      Началось всё в далёком 2010-м, когда начал использовать его для тестирования алгоритмов. Настоящих моделей ещё не подогнали — а тестировать на чём-то надо. Взял из имевшегося набора стул и напиливал на него сценарии и скрипты. Розовым его сделал потому что цвет выделяется — не перепутать с обычным стулом.
                                                      В итоге на этих розовых стульях отработали кучу алгоритмов — путешествие стула во времени, смена id листа стула, бег стула за игроком, гуляющая походка стула, стул-полтергейст управляющий коллизиями, алгоритм спауна врагов-стульев…
                                                      В итоге поигрались со стульями и забыли на пару лет.
                                                      Потом обратился ко мне товарищ — надо, мол, чтобы монстр за игроком шёл и постепенно нагонял, с регулируемой манёвренностью, чтобы упетлять можно было, помоги. Скинул ему тестовый розовый стул.
                                                      В оригинальном движке с игроком много хитростей было (его как отдельного объекта вообще не было), так что логика поведения была сложноватой — разбираться он не стал. Движок не давал сделать модельку невидимой, потому в итоге ребята просто сделали для монстра модель побольше. Ну а внутри у него — розовый стул, который всем заправляет. По идее, если теперь «залипнуть» в текстуру монстра, внутри игрок увидит стул. Но такого не бывает, поскольку коллизия с монстром мгновенно убивает. Идеальный костыль.
                                                      • 0
                                                        Может быть, этого и незаметно, но Super Time Force едва умещалась в пределы памяти Xbox 360. Из-за функции перемотки времени нам нужно было хранить всю информацию каждого активного объекта уровня в течение всей длительности перематываемой шкалы времени.
                                                        Не знаю деталей технической реализации, но возможно, что их механизм хранения перемотки не самый оптимальный. В любом случае, если кому захочется реализовать нечто подобное, рекомендую на эту тему доклад Jonathan Blow о его реализации перемотки времени в Braid (вышла на XBox360 в том числе): GDC Vault — The Implementation of Rewind in Braid

                                                        Вкратце: необходимо хранить изначальное положение всех объектов, хранить события создания и уничтожения объектов, хранить дельты только для объектов, изменивших своё положение. Это сразу отсекает необходимость сохранять статичные объекты мира, а также те, которые прекратили своё движение (например, разлетевшиеся осколки, которые упали и лежат неподвижно).

                                                        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.