Предупреждение: у нас есть цензура и предварительный отбор публикуемых материалов. Анекдоты здесь бывают... какие угодно. Если вам это не нравится, пожалуйста, покиньте сайт. 18+

История №1270509

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

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

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

Зеркало.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

В отчаянной попытке решить проблему, программисты не нашли ничего лучшего, как «заткнуть» точки пересечения координат различными непроходимыми препятствиями. Комнаты и коридоры вампирского замка заполонились стоящими в произвольных местах колоннами, шкафами, вазами с цветами и фонтанами. Такое решение хоть и не устранило проблему вампирского сумасшествия, но свело ее к допустимому минимуму...
+182
Проголосовало за – 364, против – 182
Статистика голосований по странам
Статистика голосований пользователей
Чтобы оставить комментарии, необходимо авторизоваться. За оскорбления и спам - бан.
13 комментариев, показывать
сначала новые

coodan30.11.21 10:05

Редкостный говнокод. Они хоть когда-нибудь программировать учились?

+1
ответить

mores29.11.21 01:39

Придется изучить программирование, чтобы понимать such comments

+0
ответить

Woldemars28.11.21 21:54

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

+-4
ответить

Хренонимус ➦Woldemars28.11.21 22:59

Да ладно тебе, там скорее всего Build использовался (для того времени заебись как круто и модерново), просто мальцы замудрили с картами и понатыкали зеркала там, куда их ставить не следовало (внутренние стены) вместо внешних стен, где можно создавать дубликаты комнат не портя карту ;)
Т.б. граф.дизеру не объяснили - что делать можно, а что - низзя.

+3
ответить

Chicago95 28.11.21 18:30

История очень интересная. Я ржал с самого начала и до окончания. Почему ржал? Ну, курнул и на ржав пробило. Такой вот глюк программы

+-3
ответить

Хренонимус ➦Chicago9528.11.21 23:06

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

+3
ответить

ystervark28.11.21 14:07

На первый взгляд выглядит историей из жизни долбоебов, которые
1) где-то взяли готовый движок, плохо представляя механику его работы
2) пытаются использовать его за пределами его возможностей
3) лепят костыли один на другой
4) не имеют систематически разработанной архитектуры системы, из-за чего никогда не могут предсказать последствия мелких изменений.

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

+6
ответить

Хренонимус ➦ystervark28.11.21 14:32

В случае с потерей нейтральности, странно, что не сделали отдельный класс: "похуист";

Остальное - очень похоже на ограничения движка (скажем, комнаты должны быть связаны) иначе:
В случае с координатами - вынести комнату за пределы замка, построив строение из зазеркальных комнат, которое скрыто при входе в замок и висит в воздухе;

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

+1
ответить

ystervark➦Хренонимус28.11.21 16:34

А может, движок давал ограниченные возможности изготовления новых классов.

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

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

+2
ответить

Хренонимус ➦ystervark28.11.21 18:23

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

Вспомнил, в Дюке трах был с камерами видеонаблюдения.

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

+1
ответить

ystervark➦Хренонимус29.11.21 00:00

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

А что там было с камерами? Я как-то и не помню уже, что они там были.

+2
ответить

Хренонимус ➦ystervark29.11.21 00:15

Именно: "это не баг, это фича!"
С камерами я долго копался, пока нашел.
Был такой прикол, что слизням приказано атаковать тебя в глаза (т.б. куда ты смотришь - получи слизня). Когда ты смотришь через камеру в помещение, где есть слизни - они нападают на нее, хотя видеть тебя не должны.

+1
ответить

ystervark➦Хренонимус29.11.21 00:26

Надо же, не замечал. Но и это можно объявить фичей, причем довольно забавной и интересной.

+1
ответить

Общий рейтинг комментаторов
Рейтинг стоп-листов

Рейтинг@Mail.ru