Как поделиться / повторно использовать скрипт Lua для нескольких объектов?
Я нахожусь на этапе проектирования / скелетного кодирования моей игры на C++ со сценариями Lua, но я столкнулся с проблемой проектирования:
В игре будет много копий однотипных сущностей, поведение которых контролируется одним и тем же сценарием. Есть ли простой способ поделиться сценарием между объектами одного типа в одном lua_state? Мне удалось найти этот вопрос только пару раз в Интернете; Я читал смешанные отзывы о том, стоит ли загружать один и тот же скрипт в разных lua_state, а не подробные отзывы об альтернативах.
Это просто и пуленепробиваемо, но я думаю, что загрузка, компиляция и хранение дополнительных копий одного и того же байтового кода с каждым экземпляром одного и того же созданного типа сущности - трагическая трата, поэтому я хотел бы найти более разумное решение.
Это два решения, о которых я подумал. Я не новичок в программировании или в концепциях C или OO, но я все еще учусь, когда дело доходит до Lua и особенно Lua/C API. Я думаю, что мои идеи верны, но я даже не уверен, как бы я их реализовал.
Реализуйте OO в сценарии Lua и пусть каждый объект будет представлен объектом Lua; вся логика Lua будет действовать на объект. Это также будет иметь выгоду (или "выгоду") от возможности изменения глобальной среды каким-либо отдельным объектом.
Инкапсулируйте каждый объект в его собственном окружении, используя setfenv, и скопируйте ссылки всех функций из глобального пространства. Насколько я понимаю, env - это просто таблица, отличная от глобальной, используемой по умолчанию, но я изучил setfenv, но не знаю, как мне это сделать.
1 ответ
1 и 2 - просто разные стороны одной медали, более или менее. Это просто вопрос, куда уходит объект. В типе 1 объект является явной частью сценария Lua. Это означает, что скрипт решает, как он хочет настроить свои объекты.
В типе 2 объектом является среда. Это все еще таблица Lua, но созданная для нее внешним кодом. Скрипт не может вырваться за пределы этого объекта, кроме как способами, которые позволяет внешний код.
Для меня проще всего реализовать тип 1 с помощью Luabind. У меня был бы объект AI в виде класса C++, из которого Lua могла бы получить производные. Запуск "основного сценария" для этого ИИ создаст экземпляр этого класса. Вы должны передать параметры скрипта, такие как имя объекта, которым он управляет, возможно, ссылку, которую он может использовать для управления им и т. Д.
Тип 2 довольно прост. Сначала вы создаете новую среду, создавая пустую таблицу и заполняя ее глобальными переменными, к которым у пользователя должен быть доступ. Это может быть связано с такими вещами, как разговор с игровым состоянием (поиск других объектов на сцене и т. Д.), Способы перемещения рассматриваемой сущности и т. Д. Существуют метатические приемы, которые вы можете использовать, чтобы сделать эти значения неизменными и постоянными, чтобы пользователь не мог изменить их позже.
Затем вы загружаете скрипт с lua_loadstring
или же lua_loadfile
, Это помещает функцию в стек Lua, которая представляет этот скрипт Lua. Затем вы применяете эту таблицу в качестве среды этой функции сценария с lua_setfenv
, Затем вы можете запустить этот скрипт, передавая любые переменные, которые вы пожелаете (имя объекта и т. Д.).