Предупреждение: байка не моя, рассказали англоязычные знакомые. Перевел так, как понял. За достоверность, точность и правильность изложения не ручаюсь.
Давным-давно, а точнее в конце 2000-ых, некая небольшая западная компания делала игру. Вдохновленные Deux Ex, они замахнулись на недалекое киберпанковое будущее, большие локации с элементами открытого мира, возможность кооперативного прохождения… в общем, вполне естественно масштаб проекта быстро превысил их возможности, и где-то на стадии пре-беты разработка затухла.
Но, к чести разработчиков, до состояния в основном работоспособного прототипа они игру довели. И начали ее тестировать. И нашли, понятное дело, кучу глюков и багов, многое из задуманного не работало как предполагалось, и список необходимых доработок рос как на дрожжах, а планы релиза тихо уходили в сгущающийся киберпанковый туман…
И тут вдруг в игре стали погибать игроки.
Причем погибать не от предусмотренных игрой причин — ловушки, засады, падения в открытые (но малозаметные) люки. Нет, игроки стали погибать внезапно. Шел так вот себе просто киборг-суперагент-мафиози по улице, нес за плечом себе спокойно миниган, цветочками на бетонных клумбах любовался… и вдруг «хрясь», и его КРОВЬКИШКИРАСТЕРЕБОНЬКАЛО как фембой-националист трапика-коммуниста.
Причем невзирая на броню, хиты и прочее. Один удар — и игрок любого уровня становился мокрым местом. Причем удар, что самое непонятное, из ниоткуда.
Изучение логов выявило только, что игроки погибают от «физического урона». То есть либо игрок куда-то свалился с небезопасной высоты, либо в игрока что-то бросили. Игра предусматривала возможность поднимать (руками, телекинезом или чем еще) некоторые объекты окружения — контейнеры, бочки, автомобили — и кидаться ими, причем как для игроков, так и для врагов. Такие объекты имели определенный вес, и наносимый ими (физический) урон рассчитывался из этого самого веса и скорости, приданной киданием.
Понятное дело, разработчики первым делом ухватились за первую версию; может, игрок где через текстуры проваливается? Но моделирование ситуации показало, что даже провалившись намеренно через текстуры улицы, игрок застрянет, но не помрет на месте.
Поэтому переключились на вторую версию; что на игроков сверху что-нибудь падает. Может, под игровым «небом» случайно генерируются какие-нибудь невидимые бочки и падают на игроков? Но никакого такого бага со случайной генерацией чего бы то ни было в «небе» не нашлось, да и высота игрового «неба» была явно недостаточной, чтобы одним ударом падающего предмета прикончить игрока невзирая на броню, щиты и количество хитов.
Тем временем выяснилось, что загадочный эффект действует не только на игроков, но и на врагов. Вышел какой гангстер свежим воздухом подышать, из дробовика по героям пострелять, герой даже и прицелиться не успел — а гангстера вдруг КРОВЬКИШКИРАСТЕРЕБОНЬКАЛО как фурри-бойкиссер надувную тянку. И снова — физический урон, одним ударом расплющило, болезного.
Когда же внезапно убило на месте босса локации (тем самым лишив игрока такой возможности и сделав локацию в принципе непроходимой), разработчики схватились за головы. В игре попросту не было предусмотрено возможности кинуть даже самый тяжелый кидаемый предмет с такой силой, чтобы киборга-мутанта с шестизначным количеством хитов одним ударом КРОВЬКИШКИРАСТЕРЕБОНЬКАЛО как отаку-хентайщик дайкимакуру Рэви из «Black Lagoon».
Отчаянные поиски таинственного убийцы продолжались несколько дней и увенчались успехом только по чистой случайности.
Виновником всего оказались… автомобили. Игровая уникальность которых заключалась в том, что они были единственными в игре сочетающими свойства NPC (деловито ездили туда-сюда по улицам) и кидаемого объекта (как уже упоминалось выше, в игре можно было кидаться автомобилями).
Ввиду такой вот дуалистичности, автомобили имели двойную систему обсчета динамики; одну от NPC, другую от бросаемого физического объекта. И оказалось, что у этих систем есть критическое расхождение в понимании параметра «скорость». С точки зрения динамики NPC, скорость вполне могла быть отрицательной — это просто означало, что персонаж (в данном случае автомобиль) движется задним ходом. С точки зрения же динамики физического предмета, скорость могла быть только положительной. И столкновение этих двух картин мира порождало… нестандартную ситуацию.
В некоторых ситуациях при торможении скорость автомобиля уменьшалась — за счет модификаторов, вроде столкновения с препятствиями — так резко, что становилась отрицательной. Ну, например «автомобиль стукнулся о стенку/героя/монстра и от этого слегка отъехал назад, прежде, чем остановиться». Само по себе это было абсолютно нормально.
Но. Программа обсчета динамики физического объекта отрицательную скорость не понимала. Она получала значение по модулю, и с ее точки зрения получалось, что автомобиль ускорился. Алгоритм действий автомобиля как NPC соглашался с таким выводом, и начинал экстренно гасить внезапно возникшую положительную скорость. Что с его точки зрения выглядело, как начинать разгоняться задним ходом, «прибавляя отрицательную скорость».
Тут программа обсчета динамики физического объекта окончательно впадала в прострацию; автомобиль тормозит, а скорость увеличивается. Единственным решением алгоритма действий NPC-автомобиля было тормозить еще активнее, что… абсолютно верно, приводило к набору скорости. Задом. И эта бесконечная петля повторялась и повторялась, и не только из нее не было выхода, но и, как выяснилось, не было у нее предела — ограничитель максимальной скорости для отрицательных значений не действовал.
В общем автомобиль разгонялся задним ходом до тех пор, пока не переполнялись абсолютно все ячейки параметра «скорость», предусмотренные программой (девять). Тут уже «разгонное торможение» переставало работать, и автомобиль переходил к спокойному крейсированию на скорости 999.999.999 метров в секунду. Ну, или примерно в три раза быстрее скорости света.
Причем столкновения с препятствиями, по логике движка призванные уменьшать скорость объекта — отнимать от нее некоторое значение — летящий автомобиль, естественно, только ускоряли (напоминаю, что с точки зрения NPC-автомобиля его скорость была и так отрицательной). А также меняли ему вектор движения. С учетом же что как сам автомобиль, так и абсолютное большинство препятствий вокруг были неразрушимы — это довольно быстро и логично приводило к тому, что автомобиль улетал в небо и начинал рикошетировать между «небом» и поверхностью. При этом программа уже не успевала отрисовывать сами текстуры автомобиля, и тот становился полностью прозрачным и невидимым. Но все еще материальным.
И если на пути оказывалось что-либо разрушимое — скамейка, игрок, враг или босс-киборг-мутант — то программа обсчета динамики физического объекта от всех щедрот вваливала ему урон от 1000 кг веса, летящих на 999.999.999 метрах в секунду. Количества хитпоинтов, необходимых, чтобы пережить подобное, у игровых персонажей не имелось даже суммарно.
Попробуйте представить этот пролет сверхсветового неразрушимого автомобиля по неразрушимым тесным улицам киберпанкового мегаполиса. Неон уличных фонарей сливается в жесткую гамма-радиацию, бьющую в заднее стекло. Перепуганный шофер внутри с отчаянием обреченного давит на педаль заднего хода, только ускоряя тем самым свой безумный полет. Жители мегаполиса лишь безучастно смотрят, как очередной герой или злодей — киборг, мутант, спецназовец — внезапно превращается в облако ионизированного газа. Киберпанковое будущее не лишено иронии…