-- ENTITY COMPONENT SYSTEM -- Created by Koldinium -- Licensed under 0BSD local M = {} -- Maintain one consistent global state across instances _G.__kold_ecs = _G.__kold_ecs or {} local globals = _G.__kold_ecs globals.entities = globals.entities or 0 globals.component_arrays = globals.component_arrays or {} globals.components = globals.components or {} globals.systems = globals.systems or {} function M.create_entity(components) local id = globals.entities + 1 for k,v in pairs(components) do globals.component_arrays[k][id] = globals.components[k](v) end return id end function M.delete_entity(id) for _,v in pairs(globals.component_arrays) do v[id] = nil end end function M.add_component_to_entity(entity, component_id, component_val) globals.component_arrays[component_id][entity] = globals.components[component_id](component_val) end function M.remove_component_from_entity(entity, component_id) globals.component_arrays[component_id][entity] = nil end function M.declare_system(query, system) table.insert(globals.systems, {query = query, system=system}) end function M.declare_component(component, initializer) globals.components[component] = initializer end function M.run_systems() for _,system in pairs(globals.systems) do local first_component_id = system.query[1] for id, component in globals.component_arrays[first_component_id] do if #system.query == 1 then system.system({component}) else local arg = {} for k,v in pairs(system.query) do if component_arrays[v][id] then table.insert(arg, component_arrays[v][id]) else break end end if #arg == #system.query then system.system(arg) end end end end end return M