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


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

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

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


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

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

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

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

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

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

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

Почему на воспроизведение бага влияет количество повторов? После обратной перемотки память, что, не освобождается?
Игрок в такую ситуацию не попадет. Это искусственная ситуация.
Падение ПО недопустимо даже в искусственных ситуациях. Поэтому им и дали фидбэк и потребовали исправлять.
Похожую историю я слышал. Консольная разработка. Падает очень редко и неуловимо. Сделали, чтобы обработчик page fault запускал какую-то примитивную игру, типа тетриса или пакмана. Отделу тестирования сказали, что это пасхалка, только её трудно выбить. QA издателя игру одобрил.
В игру Sonic 3D Blast на Sega MD/Genesis на обработчик исключений (в т.ч. отказов памяти) повесили якобы «секретное» меню выбора уровней.

А в Зельду на SNES на такой же обработчик повесили секретную комнату с рупиями. :D

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


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

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

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

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


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

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

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

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

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


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

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


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

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

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

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

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

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

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

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


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

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

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

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

зерлинги — линги — мясо
муталиски — муты
— какой-то такой был слег во времена моей старкрафтовой молодости.
UFO landed and left these words here
Странная какая-то история если начать думать. Вырезать полоски из текстуры брони эсминца — пожалуйста, а убрать коллизию из свойств материала — видите ли тяжело…
Из заглушек зон, в которые игроку рано, в виде слишком сильных мобов, получился отличный челлендж-режим к «Проклятым землям» — «Геноцид».
Был у меня метод, аналогичный белкам. Называется розовый стул.
Началось всё в далёком 2010-м, когда начал использовать его для тестирования алгоритмов. Настоящих моделей ещё не подогнали — а тестировать на чём-то надо. Взял из имевшегося набора стул и напиливал на него сценарии и скрипты. Розовым его сделал потому что цвет выделяется — не перепутать с обычным стулом.
В итоге на этих розовых стульях отработали кучу алгоритмов — путешествие стула во времени, смена id листа стула, бег стула за игроком, гуляющая походка стула, стул-полтергейст управляющий коллизиями, алгоритм спауна врагов-стульев…
В итоге поигрались со стульями и забыли на пару лет.
Потом обратился ко мне товарищ — надо, мол, чтобы монстр за игроком шёл и постепенно нагонял, с регулируемой манёвренностью, чтобы упетлять можно было, помоги. Скинул ему тестовый розовый стул.
В оригинальном движке с игроком много хитростей было (его как отдельного объекта вообще не было), так что логика поведения была сложноватой — разбираться он не стал. Движок не давал сделать модельку невидимой, потому в итоге ребята просто сделали для монстра модель побольше. Ну а внутри у него — розовый стул, который всем заправляет. По идее, если теперь «залипнуть» в текстуру монстра, внутри игрок увидит стул. Но такого не бывает, поскольку коллизия с монстром мгновенно убивает. Идеальный костыль.
Может быть, этого и незаметно, но Super Time Force едва умещалась в пределы памяти Xbox 360. Из-за функции перемотки времени нам нужно было хранить всю информацию каждого активного объекта уровня в течение всей длительности перематываемой шкалы времени.
Не знаю деталей технической реализации, но возможно, что их механизм хранения перемотки не самый оптимальный. В любом случае, если кому захочется реализовать нечто подобное, рекомендую на эту тему доклад Jonathan Blow о его реализации перемотки времени в Braid (вышла на XBox360 в том числе): GDC Vault — The Implementation of Rewind in Braid

Вкратце: необходимо хранить изначальное положение всех объектов, хранить события создания и уничтожения объектов, хранить дельты только для объектов, изменивших своё положение. Это сразу отсекает необходимость сохранять статичные объекты мира, а также те, которые прекратили своё движение (например, разлетевшиеся осколки, которые упали и лежат неподвижно).
Only those users with full accounts are able to leave comments. Log in, please.