Pull to refresh

Comments 96

гораздо более понятно, чем большинство современных систем.

Обычная стейт машина FSA, да и иначе толком не перепишешь.

IMO, Finite State Machines — это антипаттерн похуже синглотонов. Он имеет очень узкое применение — анимация и AI, использовать его где либо еще — моветон. За годы работы в геймдеве, я не видел ни одной нормальной реализации FSA которая бы не раздулась в неподдерживоемое спагетти.


Переписать толком можно легко, есть куча паттернов и подходов, начиная классическими вроде MVC / MVVM (которые отлично подходят для UI-driven и 2d игр, с теми или иными изменениями), и заканчиая Entity Component System и Data Oriented Design.


Я считаю, что в таких ситуацях гораздо уместнее писать Service-Centric код и Inversion of Control. Вместо монолитной машины состояний, состояние игры описывается набором сервисов. Каждый сервис имеет свое сосотояние отвечает за что-то одно и только одно, например: анимация, диалоги, инвентарь, квесты, прогресс игрока, сохранения, аутентификация итд.
Сервисы слабо связаны (через интерфейс) и общаются друг с другом по минимуму. Соответственно, ожидания каждого сервиса так же описываются через интерфейс / контракт, например, сервис диалогов может обращаться к сервису интвентаря что бы узнать, имеется ли в наличии предмет, требуемый для выполнения квеста, итд (InventoryService.HasItem(...)).
Логика каждого сервиса может быть протестирована Unit и Integration тестами.

Каждый сервис — своя FSA, остальное — модное словоблудие.

Единая FSA конечно зло, я не смотрел — так ли это в данной игре.

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


Приведите конкретный пример функционала и я приведу вам пример как сделать его на обычном OOP, без всяких FSA.

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

Есть меню вверху экрана, там в зависимости от нескольких флагов/условий могут появляться 4 одинаковых по размеру контент-менюшки. Нужно по совокупности условий скрывать 3 из них и показывать 4-ю. Как вы понятно это сделаете, если не, скажем:

let state = ...
switch state {
case state1:
  v1.hidden = true
  v2.hidden = true
  v3.hidden = false
  v4.hidden = true
case state2:
  v1.hidden = false
  v2.hidden = true
  v3.hidden = true
  v4.hidden = true
...
}

Так короче и меньше шансов ошибиться, хотя по понятности всё равно не лучший вариант:
v1.visible = state == state1;
v2.visible = state == state2;
v3.visible = state == state3;
v4.visible = state == state4;
Кодировать состояния в таблицу, таблицу парсить либо в compile time (генератор кода), либо в runtime.
а если не только прятать/показывать надо? Конкретно в этом примере мне надо чтобы на вьюхе №1 показывалась определенная анимация, если это переход с 4 стейта в первый, и т.п., и логики там еще пару строк в каждом кейсе есть.

Я нисколько не против таблиц, кстати они тоже конечный автомат, так что мы отошли от изначального вопроса :) Но если есть еще и какая-то кастомная логика кроме .visible, имхо switch — да, самое топорное, но и самое наглядное/поддерживаемое решение
Хештабшицей статус -> маска, например. Или массивом массок если state это числа в разумных пределах.

Даже если претят таблицы, то хотя бы использовать этот факт:


скрывать 3 из них и показывать 4-ю

v1.hidden = v2.hidden = v3.hidden = v4.hidden = true;

let state = ...
switch state {
case state1:
  v3.hidden = false;
  break;
case state2:
  v1.hidden = false;
  break;
...
}
можно было бы и так для красоты и краткости, так иногда и делаю, а что если на какие-то вьюшки мне нужно показывать с анимацией, если переход от четвертой к первой, и только этот переход? Да, такая логика у приложения, ничего не поделаешь. И имхо чем кастомней код тем больше ему нужно быть кодом, таблицами все не закодируешь. А старый добрый конечный автомат всегда выручает

Я считаю что вы делаете две потенциальные ошибки.


