Особенности программирования зеркал, или страх и паника в вампирском замке

19
Особенности програмирования зеркал, или страх и паника в вампирском замке

Особенности программирования зеркал, или страх и паника в вампирском замке

Содержание:

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

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

Зеркало.

Огромное такое зеркало во всю стену, которое висело в холле замка. Программисты недовольно ворчали – мол, зачем оно вампирам, они ж не отражаются – но, поворчав, все же согласились…

Поскольку это были 90-ые, то создавать зеркала в видеоиграх приходилось дедовским методом: неразрушимая прозрачная стена, по ту сторону которой точно такая же комната. Когда игрок входил в холл, по ту сторону зеркала немедленно генерировалась его точная копия, повторяющая все его движения. Тяжело, занудно, объемно, но работало. А в данной ситуации даже и хорошо: поскольку вампиры в зеркале отражаться не должны, то и можно было ограничиться одной лишь копией игрока. Выходило атмосферно и даже где-то изящно.

ЗАЗЕРКАЛЬНЫЙ ВОР

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

И тут возникла проблема.

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

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

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

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

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

АГРЕССИВНОЕ ЗАЗЕРКАЛЬЕ

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

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

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

Столкнувшись с таким сбоем, программа повторения действий игрока зацикливалась и останавливалась. И поскольку свято место пусто не бывает — на ее место подключался «обычный» набор действий для монстра. Зазеркальный двойник внезапно обнаруживал, что он может двигаться, что он очень не любит игрока, и должен пытаться его убить.

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

И все стало еще хуже.

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

Оказалось, что все дело было в суб-категориях, деливших нейтралы на группы. В своей субкатегории, двойник должен был быть одним-единственным. Но из-за небольшой ошибки, его «напарниками» по субкатегории оказались… разрушаемые чучела-мишени на стрельбище в начале игры. Атаки на мишени в начале игры настраивали против игрока всю суб-категорию, и к моменту появления зазеркального двойника, тот уже пылал мстительной яростью и мечтал поквитаться за невинно погубленных соломенных братьев. А поскольку ошибка была в мишенях, то, естественно, никакое исследование кода двойника ее не выявляло…

Эту ошибку удалось исправить легко, но вскоре нашлась еще одна: некоторые виды атак (проклятия и т.д.) действовали на всех в пределах видимости, и задевали и двойника. Который после этого терял свой «нейтралитет» и рьяно выступал против обидчика из-за прозрачной стены. Но так как проклятия были в игре вещью редкой, то программисты просто махнули на это рукой, и решили выдать баг за фичу: каждый раз, когда нейтральность двойника нарушалась, игра выводила сообщение «ПОХОЖЕ, ЭТО НЕ ПРОСТО ЗЕРКАЛО…»

ЗАЗЕРКАЛЬНАЯ ГЕОМЕТРИЯ

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

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

К сожалению, координатную систему они об этом предупредить забыли.

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

В деталях, все это выглядело примерно так: монстр-вампир видел персонажа, и начинал двигаться к нему. Программа приступала к просчету оптимального — кратчайшего — пути вампира, и в какой-то точке натыкалась на двойные, накладывающиеся координаты, согласно которым вампир должен был оказаться в комнате на другом конце замка. Такой путь явно не был оптимальным, программа пыталась изыскать новый, но поскольку вампир уже довольно слабо понимал, где он находится, результаты… как правило удручали. А то и пугали.

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

В отчаянной попытке решить проблему, программисты не нашли ничего лучшего, как «заткнуть» точки пересечения координат различными непроходимыми препятствиями. Комнаты и коридоры вампирского замка заполонились стоящими в произвольных местах колоннами, шкафами, вазами с цветами и фонтанами. Такое решение хоть и не устранило проблему вампирского сумасшествия, но свело ее к допустимому минимуму…

источник: https://fonzeppelin.livejournal.com/199872.html

Подписаться
Уведомить о
guest

0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии
Альтернативная История
Logo
Register New Account