-- Compiled with @isentinel/roblox-ts v4.0.11 local TS = _G[script] local _matter = TS.import(script, TS.getModule(script, "@lisachandra", "matter")) local createPackageRegistry = _matter.createPackageRegistry local createPackageRuntime = _matter.createPackageRuntime local findSystems = _matter.findSystems local start = _matter.start local RunService = TS.import(script, TS.getModule(script, "@rbxts", "services")).RunService -- ─── Types ─────────────────────────────────────────────────────────────────── --[[ * * Options for configuring the Matter ECS bootstrap process. * * @remarks * Combines pre-resolved systems, auto-collected Flamework barrels, hot-reload containers, and * ad-hoc extensions into a single boundary passed to the Matter loop. ]] --[[ * * Resolved boundary produced from {@link BootstrapOptions}. * * @remarks * This is the normalized input that `start()` receives after `resolveBoundary` merges all * configured sources. ]] --[[ * * Return value of {@link bootstrap}, providing access to the Matter world, crate, loop, and the * resolved boundary used. ]] local function collectSystems(modules) local systems = {} for _, container in modules do for _1, s in findSystems(container, {}) do table.insert(systems, s) end end return systems end --[[ * * Merges all configured system/module/container sources into a single {@link BootstrapBoundary} * suitable for `start()`. * * @param options - The bootstrap options specifying mode, modules, systems, hot-reload containers, * and extensions. * @returns A resolved boundary with the final system list, mode, and * containers. ]] local function resolveBoundary(options) if options == nil then options = {} end local mode = options.mode or "production" local scope = if RunService:IsClient() then "client" else "server" local _condition = RunService:IsStudio() and mode == "development" if _condition then local _result = options.hotReload if _result ~= nil then _result = _result.containers if _result ~= nil then _result = #_result end end local _condition_1 = _result if _condition_1 == nil then _condition_1 = 0 end _condition = _condition_1 > 0 end local hotReloadEnabled = _condition local allSystems = {} -- 1. Pre-resolved systems (pipeline / packages output) if options.systems then for _, s in options.systems do table.insert(allSystems, s) end end -- 2. Auto-collected systems from Flamework barrel modules if options.modules and not hotReloadEnabled then if options.modules.shared then for _, s in findSystems(options.modules.shared) do table.insert(allSystems, s) end end local scopeModule = options.modules[scope] if scopeModule then for _, s in findSystems(scopeModule) do table.insert(allSystems, s) end end end -- 3. Extension modules & systems if options.extensions then if options.extensions.modules then for _, s in collectSystems(options.extensions.modules) do table.insert(allSystems, s) end end if options.extensions.systems then for _, s in options.extensions.systems do table.insert(allSystems, s) end end end -- 4. Package descriptors (builtin or third-party) if options.packages then local registry = createPackageRegistry() for _, pkg in options.packages do registry:register(pkg) end local allIds = {} for id in registry:entries() do table.insert(allIds, id) end local resolved = registry:resolve(allIds) local runtime = createPackageRuntime(resolved) for _, s in runtime:buildSystems() do table.insert(allSystems, s) end end -- Build container list local containers = {} local _condition_1 = mode == "development" if _condition_1 then local _result = options.hotReload if _result ~= nil then _result = _result.containers end _condition_1 = _result end if _condition_1 then for _, c in options.hotReload.containers do table.insert(containers, c) end end local _result = options.extensions if _result ~= nil then _result = _result.containers end if _result then for _, c in options.extensions.containers do table.insert(containers, c) end end return { containers = containers, mode = mode, systems = allSystems, } end --[[ * * Single bootstrap entry point — works on both client and server. * * @example * ```ts * // Full pipeline path * const systems = createPipeline().use(families).build(); * const { world, crate, loop } = bootstrap({ mode: "development", systems }); * ```; * * @example * ```ts * // Auto-collect from Flamework barrels (no pipeline) * // Include builtin matter systems via packages * const { world, crate } = bootstrap({ * packages: [builtinPackage], * modules: { server: systems, shared: sharedSystems }, * ```; ]] local function bootstrap(options) if options == nil then options = {} end local boundary = resolveBoundary(options) local runtime = start({ containers = boundary.containers, systems = boundary.systems, }) return { boundary = boundary, crate = runtime.crate, debugger = runtime.debugger, loop = runtime.loop, world = runtime.world, } end return { resolveBoundary = resolveBoundary, bootstrap = bootstrap, }