Во-первых, вы строите всю архитектуру на предположении о том, что у вас может одновременно показываться только одна менюшка и это требование никогда не изменится. Но завтра к вам приходит дизайнер / заказчик и просит сделать drag-and-drop между менюшками, и оказывается что во время перетаскивания надо показать обе одновременно. И в такой момент вы понимаете, что весь код придется для этого выкинуть / переписать с нуля, потому что само понятие машины состояний тут неприменимо (раз может быть несколько состояний одновременно).


Во-вторых, в самом switch-case, конечно, ничего страшного нет, но как только добавится логика, анимации переключения между меню итд, появятся классы типа State, StateTransition и прочих артефактов спагетти-стейт машин, и проблема #1 станет еще хуже.


Как по мне, так хорошо установленные паттерны вроде MVC отлично подойдут здесь. Каждое меню или подменю имеет свою пару Controller — View. Controller отвечает за логику и делает вызовы в сервисы, View — за представление (шаблон меню, анимации). За переключение подменю может отвечать одна функция, которая при разворачивании контент-меню закрывает остальные:


// IMenuController.cs:
interface IMenuController
{
    bool IsOpen;
    void Open();
    void Close();
}

//  TopMenuController.cs:
class TopMenuController : IMenuController, INestedMenuContainer
{
    private IMenuController[] _submenus;

    public void OpenNestedMenu(int index)
    {
        for (int i=0; i<_submenus.Length; i++)
        { 
            IMenuController submenu = _submenus[i];
            if(i == index && !submenu.IsOpen)
            {
                 submenu.Open();
            }
            else if(submenu.IsOpen)
            {
                 submenu.Close();
            }
        }
    }

    // ...
}

Это просто, понятно, читабельно, а главное, требование "одновременно может быть показано толко одно меню", запрограммировано ровно в одной функции на 12 строк кода и может быть в любой момент времени изменено.


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

Допустим, есть шина (rabbitMQ), на которую льются объекты и подписаны обработчики. Каждый обработчик берёт объект со своим state, что-то делает, меняет состояние и выкидывает обратно в шину.
Бинд обработчик(и) — состояние лежит во внешнем файле и в любой момент может быть откорректирован, требование ТЗ.
Для удаления с шины есть отдельный обработчик, который мониторит неиспользуемые состояния и состояние окончания обработки.
И как здесь без конечных автоматов?
использовать его где либо еще — моветон

А парсеры?

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

У меня обратный опыт. Тем не менее, я согласен с тезисом про спагетти — стейт машины надо проектировать осторожно и внимательно. Зато когда она работает — то она работает хорошо.

UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here

Я думаю там уже потирают руки и готовят разбор…

Да, готовят! Сегодня выйдет статья :)
PVS-Studio на них есть :) Мимо такой игры мы пройти не смогли.
Если вам интересно посмотреть, какие ошибки мы там нашли, предлагаю почитать статью:
VVVVVV??? VVVVVV!!!
Работает, не трожь


Да. Судя по разному форматированию, это не невнимательная копипаста. Возможно, логика работы программы описывается именно так. Блок с первым условием — валидация/инциализация входных данных. Второй блок — обработка данных. Условия сейчас одинаковые, да.
Тут еще возможно, что во время отладки меняли значение statedelay=0 на что то еще, что меняло логику. Или меняли местами statedelay--.

А в игре как раз C++

Я всего лишь сказал, что
case e_activating_teleporter:
читается лучше, чем
case 4080:
Вы так не считаете?
А за что минус-то «предыдущему оратору»? Перечислить состояния машины состояний в enum'e и делать switch не по magic numbers, а по осмысленным идентификаторам — самый простой и естественный шаг. Который улучшил бы читаемость кода и мало-мальски облегчил бы его поддержку и отладку даже автору.

Хотя понятно, конечно, что C-код игры вторичен, вначале был flash, а в Action/Ecma/JavaScript с enum как-то не особо хорошо.
UFO just landed and posted this here

Так если каждое из них имеет какой-то смысл в механике процесса, почему бы и не быть этим самым "вменяемым именам"? Или речь о том, что имена, отражающие суть, быстро разрастутся до нечитабельной длины?

И на что его критики предлагают заменить?
UFO just landed and posted this here
будет тот же state machine, только на лямбдах, не?
В джаве некритичных к производительности приложениях это паттерн Стратегия. Почти уверен, что в играх он неуместен, но настаивать не буду.
UFO just landed and posted this here

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

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

