Скриптовая интеграция IgdrasilECS
IgdrasilECS предоставляет чистые ECS-модули для скриптов без привязки к сценам. Все операции со сценой (добавление сущностей в активную сцену, загрузка/выгрузка сцен, управление системами сцены) вынесены в модули IgdrasilSceneSystem.
Модули
IgdrasilEngine.Engine.Scripting.Modules.ECS
- ECSModule // сущности и компоненты (scene-agnostic)
- ECSComponentFactoryModule // динамическое создание и рефлексию компонентов
- ECSEventsModule // события сущности и компонентов
- ECSModuleBundle // регистрация всех ECS-модулей
// ECSSystemModule — deprecated, не подключается
Быстрый старт
using IgdrasilEngine.Engine.Scripting.Lua;
using IgdrasilEngine.Engine.Scripting.Modules.ECS;
using IgdrasilEngine.Engine.Scripting.Modules.SceneManagement;
// Движок скриптинга
var engine = new LuaEngine();
// Регистрируем ECS-модули (scene-agnostic)
ECSModuleBundle.RegisterModules<LuaModuleInterface>(
engine,
typeof(MyComponent).Assembly // сборки с вашими компонентами
);
// (Опционально) регистрируем сценовые модули для работы с текущей сценой
SceneModuleBundle.RegisterModules<LuaModuleInterface>(engine);
ECS Module (ecs)
Чистые операции над сущностями и компонентами. Модуль не хранит коллекцию сущностей: вы создаёте их и сами решаете, где хранить (обычно — добавить в активную сцену через scene.addEntityToScene).
Сущности
local ecs = require("ecs")
local player = ecs.createEntity("Player")
player.IsActive = true
-- потом добавьте в сцену: scene.addEntityToScene(player)
Компоненты
-- добавление / удаление
ecs.addComponent(player, health)
ecs.removeComponent(player, health)
-- получение/проверка по типу
local health = ecs.getComponent(player, HealthComponentType)
local has = ecs.hasComponent(player, HealthComponentType)
local many = ecs.getComponents(player, HealthComponentType)
local all = ecs.getAllComponents(player)
-- работа с тегами
ecs.addComponentWithTag(player, "health", health)
local tagged = ecs.getComponentByTag(player, "health")
ecs.removeComponentByTag(player, "health")
local tags = ecs.getComponentTags(player)
Factory Module (ecs.factory)
Динамическое создание компонентов через рефлексию.
local factory = require("ecs.factory")
local health = factory.createComponent("HealthComponent")
local transform = factory.createComponentWithParams("TransformComponent", {0, 0})
-- поля
local fields = factory.getComponentFields(health)
factory.setComponentField(health, "currentHealth", 100)
local hp = factory.getComponentField(health, "currentHealth")
-- свойства
local props = factory.getComponentProperties(health)
factory.setComponentProperty(health, "MaxHealth", 150)
local max = factory.getComponentProperty(health, "MaxHealth")
-- типы
local names = factory.getAllComponentTypeNames()
Events Module (ecs.events)
События на уровне сущности и компонентов.
local events = require("ecs.events")
-- сущность: добавление/удаление компонентов
local cbAdd = events.onComponentAdded(player, function(comp) print("added") end)
local cbRem = events.onComponentRemoved(player, function(comp) print("removed") end)
events.offComponentAdded(player, cbAdd)
events.offComponentRemoved(player, cbRem)
-- компонент: произвольные изменения
local sub = events.subscribeComponentChange(health, function(comp) print("changed") end)
events.invokeComponentChange(health)
events.unsubscribeComponentChange(health, sub)
Взаимодействие со сценой
ECS-модули не знают о сценах. Чтобы работать с активной сценой (добавлять сущности, получать списки сущностей и систем, загружать/выгружать сцены), используйте модули из IgdrasilSceneSystem:
scene(SceneModule) загрузка/выгрузка, сущности и системы активной сценыscene.events(SceneEventsModule) события загрузки/выгрузки сцен
Пример добавления сущности в сцену:
local ecs = require("ecs")
local scene = require("scene")
local e = ecs.createEntity("Player")
scene.addEntityToScene(e) -- теперь сущность участвует в сцене
Советы по производительности
- Кешируйте ссылки на компоненты вместо повторных поисков.
- Используйте теги для быстрого доступа к часто используемым компонентам.
- Минимизируйте число подписок — подписывайтесь только там, где нужна реакция.
- При массовых операциях группируйте изменения (батчинг) перед вызовом событий.