![](https://www.amk-team.ru/forum/uploads/set_resources_35/84c1e40ea0e759e3f1505eb1788ddf3c_pattern.png)
Malandrinus
Жители-
Число публикаций
1 930 -
Регистрация
-
Последнее посещение
-
Дней в топе
13 -
AMKoin
160 [Подарить AMKoin]
Весь контент пользователя Malandrinus
-
Artos,
-
Artos, я лично понял исходный вопрос в том же смысле, как и Shredder. Ну давай сформулируем вопрос иначе: "можно ли сделать то или иное с привлечением подходов, не выходящих за рамки редактирования текстовых файлов скриптов и конфигов". Давай не будем называть "ковырянием движка" любой из подобных "выходящих за рамки" подходов. Ни суть вопроса, ни правильность ответа Shredder-а от этого не изменятся. И вообще, на мой погляд надо быть более снисходительным друг к другу. Здесь же не юридические документы составляют с трёхстраничным списком оговорок и уточнений к какой-либо единственной фразе. Можно и проще относиться к лаконичности и размытости чужих формулировок.
-
Clayman,
-
Shredder, Это количество само по себе ни о чём не говорит. Во-первых, не все рестрикторы имеют логику. Многие, если не большинство, работают по своему основному назначению, рестрикторами т.е., и никакой скриптовой нагрузки не создают. Это, к примеру, все рестрикторы костров. Во-вторых, не такую уж и нагрузку создают эти рестрикторы, даже если и с логикой. Сама логика может быть большую часть времени с неактивной секцией. Если и активная, то там максимум стоит периодическая проверка на попадание какого-то непися или актора в этот рестриктор. Это достаточно малозатратная операция (к слову сказать, рестрикторы со сферическим шейпом в этом смысле намного предпочтительней боксов). Опять же, делается это с пониженной частотой, в ТЧ - всего 5 раз в секунду. Т.е. не так уж всё плохо в первом приближении. Конечно, надо предметно измерять, тогда и можно будет сказать точно. В ЗП я этого не измерял, поэтому с гарантией не скажу.
-
ColR_iT, эта функция обычно вызывается один раз при загрузке логики. Нет особенного смысла оптимизировать такого рода код. Всякие фризы при загрузке по-любому вызываются не скриптами, а данными: звуками, моделями, текстурами. Скрипты оптимизировать если и имеет смысл, то там, где они вызываются часто, на каждом апдейте, внутри длинного цикла и т.п. и при этом действительно что-то делают: оперируют со строками к примеру. В качестве некоторого оффтопа. Я как-то провёл эксперимент. Удалил с уровня все объекты, очистил биндер актора, короче, убрал почти всю нагрузку, так или иначе связанную со скриптами или вызываемую скриптами. В итоге, fps конечно подрос, но не сказать чтобы прямо драматически. На динамике и в зависимости от настроек графики на большом уровне типа Кордона fps вырастал процентов на 20-30, а то и меньше. Основная нагрузка, получается, приходится на рендер. И это я ведь вообще всё убрал, а на самом деле вряд ли можно ожидать, что всякими оптимизациями можно убрать хотя бы 5-10% от скриптовой нагрузки. В итоге, условно говоря, можно ожидать от самой хардкорной оптимизации ну скажем 3-5% итогового выигрыша в fps. Разумеется, не всё так линейно и просто. Иногда оптимизировать можно и нужно, но в целом, как видно, оптимизация ради самого процесса оптимизации ничего не даёт, кроме потери времени. Если на самом деле выловили большую часть грубых алгоритмических косяков, то в чём тогда проблема то? Пользуйтесь на здоровье и не парьтесь.
-
Shredder, Ненужная оптимизация - зло. Вот рядом жирные фризы от перебора всех предметов на каждом апдейте, неправильных моделей, создания огромных таблиц с одним и тем же содержимым при каждом входе в функцию, которая вызывается на каждом апдейте, горомоздкие (и часто ненадёжные) операции со строками, листинги десятков if ... elseif ... elseif вместо однострочной выборки из таблицы и прочее в этом духе. Положа руку на сердце, скажи, это всё уже изжили полностью? Если нет, то к чему вся эта мышиная возня вокруг микросекундных затрат на вызовы? Это не то что ненужно, но это даже вредно, поскольку в итоге делает код менее понятным при отсутствии видимой выгоды. При этом, ты тратишь своё время, которое мог бы потратить на более полезные вещи (см. выше какие). Т.е. ты конечно поступай как хочешь, но я бы рассуждал именно так.
-
Shredder, Нет, ООП не начинается с таблиц или даже классов. ООП начинается с проектирования класса (или таблицы Lua, если это то, что мы имееем для реализации). Когда структура таблицы спроектирована с учётом идей ООП и потом соответственно используется, вот тогда мы имеем ООП. Есть же основные принципы: инкапсуляция, наследование, полиморфизм. Как они технически реализуются в общем-то неважно, хотя разумеется язык, под эти идеи специально заточенный, использовать будет удобнее. И это только принципы дизайна классов. Их ещё надо правильно применить, и за программиста это никто не сделает. Ну разумеется вылетит, поскольку сам пишешь, что setData ничего не возвращает. Напиши там return self и будет работать, хотя не совсем ясно, какое это отношение имеет к сути ООП. К слову сказать, здесь на лицо типичный стилевой косяк, а именно именование метода getData не соответствует его функционалу. Он ничего не получает, а только показывает данные. Поэтому назвать его стоило бы showData или printData, но никак не getData. Кроме того, подобные примеры к сожалению никак не объясняют ни сути ООП ни его преимуществ. Класс и объект класса в первую очередь объединяют данные с поведением (это как раз инкапсуляция и есть), а в данном примере у класса поведения не наблюдается, что вызывает естественный вопрос, а зачем было городить класс. Я и не утверждал, что это полноценная реализация объектного программирования. Я сразу оговорился, что сути ООП это не передаст, а вот суть поста - да. Это лишь пример, максимально простой, для восприятия не осведомлённому человеку. ColR_iT
-
Shredder, ООП - это общая идея, подход к проектированию программ. Однако некоторые считают, что ООП - это то и только то, что человек впервые увидел, скажем, в С++. Между тем, можно использовать ООП даже не имея поддержки со стороны языка, например в чистом исходно процедурном СИ. Что касается Lua, то здесь имеем прототипную реализацию ООП. Если вкратце, то понятия класс как такового нет. Есть сразу объект, и класс ты строишь, дополняя этот объект методами, данными и пр. Новые "классы" таким образом строятся на основе копий объектов. Это расширение Lua, называемое luabing. В сущности, к собственно Lua ничего особенного не добавляет и нужно в основном для того, чтобы экспортировать классы C++. К слову сказать "class" - это синтаксически функция. Поэтому вот это class "SurgeManager" синтаксически эквивалентно такой строке class("SurgeManager") т.е. никаких "классов" с точки зрения Lua не появилось. Этот вызов регистрирует некий внутренний пользовательский объект в luabind. Также выполняет клонирование прототипа, если используется наследование в такой форме class "SurgeManager" (<базовый класс>) Всё это просто некий мелкий сервис. Тоже самое можно сделать и прямо на таблицах.
-
Shredder, Ты упустил самое главное действие - собственно загрузку звука. Подумай сам, в игре около гигабайтов звуков. Пусть даже грузятся не все, но изрядное их количество. Вот я тебе и предлагаю сперва сравнить время, затраченное на вызов пары сотен методов, со временем, затраченным на загрузку в движок такого объёма данных. Есть вероятность, что ты пытаешься оптимизировать пару процентов от общего расхода. Потратишь кучу своего времени, уберёшь, станет на эту пару процентов быстрее... proper70, Зато у них есть переключаемая логика, которая делает в точности это и которую можно прикрутить к совершенно любому объекту. Производительность чего? =) ООП повышает производительность программиста, это да. Производительность системы очевидно понижает, поскольку имеются дополнительные накладные расходы на вызовы методов классов.
-
Прежде чем переписывать, неплохо было бы выяснить соотношение времени полезной нагрузки и вызова функции/метода. Т.е. в сравнении выше сравниваются накладные расходы на вызов соответственно метода класса и просто функции. Но я подозреваю, что фризы вовсе не связаны с расходами на вызов методов класса, а скорее всего это звуки так долго грузятся. При этом, могу предположить, что на фоне времени загрузки звуков расходы на вызов что метода, что обычной функции - это копейки. Так что рекомендую сначала это проверить, а потом уже что-то переписывать.
-
Справочник по функциям и классам
Malandrinus ответил на тему форума автора Malandrinus в Скрипты / конфиги / движок
alpet, В игре это делается путём постоянного рейтрессинга. Если в направлении дождя видишь небо (т.е. ничего не видишь), значит на улице. Это легко проверить. Во время дождя, если в помещении пройти под дырочкой в крыше, то сразу зашумит, как будто стоишь на улице =) -
[SoC] Ковыряемся в файлах
Malandrinus ответил на тему форума автора Halford в Скрипты / конфиги / движок
Callisto, точно могут, поскольку я это видел своими глазами. Но больше этого к сожалению не скажу, механики процесса не знаю. -
Viнt@rь, Это сколько там методов? В обеих упомянутых системах интерфейс сводится фактически к двум функциям получить/записать переменную. Впрочем, дело твоё. Не совсем ясно, что именно ты взял за основу и какой версии, поскольку системы мои и xStream отличаются и общего имеют только класс объекта хранения. По любому, если самоцель - именно поковыряться внутри, то рекомендую взять за основу систему xStream. На мой субъективный взгляд её разбирать и менять проще.
-
Viнt@rь, а чем тебя не устраивает готовое решение?
-
panzyuza, просто нет на самом деле такой функции. В lua_help присутствует, а на самом деле такой нет.
-
[SoC] Ковыряемся в файлах
Malandrinus ответил на тему форума автора Halford в Скрипты / конфиги / движок
stillmozz, если честно, я не думаю, что в каком угодно билде мог быть юзабельный пулемёт на основе машины. Откуда вообще такая информация? Если из надписи "открыть дверь" на объекте, то это обманка, как уже здесь выясняли. Потом, объективно на основе машины просто так пулемёт не сделаешь. Есть ряд препятствий: 1. Готовая модель пулемёта не годится поскольку схема костей немного отличается, в частности точка привязки камеры и "высадки" актора отличаются от машины. 2. В машине точка привязки камеры задаётся смещением относительно центра машины, в пулемёте же камера привязывается к кости оружия (условно говоря к прикладу) и при вращении пулемёта соответственно смещается вместе с ним. В машине будет совсем другой эффект, не так хорошо смотрящийся. 3. Посадка в машину (приаттачивание актора к объекту CHolderCustom) осуществляется относительно костей дверей машины и возможна не со всех положений. Пулемёт же можно использовать просто как юзабельнй объект со всех положений, что с этими дверями не сделать или опять же потребуется достаточно нудная настройка модели. Учитывая всё сказанное, а также то, что как класс машины, так и станкового оружия в игре был заброшен и с определённого момента никем не трогался, то вряд ли разработчики инвестировали время в попытки сделать одно на основе другого. Только в ЧН был пулемёт на основе машины, но и он был не юзабельный, а только стрелял по актору (см. выше все проблемы с моделью). Что касается класса CPHSkeleton, то это возможно ложный след. Класс этот отвечает за разделение объекта на части при разрушении. Вопрос, что там не так работает в этом станковом оружии, остаётся открытым. Хотя, с практической точки зрения это не так уж и интересно. Лучше, не заморачиваясь, на основе машины сделать. -
[SoC] Ковыряемся в файлах
Malandrinus ответил на тему форума автора Halford в Скрипты / конфиги / движок
Marafon6540, здесь речь о другом. Выше stillmozz, утверждал, что в каком-то из билдов пулемёт сами разрабы сделали на основе машины. На основе машины - это как раз реальный способ обойти проблему. Я уже проводил эксперименты на этот счёт, и в принципе работает, хотя и криво, поскольку нужна достаточно нудная настройка модели. Просто если это уже сделано, это сэкономило бы время. Поэтому я и спросил, в каком именно билде пулемёт был сделан на основе машины. Вообще то в ЧН был пулемёт и именно на основе машины, но из него было не пострелять. Здесь же цель - сделать юзабельный объект. -
Desertir, А что значит недоступны? У меня был эффект, что, хоть элемент и добавлялся и не пропадал, но его было не получить штатными средствами. Потому я их тоже сохранял, чтобы потом получать по индексу из своей таблицы. Кстати классы CUIListItemEx и CUIListItem, вообще говоря предназначены для создания скриптового класса на их основе. Т.е. надо делать так: class "my_list_item" (CUIListItemEx) function my_list_item:__init(arg1, arg2) super() -- добавляю свои элемент на окно списка end -- создаю элемент списка local list_item = my_list_item(123.45, "qwerty")
-
[SoC] Ковыряемся в файлах
Malandrinus ответил на тему форума автора Halford в Скрипты / конфиги / движок
stillmozz, Это очень интересная информация. Напомни, пожалуйста, что за билд и, если можно, где его можно достать. -
Язык Lua. Общие вопросы программирования
Malandrinus ответил на тему форума автора Malandrinus в Скрипты / конфиги / движок
Dennis_Chikin, Это вполне объяснимо, если знать, как Lua обрабатывает аргументы и возвращаемые значения. И то и другое передаётся через стек языка, а помещение и извлечение значений соответственно выполняется внутренними функциями. Плюс к этому, если вызывается метод класса, организованный через luabind, то для его вызова используется предварительный поиск метода через оператор индексирования, прописанный в метатаблице. Этот оператор представляет собой достаточно тяжеловесный код, скомпилированный на С++. Поэтому на самом деле иногда имеет смысл не делать функцию, а просто вставить несколько лишних строк кода. Чистый код Lua без вызовов (т.е. голая арифметика) будет скомпилирован с помощью LuaJIT и в общем-то будет выполняться всего в несколько раз медленнее, чем код С/С++. С другой стороны, давать это в качестве общей рекомендации я бы не рискнул. Какой-нибудь новичок воспримет это как прямое одобрение использовать копипасту в качестве основного инструмента. В итоге, на фоне копеечной выгоды имеем лютый несопровождаемый ужас вместо кода. Это не так и не может быть так, поскольку то и другое - синтаксически эквивалентные конструкции. Вот тест, который подтверждает сказанное. Я здесь пытался провести как можно более точные измерения: во первых, избавиться от эффекта Jit компиляции, для чего время берётся со второго цикла, во-вторых, убрать постоянную часть и оставить только время самой операции. Если запустить этот тест несколько раз, то видно, что отношение времён практически равно единице с небольшим случайным отклонением не больше пары процентов в обе стороны. Вот где есть разница, так это между индексацией строкой и числом. Причём, если значение берётся по индексу из "массивной" части, то это примерно в пять раз быстрее индексации строкой, но если ищем по ключу в хешированной части, то это уже примерно в 10 раз медленнее, чем индексация по строке. Если первое смотрится закономерно, то второе на самом деле удивительно. Значит, массив предпочтительней таблицы с ключами-строками, но строковые ключи предпочтительней, причем однозначно, произвольных целочисленных ключей! -
Язык Lua. Общие вопросы программирования
Malandrinus ответил на тему форума автора Malandrinus в Скрипты / конфиги / движок
Kirgudu, в случае Lua вряд ли удастся что-то оптимизировать. Если бы это был СИ, то я бы получил случайное 16-и или 32-х разрядное число один раз, а потом читал бы из него биты. В Lua же затраты на вызов самой функции генерации случайного числа сопоставимы, а может и больше, чем собственно генерация этого числа. Так что напрягаться смысла нет. Artos, навскидку я бы сказал, что вариант с плавающей запятой должен быть дороже, чем целочисленный. Однако, измерение показывает, что вариант math.random() в самом деле несколько быстрее, чем, скажем, math.random(2). Надо смотреть реализацию. Если второй вариант основан на первом, то это логично. Хотя вообще говоря должно быть наоборот, получение числа с плавающей запятой должно быть основано на генерации (псевдо)случайного целого. -
[SoC] Ковыряемся в файлах
Malandrinus ответил на тему форума автора Halford в Скрипты / конфиги / движок
Gaz24, вариант первый. Создаешь с помощью аллспавна изношенный предмет на уровне. В апдейте ставишь проверку: если не установлена инфопорция и на уровне есть предмет, то перенести его в инвентарь и установить инфопорцию. вариант второй. Та же проверка на инфопорцию для разового запуска (можно уже не в апдейте, а скажем в netspawn), но вместо переноса готового предмета с уровня, спавнишь прямо в инвентарь, прописывая износ нетпакетом. Может конечно есть способы решить эту задачу без заморочек стандартными средствами, но я таких не знаю, а гуглить лень. -
[SoC] Ковыряемся в файлах
Malandrinus ответил на тему форума автора Halford в Скрипты / конфиги / движок
SkyLoader, смена визуала для онлайнового объекта? Можно наверно, но это ещё одна правка движка. Я уж тогда точно на основе машинки стал бы делать. Вот так всегда кстати. Идея красивая, а реализация упирается в множество неприятных подробностей. -
[SoC] Ковыряемся в файлах
Malandrinus ответил на тему форума автора Halford в Скрипты / конфиги / движок
Priboj37, в смысле, чтобы в худовой модели тренога была? Это не будет нормально выглядеть. Пулемёт вращается вокруг треноги, а худовое оружие - вместе с актором. Тренога не будет стоять на месте. -
[SoC] Ковыряемся в файлах
Malandrinus ответил на тему форума автора Halford в Скрипты / конфиги / движок
SkyLoader, У этого объекта нет худа. Когда актор к нему аттачится, он использует мировую модель. Так что убрать её не получится.
- [ЧН] OGSM CS 1.8 CE Fixes
- [ЧН] HARDWARMOD 3.2
- [ЗП] The Long Road
- [ЧН] New vision of War
- [ЧН] Old Good Stalker Mod - Clear Sky
- [ЗП] Unofficial Patch
- [ЗП] Смерти вопреки
- [ЗП] Контракт на хорошую жизнь
- [ЗП] Shoker Weapon Mod 2.1
- [ЗП] Hardcore pack for SGM 2.2
- [ЗП] Контракт Синдиката
- [ЗП] Клондайк 2.0
- ...и другие моды