если в игре VVVVVV код на 309 элементов, сколько их может быть в игре AaaaaAAaaaAAAaaAAAAaAAAAA!!! (A Reckless Disregard for Gravity) ?

Разработчики игр говнокодят! Вот это поворот!
Ну вообще все говнокодят, просто разборы говнокода в играх как правило интересны, потому связаны с какой-то фичей в игре. А разбор говнокода в условном notepad не интересен. Вот и вся разница в говнокоде в геймдеве и не в гемйдеве.

Кстати говоря, о багах в Блокноте — это тоже может быть интересно. Например, если реверсить код https://habr.com/ru/post/264081/

Как там в книге по программированию на Форте было «Если ваше определение не входит в один экран, то имеет смысл разбить его не несколько более мелких определений»
«Если ваше определение не входит в один экран»
--то купите экран побольше!
Первые форт-системы ориентировались на работу без ОС, и исходные тексты там редактировались с помощью так называемого блочного редактора. И исходный текст всей системы и «прикладух» вместе с документацией хранился в одной области памяти, разделённой на «экраны» по 1 (одному) килобайту каждый.

Соотаетственно в начале каждого экрана писалось, что эта часть исходников делала (во многих системах каждому экрану с исходниками соответствовал экран с документацией. Тоже 1 КБ), и загрузка и редактирование происходило поэкранно. Можно было выводить список первых строк экранов-блоков.

По историческим причинам блочные редакторы всё ещё являются частью некоторых достаточно современных форт-систем. Где под эти самые блоки отводится просто отдельный текстовый (ну, почти) файл. Например см. www.forth.com/starting-forth/3-forth-editor-blocks-buffer (там код адаптированный к коммерческому и ещё, вроде, живому SwiftForth).
Разбить код на мелкие кусочки — задача не очень сложная.

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

2071: При строительстве подставки под экран был случайно возведён космический лифт.

