Перейти к контенту

Язык Lua. Общие вопросы программирования


Malandrinus

Рекомендуемые сообщения

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

Для начала интересный факт, не все знают. Частота вызова апдейта актора в игре абсолютно точно совпадает с частотой 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 ядер, 5.7ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

Поделиться этим сообщением


Ссылка на сообщение
(изменено)

Artos

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

А за поправки и уточнения спасибо :)

Вариант "елочка" довольно интересен, но, с другой стороны, когда допустим будут выполнены действия 1200 мс, то и 300мс, и 100мс будут выполнены в тот же такт. А это уже может привести к изрядному подвисанию, если там что-то тяжелое. Несколько независимых таймеров можно подстроить так, что их частоты не будут кратны друг другу. Например, 100мс, 260, 1170, и т.д.. нагрузка на цп будет распределяться равномернее. А в варианте "елочка" пики нагрузки неизбежны.

 

Раньше не писал - потому что меня не было на форуме. Работа.

Позвольте, разве я для себя пишу? :) Ни в коей мере.

Ну и наконец. Да, к Lua это отношения не имеет никакого. Я применял точно такой же прием, когда писал код в Delphi. Но думаю, от этого он не становится менее полезным.

 

Изменено пользователем Zander_driver

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine.

Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист.

AMD Ryzen 9 7950X (16 ядер, 5.7ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

Поделиться этим сообщением


Ссылка на сообщение

Заранее прошу прощения за запоздалый ответ - раньше не было возможности, и за, по сути, оффтоп. Я думаю, этот мой пост стоит удалить после прочтения заинтересованными лицами.

 

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 ядер, 5.7ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

Поделиться этим сообщением


Ссылка на сообщение

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

Короче, имеем некоторую таблицу. Для этой таблицы вызывается цикл:

    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 ядер, 5.7ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

Поделиться этим сообщением


Ссылка на сообщение

ВНИМАНИЕ, var - результат return без аргумента.

а разве return без аргумента - не то же самое что return nil ?

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine.

Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист.

AMD Ryzen 9 7950X (16 ядер, 5.7ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

Поделиться этим сообщением


Ссылка на сообщение

Вопрос. Какие проблемы могут быть (и будут ли?) если в файлах луа-скрипта присутствует текст кириллицы. не в названиях функций или переменных само собой, а к примеру так:

local t = "Текст кириллицей"

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine.

Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист.

AMD Ryzen 9 7950X (16 ядер, 5.7ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

Поделиться этим сообщением


Ссылка на сообщение

@Nazgool, В основном у меня такие вещи для вывода текста на статик. Ну еще бывает с ними перед этим string.format работает.

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine.

Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист.

AMD Ryzen 9 7950X (16 ядер, 5.7ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

Поделиться этим сообщением


Ссылка на сообщение

@Solomon753, Всем будет гораздо проще, если вы опишете задачу которую пытаетесь решить.

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine.

Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист.

AMD Ryzen 9 7950X (16 ядер, 5.7ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

Поделиться этим сообщением


Ссылка на сообщение

 

 

Мне скинули сборку для ТЧ специально для моего будущего мода и сказали мол , что она не выделяется стабильностью

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

  • Нравится 1

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine.

Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист.

AMD Ryzen 9 7950X (16 ядер, 5.7ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

Поделиться этим сообщением


Ссылка на сообщение

Что более жалко терять, свой будущий мод или какой-то патч...

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine.

Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист.

AMD Ryzen 9 7950X (16 ядер, 5.7ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

Поделиться этим сообщением


Ссылка на сообщение

 

 

Т.е. я использую ДА, НЕТ и НЕ ЗНАЮ. Вот nil - это и есть это самое НЕ ЗНАЮ.

Напомнило комичный случай из личной практики :) когда начинал писать "скриптовый интерфейс" - он был только инвентарем, и ничем больше. Потом туда же добавилось окно обыска - потребовалось указать при создании интерфейса, что же рисовать. Добавил к входным аргументам еще один. Если он ~= nil - рисуем окно обыска.

Потом туда же добавилось ПДА. Потребовалось выяснять еще значение этого аргумента.

В итоге интерфейс рисуется по принципу:

Нарисовать окно обыска?

 -> Если да (true), рисуем окно обыска

 -> Если нет (false), рисуем пда

 -> Если не известно (nil), рисуем инвентарь.

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

 

 

 

а undefined "я в душе не гребу, что это за переменная, и откуда она взялась"

И почему я не пишу на JavaScript, он мне уже заочно нравится :)

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine.

Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист.

AMD Ryzen 9 7950X (16 ядер, 5.7ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

Поделиться этим сообщением


Ссылка на сообщение

И чем дальше будут продвигаться успехи двиглоправов, тем больше там будет таких подводных камней сюрпризов, надо полагать?

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine.

Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист.

AMD Ryzen 9 7950X (16 ядер, 5.7ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

Поделиться этим сообщением


Ссылка на сообщение

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

Например:

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 ядер, 5.7ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

Поделиться этим сообщением


Ссылка на сообщение

 

 

v:normalize() и v:set_length( 1 ) - это таки одно и тоже, или таки нет ?

По смыслу должно быть то же.

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine.

Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист.

AMD Ryzen 9 7950X (16 ядер, 5.7ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

Поделиться этим сообщением


Ссылка на сообщение

Не уверен я, куда этот вопрос писать, но попробую сюда.

Вопрос про объявление и наследование классов в 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 ядер, 5.7ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

Поделиться этим сообщением


Ссылка на сообщение
  • Недавно просматривали   0 пользователей

    Ни один зарегистрированный пользователь не просматривает эту страницу.

AMK-Team.ru

×
×
  • Создать...