Zander_driver 10 333 Опубликовано 27 Сентября 2011 Выскажу свой совет по оптимизации скриптов именно применительно к игре. Может быть, это будет из разряда "Капитан очевидность рекомендует", но я своих методов в других модах пока не встретил, так что думаю начинающим скриптерам будет полезно. Для начала интересный факт, не все знают. Частота вызова апдейта актора в игре абсолютно точно совпадает с частотой fps. Т.е., на разных машинах эта частота будет ооочень разной. Очень часто модостроителю нужно что-то свое поставить в апдейт, иногда хочется поставить и что-то довольно ресурсоемкое. Но - тем самым мы снижаем fps. На слабых машинах это приведет к невозможности играть вообще. Как же быть? Я поступил следующим образом: в bind_stalker-e в функции actor_binder:update(delta) вызываю свой апдейтер twoteam.actor_update(self, delta) А сам апдейтер организую таким образом local time_100 = 0 local time_300 = 0 local time_1200 = 0 local time_5000 = 0 function actor_update(actor, delta) --- Действия, которые надо производить с частотой fps time_100 = time_100 + delta if time_100 > 100 then --- Действия, которые надо производить с частотой раз в 100мс time_100 = 0 end time_300 = time_300 + delta if time_300 > 300 then --- Действия, которые надо производить с частотой раз в 300мс time_180 = 0 end time_1200 = time_1200 + delta if time_1200 > 1200 then --- Действия, которые надо производить с частотой раз в 1200мс time_1200 = 0 end time_5000 = time_5000 + delta if time_5000 > 5000 then --- Действия, которые надо производить с частотой раз в 5 секунд time_5000 = 0 end end Какие периоды срабатывания ставить, и сколько делать таких под-апдейтеров, каждый сам для себя решит исходя из практических целей. Плюс в том, что какое-то ресурсоемкое действие можно поставить, скажем, в обработку раз в 1200 мс. Допустим оно занимает 100 мс. Оно будет выполнено, несущественно повлияв на производительность (снижение среднего fps менее 10%). А если бы мы поставили это действие прямо в "родной" апдейт, получили бы fps = 10 или менее. А это уже на грани неиграбельности, согласитесь На самом деле, среди всех тех вещей которые обычно пихают в апдейт актора, бОльшую часть совсем не обязательно делать так часто. Может быть это только мне так кажется, но вначале темы обсуждение идет... немного не по теме. Позволю себе цитату Здесь предлагается обсуждать язык Lua, его синтаксические особенности, производительность, приёмы использования стандартные и не очень. Также здесь предлагается постить примеры алгоритмов для решения разных достаточно общих задач, по возможности не сильно привязанных к игре. Вместо означенного - видим обсуждение редакторов, как и что в них можно делать и т.д. Не спорю информация полезная, но во-первых, она пока что разбросана по капле по многим постам, а во вторых... боже мой, я до сего дня вообще не знал тех вещей, которые тут обсуждались. Сидел себе на Notepad-e и горя не знал. Наверно, я неправильный скриптер, или не скриптер совсем? Это к тому, что пока большая часть темы представляет практический интерес не для всех, кто считает себя скриптерами... 1 Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine. Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист. AMD Ryzen 9 7950X (16 ядер, 32 потока, 5.75 ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD. Поделиться этим сообщением Ссылка на сообщение
Zander_driver 10 333 Опубликовано 27 Сентября 2011 (изменено) Artos Ну насчет того, что мой пост был бы уместнее "Скриптовании", поспорю. По некоторым причинам это может и так, но там ведется общение по системе вопрос-ответ, И вряд ли кто-то бы задал вопрос именно об этом, т.к. начинающие модеры обычно делают по принципу "у меня работает - значит нормально". Мой же пост скорее является рекомендацией по организации кода, чтобы работало не только у себя любимого, но и у других. А за поправки и уточнения спасибо Вариант "елочка" довольно интересен, но, с другой стороны, когда допустим будут выполнены действия 1200 мс, то и 300мс, и 100мс будут выполнены в тот же такт. А это уже может привести к изрядному подвисанию, если там что-то тяжелое. Несколько независимых таймеров можно подстроить так, что их частоты не будут кратны друг другу. Например, 100мс, 260, 1170, и т.д.. нагрузка на цп будет распределяться равномернее. А в варианте "елочка" пики нагрузки неизбежны. Раньше не писал - потому что меня не было на форуме. Работа. Позвольте, разве я для себя пишу? Ни в коей мере. Ну и наконец. Да, к Lua это отношения не имеет никакого. Я применял точно такой же прием, когда писал код в Delphi. Но думаю, от этого он не становится менее полезным. Изменено 27 Сентября 2011 пользователем Zander_driver Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine. Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист. AMD Ryzen 9 7950X (16 ядер, 32 потока, 5.75 ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD. Поделиться этим сообщением Ссылка на сообщение
Zander_driver 10 333 Опубликовано 29 Сентября 2011 Заранее прошу прощения за запоздалый ответ - раньше не было возможности, и за, по сути, оффтоп. Я думаю, этот мой пост стоит удалить после прочтения заинтересованными лицами. Artos. Вот же вы. Вроде как, модостроитель с опытом побольше моего. Однако шоры и у вас есть - слишком уж вы предпочитаете теоретический подход к скриптам, и в данном случае, забыв о практике, совершили ошибку. Мой пример с асинхронными таймерами был для наглядности. Мои собственные таймеры по 100, 300 и 1200 - асинхронны ТОЖЕ. Как же так? Всмотритесь в код внимательнее и подумайте, как он выполняется. Подсчет прошедшего времени ведется по delta. это период времени в миллисекундах, прошедший с прошлого апдейта. В каждом апдейте к таймерам прибавляется delta, и если набралось больше заданного предела - таймер срабатывает. И все ваши рассуждения были бы верны, если бы delta была равна 1. всегда. Но это возможно только если fps = 1000. Едва ли много у кого есть компьютеры столь монструозной мощи, чтобы тянуть сталкер ТЧ на такой скорости. А на практике у среднего игрока средний fps лежит в пределах нескольких десятков, причем это очень переменная величина даже на одной машине. При fps ~ 60 имеем delta ~ 16. И что же в таком случае происходит? 1-й такт. timer_100 = 0, timer_300 = 0, timer_1200 = 0 прибавляем ко всем таймерам по отдельности нашу delta. Будем хоть тут считать, что она постоянна и равна 16. 2-й такт timer_100 = 16, timer_300 = 16, timer_1200 = 16 3-й такт timer_100 = 32, timer_300 = 32, timer_1200 = 32 4-й такт timer_100 = 48, timer_300 = 48, timer_1200 = 48 5-й такт timer_100 = 64, timer_300 = 64, timer_1200 = 64 6-й такт timer_100 = 80, timer_300 = 80, timer_1200 = 80 7-й такт timer_100 = 96, timer_300 = 96, timer_1200 = 96 8-й такт timer_100 = 112, timer_300 = 112, timer_1200 = 112 в первом таймере выполняется условие. Выполняем его действия и обнуляем таймер, теперь timer_100 = 0 9-й такт timer_100 = 16, timer_300 = 128, timer_1200 = 128 пропустим 6 тактов, в которые не происхоит ничего особенного, прибавим ко всем таймерам по 6*16=96 15-й такт timer_100 = 112, timer_300 = 224, timer_1200 = 224 В первом таймере опять выполняется условие. Он опять выполняется и обнуляется, timer_100 = 0 16-й такт timer_100 = 16, timer_300 = 240, timer_1200 = 240 На этот раз пропустим всего 4 такта. Прибавим везде по 4*16 = 64 20-й такт timer_100 = 80, timer_300 = 304, timer_1200 = 304 Вот и ваша ошибка. timer_300 выполнил условие и сработал, а timer_100 - еще нет. Где же ваша синхронность? А нет ее. timer_300 обнуляется 21-й такт timer_100 = 96, timer_300 = 16, timer_1200 = 320 22-й такт timer_100 = 112, timer_300 = 32, timer_1200 = 336 Вот теперь наконец сработал timer_100. Через два такта после своего соседа. При желании можете продолжить самостоятельно, Чем дальше в лес - тем больше расхождение таймеров, и timer_1200 так же не будет синхронным с timer_300. Прибавьте к этому тот факт что fps, а следовательно и delta - постоянно меняются. Поэкспериментировав со значениями, увидите что чем больше delta чем ниже fps, тем сильнее расхождения. Т.е. рассинхронизация таймеров в данном случае происходит скорее именно там, где она нужна - на слабых машинах. p.s. Вам бы самому не мешало иногда перечитывать свои слова, и не выдавать свои размышления за истину в последней инстанции. Пусть они основаны на теории, которая вам кажется верной. Может я и ошибся, но Все твои таймеры имеют одну и ту же стартовую установку (0) Это означает, что ВСЕ они работают СИНХРОННО, и когда сработает таймер 1200, в это же время сработает и таймер 300 и таймер 100. Сделав вроде как несколько "независимых" таймеров - по сути ты просто продублировал один и тот же, только задав различные периоды. И в любом случае при кратности периодов - таймеры будут запускать ведомые функции единовременно. Заинтересовавший тебя вариант "елочка" НИЧЕМ не отличается от твоего же, только оптимизирован с целью исключения лишник операция по сложению и сравнению. Твой вариант точно также будет запускать все вызовы так же как и "елочка", т.е. единовременно. выглядит именно как преподнесение такой "истины". Потому и ввязался в, по сути флейм - просто не люблю неверных утверждений на страницах подобных тем. Увидел - оспорил, да простят меня форумчане (я надеюсь). p.p.s. И совсем уж переходя на личности... Artos, помоему вы очень любите спорить Хотя я и сам такой... Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine. Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист. AMD Ryzen 9 7950X (16 ядер, 32 потока, 5.75 ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD. Поделиться этим сообщением Ссылка на сообщение
Zander_driver 10 333 Опубликовано 9 Октября 2012 Наткнулся на ситуацию, наводящую на мысли что я чего-то важного не знаю... что надо было знать в этом случае. Или может я сошел с ума Короче, имеем некоторую таблицу. Для этой таблицы вызывается цикл: for k,v in pairs(I_List) do local ControlName = self.StoF(k) if ControlName then local bth = CUIButton() btn:SetAutoDelete(true) btn:SetWindowName(ControlName) --- ! ПОЛУЧИТЬ РАЗМЕР ТЕКСТУРЫ local btn_width = ltx:r_float(k, "inv_grid_width") * 50 local btn_height = ltx:r_float(k, "inv_grid_height") * 50 next_x = next_x + btn_width if next_x > 300 then next_x = 0 valid_x = 0 valid_y = valid_y + 50 if valid_y > 400 then --- error! news_manager.send_tip(db.actor, "Inventory Over!", nil, nil, 3000) end end btn:Init(ControlName, valid_x + base_x, valid_y + base_y, btn_width, btn_height) valid_x = valid_x + btn_width next_x = valid_x self:Register(btn) self.main_frame:AttachChild(btn) end end При этом, непосредственно перед циклом содержимое таблицы выводится в лог: { [KEY: STRING:ammo_12x70_buck] = VALUE: TABLE:; Table value: { [KEY: NUMBER:1] = VALUE: TABLE:; Table value: { [KEY: NUMBER:1] = VALUE: NUMBER:17664; [KEY: NUMBER:2] = VALUE: NUMBER:1; [KEY: NUMBER:3] = VALUE: NUMBER:12; } [KEY: NUMBER:2] = VALUE: TABLE:; Table value: { [KEY: NUMBER:1] = VALUE: NUMBER:17665; [KEY: NUMBER:2] = VALUE: NUMBER:1; [KEY: NUMBER:3] = VALUE: NUMBER:12; } [KEY: NUMBER:3] = VALUE: TABLE:; Table value: { [KEY: NUMBER:1] = VALUE: NUMBER:17666; [KEY: NUMBER:2] = VALUE: NUMBER:1; [KEY: NUMBER:3] = VALUE: NUMBER:12; } [KEY: NUMBER:4] = VALUE: TABLE:; Table value: { [KEY: NUMBER:1] = VALUE: NUMBER:17667; [KEY: NUMBER:2] = VALUE: NUMBER:1; [KEY: NUMBER:3] = VALUE: NUMBER:12; } [KEY: NUMBER:5] = VALUE: TABLE:; Table value: { [KEY: NUMBER:1] = VALUE: NUMBER:17668; [KEY: NUMBER:2] = VALUE: NUMBER:1; [KEY: NUMBER:3] = VALUE: NUMBER:12; } [KEY: NUMBER:6] = VALUE: TABLE:; Table value: { [KEY: NUMBER:1] = VALUE: NUMBER:17669; [KEY: NUMBER:2] = VALUE: NUMBER:1; [KEY: NUMBER:3] = VALUE: NUMBER:12; } [KEY: NUMBER:7] = VALUE: TABLE:; Table value: { [KEY: NUMBER:1] = VALUE: NUMBER:17670; [KEY: NUMBER:2] = VALUE: NUMBER:1; [KEY: NUMBER:3] = VALUE: NUMBER:12; } [KEY: NUMBER:8] = VALUE: TABLE:; Table value: { [KEY: NUMBER:1] = VALUE: NUMBER:17671; [KEY: NUMBER:2] = VALUE: NUMBER:1; [KEY: NUMBER:3] = VALUE: NUMBER:12; } [KEY: NUMBER:9] = VALUE: TABLE:; Table value: { [KEY: NUMBER:1] = VALUE: NUMBER:17672; [KEY: NUMBER:2] = VALUE: NUMBER:1; [KEY: NUMBER:3] = VALUE: NUMBER:12; } [KEY: NUMBER:10] = VALUE: TABLE:; Table value: { [KEY: NUMBER:1] = VALUE: NUMBER:17673; [KEY: NUMBER:2] = VALUE: NUMBER:1; [KEY: NUMBER:3] = VALUE: NUMBER:12; } } } Как видим, в таблице есть один элемент, ключ его - строка ammo_12x70_buck, значение - таблица из 10 подтаблиц. Вроде бы все нормально? А вот функция которая вызывается в цикле строкой self.StoF: function ammo_cargo_space:StoF(section) if not section then log("NIL НА ВХОДЕ!!!") return end local c1 = string.gsub(section, ".", "") return string.gsub(c1, "-", "") end И вот она следом за парсингом нормально заполненной таблицы, выдает в лог вопль что у нее nil на входе. Каким образом это возможно если ей передается ключ таблицы? Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine. Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист. AMD Ryzen 9 7950X (16 ядер, 32 потока, 5.75 ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD. Поделиться этим сообщением Ссылка на сообщение
Zander_driver 10 333 Опубликовано 23 Сентября 2014 ВНИМАНИЕ, var - результат return без аргумента. а разве return без аргумента - не то же самое что return nil ? Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine. Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист. AMD Ryzen 9 7950X (16 ядер, 32 потока, 5.75 ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD. Поделиться этим сообщением Ссылка на сообщение
Zander_driver 10 333 Опубликовано 4 Октября 2014 Вопрос. Какие проблемы могут быть (и будут ли?) если в файлах луа-скрипта присутствует текст кириллицы. не в названиях функций или переменных само собой, а к примеру так: local t = "Текст кириллицей" Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine. Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист. AMD Ryzen 9 7950X (16 ядер, 32 потока, 5.75 ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD. Поделиться этим сообщением Ссылка на сообщение
Zander_driver 10 333 Опубликовано 8 Октября 2014 @Nazgool, В основном у меня такие вещи для вывода текста на статик. Ну еще бывает с ними перед этим string.format работает. Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine. Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист. AMD Ryzen 9 7950X (16 ядер, 32 потока, 5.75 ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD. Поделиться этим сообщением Ссылка на сообщение
Zander_driver 10 333 Опубликовано 3 Декабря 2014 @Solomon753, Всем будет гораздо проще, если вы опишете задачу которую пытаетесь решить. Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine. Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист. AMD Ryzen 9 7950X (16 ядер, 32 потока, 5.75 ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD. Поделиться этим сообщением Ссылка на сообщение
Zander_driver 10 333 Опубликовано 6 Июня 2016 Мне скинули сборку для ТЧ специально для моего будущего мода и сказали мол , что она не выделяется стабильностью Тогда можешь считать что тебе ничего не скинули. Основа, то на чем разработка держится как на фундаменте - должна быть стабильна как железнодорожное полотно. Если такой нет, лучше брать за основу оригинал. 1 Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine. Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист. AMD Ryzen 9 7950X (16 ядер, 32 потока, 5.75 ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD. Поделиться этим сообщением Ссылка на сообщение
Zander_driver 10 333 Опубликовано 6 Июня 2016 Что более жалко терять, свой будущий мод или какой-то патч... Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine. Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист. AMD Ryzen 9 7950X (16 ядер, 32 потока, 5.75 ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD. Поделиться этим сообщением Ссылка на сообщение
Zander_driver 10 333 Опубликовано 8 Июня 2016 Т.е. я использую ДА, НЕТ и НЕ ЗНАЮ. Вот nil - это и есть это самое НЕ ЗНАЮ. Напомнило комичный случай из личной практики когда начинал писать "скриптовый интерфейс" - он был только инвентарем, и ничем больше. Потом туда же добавилось окно обыска - потребовалось указать при создании интерфейса, что же рисовать. Добавил к входным аргументам еще один. Если он ~= nil - рисуем окно обыска. Потом туда же добавилось ПДА. Потребовалось выяснять еще значение этого аргумента. В итоге интерфейс рисуется по принципу: Нарисовать окно обыска? -> Если да (true), рисуем окно обыска -> Если нет (false), рисуем пда -> Если не известно (nil), рисуем инвентарь. Выглядит забавно, переписать более нормально руки не доходят, так и работает а undefined "я в душе не гребу, что это за переменная, и откуда она взялась" И почему я не пишу на JavaScript, он мне уже заочно нравится Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine. Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист. AMD Ryzen 9 7950X (16 ядер, 32 потока, 5.75 ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD. Поделиться этим сообщением Ссылка на сообщение
Zander_driver 10 333 Опубликовано 17 Октября 2016 И чем дальше будут продвигаться успехи двиглоправов, тем больше там будет таких подводных камней сюрпризов, надо полагать? Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine. Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист. AMD Ryzen 9 7950X (16 ядер, 32 потока, 5.75 ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD. Поделиться этим сообщением Ссылка на сообщение
Zander_driver 10 333 Опубликовано 14 Ноября 2016 Ну в данном случае, так и делается.В некоторых случаях, если заранее известно что надо будет искать определенный элемент таблицы, проверять есть ли такой или нету, можно записывать данные не в значения, а в ключи таблицы. Например: local tbl = {} tbl["text_1"] = true tbl["text_2"] = true if tbl.text_1 then -- Наши действия... end Плюс такой конструкции в отсутствии цикла, но это не всегда применимо, требуется изначально затачивать таблицу под такие действия. 1 Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine. Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист. AMD Ryzen 9 7950X (16 ядер, 32 потока, 5.75 ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD. Поделиться этим сообщением Ссылка на сообщение
Zander_driver 10 333 Опубликовано 5 Февраля 2017 v:normalize() и v:set_length( 1 ) - это таки одно и тоже, или таки нет ? По смыслу должно быть то же. Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine. Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист. AMD Ryzen 9 7950X (16 ядер, 32 потока, 5.75 ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD. Поделиться этим сообщением Ссылка на сообщение
Zander_driver 10 333 Опубликовано 19 Ноября 2020 Не уверен я, куда этот вопрос писать, но попробую сюда. Вопрос про объявление и наследование классов в Lua, c Luabind-ом из OGSR. Скрытый текст Код примерно такой структурно class "A" function A:__init() end function A:__finalize() end *** class "B" (A) function B:__init (...) super() self.params = {...} end *** class "C" (B) function C:__init (...) super(...) end *** class "D" (C) function D:__init (...) super(...) end *** class "E" (D) function E:__init (...) super(...) end *** class "F" (E) function F:__init (...) super(...) end *** // и т.д. function Create() same_object = G_script.G(...) end -- Где '***' - обозначают разные файлы... Возвращает примерно такой лог [19.11.20 15:41:07.174] expected class [B] to derive from or a newline [19.11.20 15:41:07.181] ***************************[ScriptCrashHandler]********************************** [19.11.20 15:41:07.181] stack traceback: [C]: at 0x018000bee4 ....a.l.k.e.r_ogsr\gamedata\scripts\script_B.script:20: in main chunk [C]: in function '__index' ....e.r_ogsr\gamedata\scripts\script_C.script:15: in main chunk [C]: in function '__index' ...a.l.k.e.r_ogsr\gamedata\scripts\script_D.script:15: in main chunk [C]: in function '__index' ....a.l.k.e.r_ogsr\gamedata\scripts\script_E.script:15: in main chunk [C]: in function '__index' ...a.l.k.e.r_ogsr\gamedata\scripts\script_F.script:15: in main chunk [C]: in function '__index' ....a.l.k.e.r_ogsr\gamedata\scripts\script_G.script:15: in main chunk [C]: in function '__index' ....t.a.l.k.e.r_ogsr\gamedata\scripts\subtask.script:270: in function 'Create' Где строка "expected class [ Х ] ... " неизменно указывает на тот класс, который является потомком класса, не имеющего родителей. Т.е. если например я C наследую от A - ругаться лог будет на C. Если же С наследует от B, B наследует от A, а для A я создам новый класс-родитель X. Так что А наследует от X, а X ни от кого - то ругаться будет на A. Разве я не могу наследовать от скриптовых классов? Если сам по себе скриптовый класс (т.е. просто вот это:) class "same" function same:__init() ... end function same:method0() ... end , etc... Исправно работает. Конструкции вроде биндеров class "actor_binder" (object_binder) function actor_binder:__init (obj) super(obj) ... Тоже работают, наследуя от классов, объявленных в движке. object_binder в данном случае. А от скриптового наследовать нельзя? * * * По-копавшись, обнаружил искомое в старом m_netpk.script, артосо-модуль т.е. Там объявлен class "net_base" - не наследующий ни от кого, и от него наследуются другие классы. Т.е. там это работало, хотя модуль не под OGSR создавался. А тут? Что я делаю не так, или что надо делать не так, объявляя наследование классов друг от друга в скриптах под OGSR. Проясните, кто в курсе. Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine. Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист. AMD Ryzen 9 7950X (16 ядер, 32 потока, 5.75 ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD. Поделиться этим сообщением Ссылка на сообщение
Zander_driver 10 333 Опубликовано 13 Мая 10.05.2024 в 20:02, Личность сказал: Почему нет статьи про анимации? Раньше точно были... Если на пальцах, в сталкере анимация это некая последовательность данных записанная в модель. В современных движках вроде OGSR, есть методы вызова нужной анимации по имени, у определенного объекта. Были ли они в оригинальном движке ТЧ, честно говоря не помню. Если были, то их должно быть возможно найти тут. Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine. Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист. AMD Ryzen 9 7950X (16 ядер, 32 потока, 5.75 ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD. Поделиться этим сообщением Ссылка на сообщение