При любом разрешении экран (текстовый буфер) имеет размерность 1024 символа. «Вы можете купить машину любого цвета, при условии что этот цвет — черный»
Публикация кода одной игры показала как устроены абсолютно все игры. Логика журналиста как всегда безукоризненна.
Ну надо сказать что во много это так и есть (если что 11 лет профессионально в геймдеве). Я правда не понимаю чего так все возмутились.
Тем временем этот код критикуем мы, в телах и головах которых эволюция накапливала технический долг миллионы лет. И надеюсь, что люди будущего будут вечно восхищаться тем, что смогли разгрести этот костыльный ад.
UFO just landed and posted this here
Мышцы вокруг ушей ни чем не мешают.
Копчик — да, уязвимая штука — легко крашится и потом вся система страдает.
Но мне кажется рефакторить нужно сначала наиболее критические места, ИМХО:
1) дублировать/резервировать мышцу для поддержания давления в кровеносной системе.
2) усилить/укрепить систему монтажа «ЦП» и большинства сенсоров.
3) разнести в пространстве интерфейсы систем отвода отработки и репродуктивной системы. (ибо не гигиенично).
:)
Увести сосуды глаз за сетчатку! КПД глаза в нынешнем виде поистине уныл, осьминоги ржут над нами :(
А будут продолжать ржать — дадим им мозг, чтобы страдали от бессмысленности существования.
UFO just landed and posted this here
1.1 Сменить систему кровообращения на магнитную.

Внешние неодимые магниты — vulnerability detected.

Не, нам только в своём форке надо исправлять, чужие баги не нужны.
Когда-то давно я купил себе телефон Nokia 1020 под виндой. Хорошенько протащившись от плиточного интерфейса (до сих пор на андроиде пользую шеллку с плитками, уж больно нравится), решил попробовать что-нибудь написать под эту платформу.
Ну а что писать? Конечно игрушку какую-нибудь. Что-нибудь простое и из времен молодости.
За два дня(в буквальном смысле за 2 дня) наклепал говнокода и как водится — «х.як-х.як и в продакшин» (в смысле в магазин приложений). Не запаривался никакими игровыми фреймворками, все было сделано на обычном виндовом Canvas'е, без «эффектов» — просто игровые юниты + гравитация.
Потом несколько раз обновлял приложение (добавлял новые уровни, предварительно их пройдя локально у себя на телефоне + мелкие доработки, типа вкл/выкл звук и еще что-то там), потом наигрался и забыл/забил.

Так вот, к чему это я все? К тому, что код у меня в этой игрулине был примерно такого же уровня — он абсолютно не был продуман, т.к. изначально вообще не было никакого плана разработки. Ни количества уровней, ни списка фич, а общая концепция сводилась к «ща наклепаем и поглядим, как оно будет, а когда-нибудь потом сделаю как надо».
Скорее всего автор упомянутой игры пошёл по такому же пути — слепил в коде какую-то мелькнувшую идею, по ходу разработки обвесил ее всякими плюхами и дополнениями, ну а после просто поленился делать рефакторинг (хотя судя по коду, там проще с нуля переписать, чем пытаться привести все это хозяйство к «правильному» виду).
Поддерживаю. И вообще, не верю в проектирование ПО. Проектирование ПО — это когда ты перекладываешь риски на заказчика, согласовываешь с ним ТЗ/проект (= текущая абстракция), реализуешь, и этот дурак тебе платит за получение продукта, который ему не нужен. Не нужен, так как на первом же прототипе или после первых дней прогона в реальности, он говорит «да, я помню, мы так согласовывали, но вот тут нам нужно поменять это и это, убрать это и добавить это», а в ответ получает «простите, в ТЗ мы вот так прописали — сделаем версию 1.0 как договаривались, оплатите, начнем писать версию 1.1». И это в лучшем случае. В худшем — программисты возмущаются, что за идиот заказчик, не знает, что ему надо. А это так и есть — заранее никто не знает, что ему надо, как будет удобно пользоваться инструментом, которого вообще пока что еще нет.

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

Некрасиво? Да. Но эта рабочая схема. Весь мир создан на скотче и синей изоленте. Идея «давайте просто хорошо придумаем как надо и сделаем» — только в голове у юношей бывает, до первого раза, когда они все делали как надо, сами, и выясняется, что когда «придумывал как надо» — придумал фигню какую-то.
Именно! Я уже как-то описывал один краткий случай из жизни, когда добрую половину ТЗ для довольно сложного продукта спустили в унитаз в самом начале разработки и сэкономили тонну нервов и денег друг другу.
А все потому, что мне пришло в голову походить хвостом за инженерами (для которых это ПО разрабатывалось), понаблюдать процесс работы, поспрашивать «а чо это вы тут делаете такое, ааа?».
В результате чего уже на второй день стало понятно, что в ТЗ (54 страницы!) описана какая-то лютая херня, к реальной необходимости имеющая довольно посредственное отношение, проще nanoCAD поставить и обучить персонал, чем городить написанное.

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

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

какая изящная переформулировка фразы «нет ничего более вечного, чем временное»

Есть мнение, что самая опасная вресия продукта это версия 2.0. "Ну уж теперь я всё сделаю по-багатому по-умному." Со всеми вытекающими..

Один делает, миллионы обсирают. Чел сделал единственно правильным путём. Он сделал игру, в которую прикольно играть, которую любят. Код выполняет машина. Кучи современных разработчиков не имеют своего мнения в принципе и не могут самостоятельно оценить код. И написать код без гайдлайнов и «одобрения сообщества» не могут. Игры это чертовски сложно (первую игру я написал более 15 лет назад, а последние 11 лет я только и делаю что пишу игры профессионально, ежедневно). И пытаться разводить в играх эталоны полированного кода который дорого модифицировать, сложно хакать, но который весь из себя запривачен и построен на миллионе абстракций смысла никакого нет. Я пробовал делать архитектурные изыски, их потом сложнее поддерживать. Я сейчас работаю с игрой релиз которой состоялся 9 лет назад, и она всё ещё активна, она переживает третью смену движка, и поверьте там очень много кода который плохо пахнет. И что теперь, застрелиться? Если работать а не обсуждать, то выясняется что не всё так уж и плохо. А застопорить разработку на месяцы для «архитектурирования» ни к чему хорошему не приведёт. Иначе говоря я считаю что значение понятия «красивый код» переоценено. Неплохо на похожую тему высказался Джоэл habr.com/ru/post/219651 Ну и, конечно, не могу не упомянуть просто идеальную иллюстрацию к тому что бездумное причёсывание кода не всегда нужно habr.com/ru/post/440414
Если кратко это резюмировать: не нужно жить в говне, если говно случилось, нужно вытереть, но пытаться в коде совместить впечатление от Лувра и стерильной лаборатории одновременно никакого смысла нет.

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


Сейчас процент более менее завершенных проектов куда больше :)

