Как реализовать скриптинг и компиляцию игр в игровом движке с использованием c++?
Я написал простейший игровой движок и теперь думаю как организовать систему скриптов и компиляцию конечной игры как в unity или unreal engine с использованием c++ в качестве скриптового языка. Для использования скриптов в редакторе я планирую компилировать пользовательские классы в dll и парсить их чтобы знать какие есть переменные и методы. Но как действовать на этапе создания исполняемого файла конечного приложения? Использование каждого скрипта в виде отдельного dll создаёт много проблем. Какие есть варианты в данном случае? Можно ли как-то сделать класс библиотекой и встраивать и в нее пользовательские классы? Или есть более эффективные подходы?
LoliDeveloper, полностью устраивают, вопрос в том как организовать сам процесс. Движок должен быть библиотекой в которая вместе со скриптами компилируется в exe? Или можно как-нибудь объединить dll в один большой и тогда можно делать сразу exe из движка.
Anthony228357, Я конечно далеко не эксперт, но по моему тут всё зависит от размеров движка. Я когда писал свой, то у меня просто всё лежало в хедерах не скомпилированно. И по надобности я просто подключал нужные хедеры. Но это было очень давно, наверное вам не подойдёт такое. Использовать dll-ки гораздо эффективнее.
LoliDeveloper, это понятная система, я просто пытаюсь сделать как в Unity ,где ты просто пишешь пару методов, а движок сам определяет когда их вызвать.
LoliDeveloper, ну тип в том же unity есть start, awake,update, которые соответствуют определенному событию и вызываются при старте игры или при отрисовке кадра. А движок сам все инициализирует и создаёт цикл игры.
Я далек от игроделанья, но у вас на лицо просто иерархия классов с виртуальными методами.
Пользовательский скрипт для реализации своего функционала должен наследовать какой-то ваш класс и переопределять нужные ему методы. В реализации базового класса должна быть реализация базового функционала этих методов.
Ваш движок вызывает в нужных местах виртуальные методы базового класса, тем самым вызывается пользовательская реализация этих виртуальных методов.
Таким образом, не нужно парсить пользовательские скрипты - пользователь просто использует готовую иерархию классов вашего движка.
Классы могут импортироваться из DLL. Запихивать пользовательские скрипты в одну или несколько DLL - в принципе особой роли не играет. С одной DLL работать проще. Можно вообще не использовать DLL, а собирать один готовый исполняемый файл. Это все на ваше усмотрение, при правильной реализации все варианты рабочие.
res2001, а какие есть подходы для сборки готового файла? Просто движок можно собрать или в библиотеку или в исполняемый файл. Если библиотеку, то в нее нужно как-то впихнуть пользовательские классы, но вопрос в том как?
Anthony228357, Какая схема вам больше по душе ту и можно организовать.
1. Вы можете поставлять свой движок в виде исходного кода. Тогда просто добавляете пользовательский код в сборку и можно собрать монолитный исполняемый файл или динамическую библиотеку.
2. Если движок не хотите поставлять в исходном коде, то можете поставлять его в виде статической библиотеки и точно так же компоновать с пользовательским кодом, только движок в сборку будет добавляться на этапе линковки.
3. Движок в виде исполняемого файла или dll. Пользовательский код собирается в одну или несколько dll. Внутри движка реализована схема загрузки пользовательских библиотек (add-on/plugin).
res2001, с первым и третьим пунктом понятна реализация, а вот как реализуется компановка пользовательского кода и статической библиотеки? У пользователя будет только файлы с классом, а функция main будет внутри библиотеки и не будет ничего знать о классах пользователя. Разве есть какой-то способ вызывать функции в файлах с описанием класса?
Anthony228357, В любом случае движок не должен ничего знать о вышестоящем уровне (хоть в первом, хоть в третьем варианте), это вообще никак с компоновкой не связано. Если вы закладываетесь на то, что движок что-то там предполагает о пользовательском коде (или будет его анализировать каким-то образом), то это гиблое дело. Движку этого не нужно.
Пользовательский код будет знать об интерфейсе движка через файлы заголовков, где вся нужная информация для вызова методов и функций движка будет. Дальше вступают в действие наследование и виртуальные методы.
Разве есть какой-то способ вызывать функции в файлах с описанием класса?
Функции будут вызываться тогда, когда программа уже будет собрана и все зависимости удовлетворены. Пока вы пишите код и для компиляции достаточно информации (содержащейся в заголовках) о имени, типе возвращаемого значения и количестве и типе аргументов функций и методов.
При компиляции любых программ на С/С++, состоящих из нескольких файлов исходного кода, компилятор ВСЕГДА компилирует файлы по отдельности. При компиляции каждого конкретного файла компилятор ничего не знает о других файлах исходного кода и он в них не заглядывает. Это не касается файлов заголовков, которые подключаются внутри компилируемого файла исходного кода, их компилятор, конечно включает в сборку.
Только на этапе линковки полученные объектные файлы объединяются в один исполняемый файл, вот тогда линковщик и должен разрешить все зависимости. В случае второго варианта линковщик разрешит зависимости от движка, т.к. статическая библиотека движка будет участвовать в линковке. Точно так же линковщик найдет main() в статической библиотеке движка и успешно будет ее использовать.