---@generic T ---@param shape T | fun() ---@param process fun(entity: T, dt: number, system: System) | nil ---@return System | { entities: T[] } function filteredSystem(name, shape, process) assert(type(name) == "string") assert(type(shape) == "table" or type(shape) == "function") assert(process == nil or type(process) == "function") local system = tiny.processingSystem() system.name = name if type(shape) == "table" then local keys = {} for key, value in pairs(shape) do local isTable = type(value) == "table" local isMaybe = isTable and value.maybe ~= nil if not isMaybe then -- ^ Don't require any Maybe types keys[#keys + 1] = key end end system.filter = tiny.requireAll(unpack(keys)) elseif type(shape) == "function" then system.filter = shape end if not process then return World:addSystem(system) end function system:process(e, dt) process(e, dt, self) end return World:addSystem(system) end