Я же не говорю что проектирование, архитектура и всё прочее не нужно. Просто при реализации проекта и задуманной архитектуры неизбежно выползут несостыковки, это нормально, если нельзя быстро в рамках архитектуры сделать хорошо то нужно подставить костыль и продолжать, мониторя то, сколько костылей натыкано и как они себя ведут. Если ломаются — править, а если нет, то пусть стоят. А говорить что в коде не должно быть ни одного костыля — врать себе и другим. В данном случае, если бы чувак вместо релиза сидел бы полировал — ничего бы не получилось.
я если честно крайне плохонький кодер, но обычно после получения работающего прототипа он откладывается в сторону и переписывается с нуля — что бы поубирать всю ту «муть» и «гуляние мысли» которые были в процессе прототипирования…
Одна из лучших игр за последнее время и я сперва очень обрадовался что автор выложил её в open source, потом прочёл лицензию и радость пропала. Короче, товарищ просто дал нам возможность почитать его код :)
Почему? Вы можете собрать для себя любимого билд с оригинальными ресурсами, куртизанками и преферансом.
Плюс можно делать всякие аддоны, тулзы и прочая, но их, как я понял, нельзя будет монетизировать.
В остальном да, это весьма ограничивающая лицензия.
Open source (в понимании Open Source Initiative) тем и хорош что каждый может и форк сделать, и подзаработать быть может (почему нет?). А тут ограниченная во всех смыслах лицензия которая годится только что для образования (хотя и тут не факт что его можно полноценно использовать в платных учебных материалах) и статей «как не надо писать код». Я думал автор действительно хотел вложиться в open source как сделала id software в своё время, но нет, парень просто пропиарил себя. Я бы это даже open source не назвал. Всё для чего годится такой код это лепка модификаций его же игры.
Как говорится, «неделя непрерывного программирования спасает от двух часов проектирования». Да, автор молодец, выпустил завершённый продукт, но мне было бы стрёмно выпускать продукт с таким кодом (если только он не был написан под дулом пистолета).
Тут уже несколько раз приводился switch на 300 состояний. Попробуйте вспомнить хоть какую-нибудь сущность, представителей которой вы можете описать в количестве 300 штук. Я почти уверен, что в оригинальном коде игры этому состоянию нет названия, потому что автор не попытался его как-то назвать. А значит и не было попытки как-то его декомпозировать.

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

Апдейт большого размера уже редкость, но вот игры которые перевалили за 80 гигов на харде уже не редкость. И та ки да, 99 процентов файлов из этих 80 гигов это медиа файлы, как картинки с разным разрешением и музыка. Если повезет то музыка в МП3 и можно скопировать на телефончик. Если не повезет, то нужно понять как конвертировать один тип файла в другой.

Три года назад я написал плагин для X-Plane. От идеи и первого прототипа до первой публичной версии прошло две недели. С тех пор эта штука попала в топ-5 самых скачиваемых плагинов для X-Plane (250К это очень много для симуляторов) и есть во всех списках «N плагинов X-Plane, которые вам необходимы».
Но ёлки-палки, внутри довольно ужасный код на голом С. Многие вещи, которые я заложил в самом начале, так и остаются в неизменном виде. С тех пор плагин стал делать гораздо больше функций и это тоже добавило некоторого хаоса. Я это потихоньку привожу в порядок, но на самом деле проще всё сжечь и переписать заново.
Это я всё к чему. Если бы я тогда начал продумывать архитектуру, то эта штука скорее всего вообще бы не появилась. Я бы просто утонул в деталях, в начале я вообще не представлял за какую сложную штуку взялся и сколько там нюансов.

Ладно игры — работал в одной Fin-Tech конторе, которая делала софт для top-tier investment банков: там был тоже был один мега-фактори с огромным case-switch'eм. В какой-то момент он превысил 65536 строчек кода, и начались проблемы с дебагом в VisualStudio

UFO just landed and posted this here
Представляю ответ. «Перепиши код, даун!»!

У меня есть живой пример — люди в одном проектном институте копипастили код АСУТП, что он перестал влезать в контроллер по памяти (100500 задвижек или что то типа).

Ну я по молодости, примерно так нетолерантно им и ответил
Справедливости ради должен отметить, что в промышленной автоматике ресурсов куда меньше, потому они заканчиваются быстрее.
А нарастить ресурсы (ПЗУ, ОЗУ) или невозможно, или очень дорого.
Я в своей игре тоже писал кучу говнокода, и как-то работало, и всем было плевать.

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

Наверное, есть исключения — или долгоиграющие AAA проекты (кхе-кхе, на тебя смотрю, Star Citizen), или всякие MMO/MOBA у которых очень долгий цикл сопровождения. Но да, для проектов поменьше, для инди, выкатить рабочее важнее внутренних красот.

У инди просто ограничение на ресурсы еще жестче, чем у крупных студий.
В XRay много говнокода. В точности в гранатомётах, если базовый класс оружия CWeapon и CWeaponMagazined более или менее работают, то гранатомётный классы совсем по тупому сделаны. В базовом огнестрельном классе CWeaponMagazined выстрел производится из метода FireTrace, при этом, выстрелу предшествует ряд методов, вызов которых ещё не означает что сам выстрел произошёл. Ну вот погромист гранатомётов, CWeaponRG6, CWeaponRPG7, CWeaponMagazinedWGrenade, сделал так, что, при выстреле граната запускается из разных методов, но только не из FireTrace. Ну вроде бы всё работает, но при определённых условиях работает совсем не правильно, CWeaponRG6 может стрелять гранатой когда магазин пуст при определённых условиях, у остальных тоже стрельба при определённых условиях не правильная. В точности, если заблокировать оружие скриптовым методом wpn:set_queue_size(0) то выстрел всё равно произойдёт, точней произойдёт вылет гранаты, хотя выстрела как бы и нет.
Хотя класс гранатомёта, это же довольно простой объект, произошёл выстрел, и в методе где запускается пуля, выпускается граната по направлению выстрела. Вроде всё просто, метод FireTrace сделал виртуальным и переопределил в гранатомётах.
Я из-за этой ошибки, не смог написать скрипт ПЗРК на Lua для оригинального движка. Логика ПЗРК на порядок сложней чем в простом РПГ.
ЗЫ
В XRay граната-ракета это такой же наследник CGameObject, как и все остальные объекты в игре. В других движках, может по другому реализовано, в точности наследник пули, как CRYENGINE.
CWeaponRG6 может стрелять гранатой когда магазин пуст при определённых условиях

Напомнило

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


И вообще, раз пошла такая пьянка...

Кстати, как вызвать этот баг? Для этого, гранатомёт РГ-6 надо зарядить, потом разрядить, опять разрядить, и снова разрядить, повторять пока не надоест, далее разряжаем в последний раз, и прячем гранаты. И всё, можно стрелять, отдачи нет, вспышки нет, но гранаты вылетает. Можно быстро уничтожить большое количество противников на открытой площади.
ЗЫ
Как видно РГ-6 оружие читерское, особенно в мультиплейере! Как разрабы поступили в этом случае? Очень просто, они в МП заблокировали разрядку оружия во обще! =) Вот так просто, контекстное меню заблокировали, и всего делов. Хотя починить гранатомёты не сложно, но вероятно свободных программистов для этого не было. С этим связано не справедливая система оплаты в GSC. Надеясь сейчас это не так, а то в СТАЛКЕР-2 таких багов будет не меньше.
UFO just landed and posted this here
Sign up to leave a comment.

Articles