From 921c61a0a6d882fcf66bc6a5470e89068dc6f83e Mon Sep 17 00:00:00 2001 From: Logan Hunt <2dloganh@gmail.com> Date: Thu, 15 Jan 2026 14:31:56 -0500 Subject: [PATCH 1/9] Refactor Roam bootstrappers and service management Improves error handling and configuration in ClientBootstrapper and ServerBootstrapper, adds support for custom require options, and refactors service registration, initialization, and startup logic in Roam. Updates example setup and deprecates outdated test file. Adds VSCode and Stylua configuration files for consistent formatting. --- .vscode/settings.json | 13 + .../src/Bootstrappers/ClientBootstrapper.luau | 36 +- .../src/Bootstrappers/ServerBootstrapper.luau | 28 +- lib/roam/src/Bootstrappers/_ExampleSetup.luau | 15 +- lib/roam/src/init.luau | 729 +++++++++++------- lib/roam/src/init.spec.luau | 1 + stylua.toml | 12 + 7 files changed, 537 insertions(+), 297 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 stylua.toml diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..8b3e4bc --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,13 @@ +{ + "[lua]": { + "editor.defaultFormatter": "JohnnyMorganz.stylua", + "editor.formatOnSave": true + }, + "[luau]": { + "editor.defaultFormatter": "JohnnyMorganz.stylua", + "editor.formatOnSave": true + }, + "selene.selenePath": "", + "stylua.targetReleaseVersion": "latest", + +} \ No newline at end of file diff --git a/lib/roam/src/Bootstrappers/ClientBootstrapper.luau b/lib/roam/src/Bootstrappers/ClientBootstrapper.luau index 86f0232..9ed97a8 100644 --- a/lib/roam/src/Bootstrappers/ClientBootstrapper.luau +++ b/lib/roam/src/Bootstrappers/ClientBootstrapper.luau @@ -5,10 +5,13 @@ local ReplicatedStorage = game:GetService("ReplicatedStorage") local BootstrapperModule = script -local function StartGame(script) - if script.Name == "start" then +local function StartGame(script, requireConfig: { + AllowYieldingRequires: boolean?; -- Default: false + StopOnFailedRequire: boolean?; -- Default: true +}?) + local Promise = require(BootstrapperModule.Parent.Parent.Parent.Promise) + if script.Name == "start" then -- We may want to remove this check later. It doesnt allow nice custom structures since its tailored to my opinion. script:Destroy() - local Promise = require(BootstrapperModule.Parent.Parent.Parent.Promise) return Promise.reject() end @@ -16,35 +19,42 @@ local function StartGame(script) local SRC_NAME = Roam.DEFAULT_SRC_NAME -- Roam.Debug = true -- Enables prints to see when services Init and Start - -- Require modules under the Client folder that end. - Roam.requireModules({ + -- Require modules under the Client folder that end in "Service" or "Controller" + local result = Roam.requireModules({ ReplicatedStorage[SRC_NAME].Client; ReplicatedStorage[SRC_NAME].Shared; }, { DeepSearch = true; + StopOnFailedRequire = if requireConfig and requireConfig.StopOnFailedRequire ~= nil then requireConfig.StopOnFailedRequire else true; + AllowYieldingRequires = if requireConfig and requireConfig.AllowYieldingRequires ~= nil then requireConfig.AllowYieldingRequires else false; RequirePredicate = function(obj: ModuleScript) -- Only require modules that end in "Service" or "Controller" local isService = obj.Name:match("Service$") or obj.Name:match("Controller$") return isService end; - IgnoreDescendantsPredicate = function(obj: Instance) -- Ignore the "node_modules_dependencies" folder and anything under "Server" - return obj.Name == "Server" -- or obj.Name == DPDN + IgnoreDescendantsPredicate = function(obj: Instance) -- Ignore anything under "Server" + return obj.Name == "Server" end; }) + if not result.Success then + return Promise.reject("šŸ›‘ [CLIENT] Failed module requires during client bootstrap šŸ›‘") + end - -- Wait for the server to start Orion + -- Wait for the server to start if not workspace:GetAttribute("RoamStarted") then workspace:GetAttributeChangedSignal("RoamStarted"):Wait() end - -- Start Roam return Roam.start():andThen(function() print("[CLIENT] Roam Started!") - end):catch(function(err) - warn(err) - error("[CLIENT] Roam Failed to Start!") - end) + return true + end) + :catch(function(err) + local sanitizedError = tostring(err):gsub("%[(.-):", "") + task.spawn(error, "šŸ›‘ [CLIENT] Roam Failed to Start! šŸ›‘" .. sanitizedError) + return false + end) end return StartGame \ No newline at end of file diff --git a/lib/roam/src/Bootstrappers/ServerBootstrapper.luau b/lib/roam/src/Bootstrappers/ServerBootstrapper.luau index c878f71..264dfc5 100644 --- a/lib/roam/src/Bootstrappers/ServerBootstrapper.luau +++ b/lib/roam/src/Bootstrappers/ServerBootstrapper.luau @@ -25,10 +25,13 @@ local function ShutdownServer(err) end end -local function StartGame(script) - if script.Name == "start" then +local function StartGame(script, requireConfig: { + AllowYieldingRequires: boolean?; -- Default: false + StopOnFailedRequire: boolean?; -- Default: true + }?) + local Promise = require(BootstrapperModule.Parent.Parent.Parent.Promise) + if script.Name == "start" then -- We may want to remove this check later. It doesnt allow nice custom structures since its tailored to my opinion. script:Destroy() - local Promise = require(BootstrapperModule.Parent.Parent.Parent.Promise) return Promise.reject() end @@ -37,29 +40,40 @@ local function StartGame(script) -- Roam.Debug = true -- Enables prints to see when services Init and Start -- Register modules under the Server folder. - Roam.requireModules({ + local result = Roam.requireModules({ ServerScriptService[SRC_NAME].Server, ReplicatedStorage[SRC_NAME].Shared, }, { DeepSearch = true, + StopOnFailedRequire = if requireConfig and requireConfig.StopOnFailedRequire ~= nil then requireConfig.StopOnFailedRequire else true, + AllowYieldingRequires = if requireConfig and requireConfig.AllowYieldingRequires ~= nil then requireConfig.AllowYieldingRequires else false, RequirePredicate = function(obj: ModuleScript) -- Only require modules that end in "Service" local isService = obj.Name:match("Service$") return isService end, - IgnoreDescendantsPredicate = function(obj: Instance) -- Ignore the "node_modules_dependencies" folder and anything under "Client" - return obj.Name == "Client" -- or obj.Name == DPDN + IgnoreDescendantsPredicate = function(obj: Instance) -- Ignore anything under "Client" + return obj.Name == "Client" end, }) + if result.Success == false then + task.spawn(error, "šŸ›‘ [SERVER] Failed module requires during server bootstrap šŸ›‘") + ShutdownServer("Failed module requires during server bootstrap") + return Promise.reject() + end + -- Start Roam return Roam.start() :andThen(function() print("[SERVER] Roam Started!") workspace:SetAttribute("RoamStarted", true) -- Alert the Client that the Server is ready + return true end) :catch(function(err) + local sanitizedError = tostring(err):gsub("%[(.-):", "") + task.spawn(error, "šŸ›‘ [SERVER] Roam Failed to Start! šŸ›‘" .. sanitizedError) ShutdownServer(err) - task.spawn(error, "šŸ›‘ [SERVER] Roam Failed to Start! šŸ›‘\n\t" .. tostring(err)) + return false end) end diff --git a/lib/roam/src/Bootstrappers/_ExampleSetup.luau b/lib/roam/src/Bootstrappers/_ExampleSetup.luau index d342e5e..53e6461 100644 --- a/lib/roam/src/Bootstrappers/_ExampleSetup.luau +++ b/lib/roam/src/Bootstrappers/_ExampleSetup.luau @@ -9,13 +9,13 @@ local ReplicatedStorage = game:GetService("ReplicatedStorage") local ServerScriptService = game:GetService("ServerScriptService") local Packages = ReplicatedStorage.Packages -local Roam = require(Packages.Roam) :: any ---@module Roam +local Roam = require(Packages.Roam) local function StartGame() -- Register modules under the Server folder. Roam.requireModules( { - ServerScriptService.Orion.Server, + ServerScriptService.Server, }, true, function(obj: ModuleScript) -- Only require modules that end in "Service" @@ -44,13 +44,13 @@ StartGame() local ReplicatedStorage = game:GetService("ReplicatedStorage") local Packages = ReplicatedStorage.Packages -local Roam = require(Packages.Roam) :: any ---@module Roam +local Roam = require(Packages.Roam) local function StartGame() -- Require modules under the Client folder that end. Roam.requireModules( { - ReplicatedStorage.Orion.Client, + ReplicatedStorage.Client, } ) @@ -77,11 +77,9 @@ StartGame() -------------------------------------------------------------------------------- local ReplicatedStorage = game:GetService("ReplicatedStorage") - local Packages = ReplicatedStorage.Packages -local Roam = require(Packages.Roam) :: any ---@module Roam -local MyService = Roam.createService("MyService") ---@class MyService +local MyService = {} function MyService:RoamStart() -- Game Logic @@ -91,4 +89,7 @@ function MyService:RoamInit() -- Initialize the Service end +local Roam = require(Packages.Roam) +Roam.registerService(MyService, "MyService") + return MyService diff --git a/lib/roam/src/init.luau b/lib/roam/src/init.luau index c2f700c..4730ecb 100644 --- a/lib/roam/src/init.luau +++ b/lib/roam/src/init.luau @@ -61,21 +61,18 @@ ::: ]=] - local RunService = game:GetService("RunService") local Packages = script.Parent -local Promise = require(Packages.Promise) ---@module _Promise -local Symbol = require(Packages.Symbol) ---@module _Symbol - -local KEY_CONFIG = Symbol("RoamServiceConfig") +local Promise = require(Packages.Promise) +local Symbol = require(Packages.Symbol) -local Roam_START_METHOD_NAME = "RoamStart" -local Roam_INIT_METHOD_NAME = "RoamInit" - -local RunContext = RunService:IsServer() and "SERVER" or "CLIENT" +local Roam = {} +-------------------------------------------------------------------------------- --// Types //-- +-------------------------------------------------------------------------------- + type table = { [any]: any } export type Service = table @@ -115,7 +112,7 @@ export type Service = table ]=] export type ServiceConfig = { Name: string, -- Name of the Service. Must be unique. Used when accessing via .getService - RequiredServices: {Service}?, -- The Services that this Service depends on. Roam will ensure that these Services are initialized before this Service. + RequiredServices: { Service }?, -- The Services that this Service depends on. Roam will ensure that these Services are initialized before this Service. StartMethodName: string?, -- Overrides default StartMethodName of "RoamStart" InitMethodName: string?, -- Overrides default InitMethodName of "RoamInit" [any]: any, @@ -124,43 +121,59 @@ export type ServiceConfig = { type Promise = typeof(Promise.new()) -------------------------------------------------------------------------------- ---// Volatiles //-- +--// Constants //-- -------------------------------------------------------------------------------- -local services: { [string]: Service } = {} +local KEY_CONFIG = Symbol("RoamServiceConfig") +local DEFAULT_START_METHOD = "RoamStart" +local DEFAULT_INIT_METHOD = "RoamInit" +local INIT_TIMEOUT_SECONDS = 120 +local RUN_CONTEXT = RunService:IsServer() and "SERVER" or "CLIENT" + +-------------------------------------------------------------------------------- +--// State //-- +-------------------------------------------------------------------------------- +local services: { [string]: Service } = {} local started = false local startedComplete = false local onStartedComplete = Instance.new("BindableEvent") -------------------------------------------------------------------------------- ---// Private Functions //-- +--// Utility Functions //-- -------------------------------------------------------------------------------- --- Checks to see if an Instance's Name ends in `Service` -local function ServiceNameMatch(obj: Instance) +local function serviceNameMatch(obj: Instance): boolean return obj.Name:match("Service$") ~= nil end --- Reconciles a primary table with a secondary table -local function Reconcile(primary, secondary) - primary = primary or {} - secondary = secondary or {} - for i in pairs(secondary) do - primary[i] = primary[i] or secondary[i] +local function reconcile(primary: T?, secondary: T): T + primary = primary or {} :: any + secondary = secondary or {} :: any + for key, value in pairs(secondary :: any) do + (primary :: any)[key] = (primary :: any)[key] or value end - return primary + return primary :: T end --- checks if a service exists with the given name -local function DoesServiceExist(serviceName: string): boolean - local service: Service? = services[serviceName] - return service ~= nil +local function serviceExists(service: string | table): boolean + if type(service) == "string" then + return services[service] ~= nil + elseif type(service) == "table" then + for _, registeredService in pairs(services) do + if registeredService == service then + return true + end + end + return false + else + error("serviceExists expects a string or table as argument") + end end --- requires a given modulescript and throws a safe error if it yields -local function EnsureUnyieldingRequire(module: ModuleScript) - local moduleContent +local FAILED_REQUIRE_YIELD = Symbol("FailedRequireYield") +local function ensureUnyieldingRequire(module: ModuleScript) + local moduleContent = FAILED_REQUIRE_YIELD task.spawn(function() local current task.spawn(function() @@ -170,26 +183,242 @@ local function EnsureUnyieldingRequire(module: ModuleScript) end) assert(success, `Failed to load module: {module.Name}\n{msg}`) end) - assert(coroutine.status(current) == "dead", "Roam Require Yielded: ".. module:GetFullName()) + + if coroutine.status(current) ~= "dead" then + error( + `Roam Require detected yield. Check the following module and the modules it requires: {module:GetFullName()}` + ) + end end) + return moduleContent end +local function formatError(context: string, details: string): string + return `[Roam {RUN_CONTEXT}] {context}: {details}` +end + -------------------------------------------------------------------------------- ---// Roam //-- +--// Validation Functions //-- -------------------------------------------------------------------------------- -local Roam = {} -Roam.ClassName = "Roam" -Roam.Services = services -- A table of Services. Only properly accessible after Roam has been started. -Roam.ServiceNameMatch = ServiceNameMatch -Roam.Debug = false -- Whether or not to print debug messages -Roam.DEFAULT_SRC_NAME = "src" +local function validateServiceConfig(serviceConfig: any, serviceName: string?): ServiceConfig + if typeof(serviceConfig) == "string" then + serviceConfig = { Name = serviceConfig } + elseif not serviceConfig then + serviceConfig = {} + end -Roam.Bootstrappers = { -- Generic Bootstrappers for Roam / Orion - Server = require(script:FindFirstChild("Bootstrappers"):FindFirstChild("ServerBootstrapper")) :: (script: Script) -> (Promise); - Client = require(script:FindFirstChild("Bootstrappers"):FindFirstChild("ClientBootstrapper")) :: (script: Script) -> (Promise); -} + if typeof(serviceConfig) ~= "table" then + error(formatError("Invalid ServiceConfig", `Expected table, got {typeof(serviceConfig)}`)) + end + + local name = serviceConfig.Name or serviceName + if not name then + error(formatError("Missing Service Name", "Service must have a name")) + end + + if type(name) ~= "string" or #name == 0 then + error(formatError("Invalid Service Name", `Name must be a non-empty string, got {type(name)}`)) + end + + if serviceExists(name) then + error(formatError("Duplicate Service", `Service "{name}" already exists`)) + end + + if serviceConfig.RequiredServices then + for i, requiredService in ipairs(serviceConfig.RequiredServices) do + if type(requiredService) ~= "table" then + error( + formatError( + "Invalid Required Service", + `RequiredServices[{i}] must be a Service table, got {typeof(requiredService)} while registering "{name}"` + ) + ) + end + if not serviceExists(requiredService) then + warn( + formatError( + "Unregistered Required Service", + `RequiredServices[{i}] is not a registered service while registering "{name}"` + ) + ) + end + end + end + + -- remove duplicates from RequiredServices + if serviceConfig.RequiredServices then + local seen = {} + local uniqueRequiredServices = {} + for i, reqService in ipairs(serviceConfig.RequiredServices) do + if not seen[reqService] then + seen[reqService] = true + table.insert(uniqueRequiredServices, reqService) + else + warn( + formatError( + "Duplicate RequiredService", + `Service "{name}" has duplicate required service at index {i}` + ) + ) + end + end + serviceConfig.RequiredServices = uniqueRequiredServices + end + + return serviceConfig :: ServiceConfig +end + +local function validateRequiredServices(): { string } + local missingServices = {} + + for serviceName, service in pairs(services) do + local config: ServiceConfig = service[KEY_CONFIG] + if not config.RequiredServices then + continue + end + + for _, requiredService in ipairs(config.RequiredServices) do + local found = false + for _, existingService in pairs(services) do + if requiredService == existingService then + found = true + break + end + end + + if not found then + table.insert(missingServices, `Required service for '{serviceName}' not found`) + end + end + end + + return missingServices +end + +-------------------------------------------------------------------------------- +--// Service Management //-- +-------------------------------------------------------------------------------- + +local rejectedInitializations = {} +local function createServiceInitPromise(service: Service, config: ServiceConfig): Promise? + local initMethodName = config.InitMethodName or DEFAULT_INIT_METHOD + local initMethod = service[initMethodName] + + if type(initMethod) ~= "function" then + return nil + end + + return Promise.new(function(resolve, reject) + if Roam.Debug then + print(`[{RUN_CONTEXT}] Initializing {config.Name}`) + end + + local startTime = os.clock() + local initFunction = service[initMethodName] + + -- Prevent re-initialization + service[initMethodName] = function() + error(`{config.Name} | Cannot call Init method after service has been initialized`) + end + + local success = false + local initThread = task.spawn(function() + debug.setmemorycategory(config.Name) + initFunction(service) + success = true + end) + + while coroutine.status(initThread) ~= "dead" do + task.wait() + end + + if not success then + table.insert(rejectedInitializations, "\n - " .. config.Name) + reject(`Failed to initialize {config.Name}`) + return + end + + local elapsed = os.clock() - startTime + if Roam.Debug then + print(`[{RUN_CONTEXT}] Initialized {config.Name} in {string.format("%.3f", elapsed)}s`) + end + + resolve(elapsed) + end):timeout(INIT_TIMEOUT_SECONDS, `Service {config.Name} took too long to initialize`) +end + +local function startService(service: Service, config: ServiceConfig): () + local startMethodName = config.StartMethodName or DEFAULT_START_METHOD + local startMethod = service[startMethodName] + + if type(startMethod) ~= "function" then + return + end + + task.spawn(function() + if Roam.Debug then + print(`[{RUN_CONTEXT}] Starting {config.Name}`) + end + + debug.setmemorycategory(config.Name) + local startFunction = service[startMethodName] + + -- Prevent re-starting + service[startMethodName] = function() + error(`{config.Name} | Cannot call Start method after service has been started`) + end + + startFunction(service) + end) +end + +-------------------------------------------------------------------------------- +--// Topological Sorting //-- +-------------------------------------------------------------------------------- + +local function createAdjacencyList(): { [Service]: { Service } } + local adjacencyList = {} + for _, service in pairs(services) do + adjacencyList[service] = service[KEY_CONFIG].RequiredServices or {} + end + return adjacencyList +end + +local function topologicalSort(adjacencyList: { [Service]: { Service } }): { Service } + local visited = {} + local stack = {} + + local function visit(service: Service) + if visited[service] then + return + end + + visited[service] = true + + for _, dependency in ipairs(adjacencyList[service] or {}) do + visit(dependency) + end + + table.insert(stack, service) + end + + for service in pairs(adjacencyList) do + visit(service) + end + + return stack +end + +local function getSortedServices(): { Service } + local adjacencyList = createAdjacencyList() + return topologicalSort(adjacencyList) +end + +-------------------------------------------------------------------------------- +--// Main Roam Module //-- +-------------------------------------------------------------------------------- --[=[ @private @@ -198,16 +427,29 @@ Roam.Bootstrappers = { -- Generic Bootstrappers for Roam / Orion @prop ClassName "Roam" The ClassName of the Roam module. ]=] +Roam.ClassName = "Roam" + +--[=[ + @within Roam + @prop Services {[string]: Service} + A table of Services. Only properly accessible after Roam has been started. +]=] +Roam.Services = services -- A table of Services. Only properly accessible after Roam has been started. + +Roam.ServiceNameMatch = serviceNameMatch --[=[ @within Roam @prop Debug boolean Whether or not to print debug messages. Default is false. ]=] +Roam.Debug = false -- Whether or not to print debug messages + +Roam.DEFAULT_SRC_NAME = "src" --[=[ @within Roam - @prop Bootstrappers {Server: (script: Script) -> (), Client: (script: Script) -> ()} + @prop Bootstrappers {Server: (script: Script) -> Promise, Client: (script: Script) -> Promise} A table of generic bootstrappers for Roam that you can use to quickly setup new projects. ```lua local Roam = require(Packages.Roam) @@ -216,6 +458,10 @@ Roam.Bootstrappers = { -- Generic Bootstrappers for Roam / Orion :andThenCall(print, "Roam Server Bootstrapped!") ``` ]=] +Roam.Bootstrappers = { -- Generic Bootstrappers for Roam / Orion + Server = require(script:FindFirstChild("Bootstrappers"):FindFirstChild("ServerBootstrapper")) :: (script: Script, config: { [string]: any }?) -> Promise, + Client = require(script:FindFirstChild("Bootstrappers"):FindFirstChild("ClientBootstrapper")) :: (script: Script, config: { [string]: any }?) -> Promise, +} --[=[ Registers a Service/Table with Roam to be Initialized and Started when Roam starts. @@ -241,91 +487,19 @@ Roam.Bootstrappers = { -- Generic Bootstrappers for Roam / Orion ``` ]=] function Roam.registerService(service: Service, serviceConfig: (ServiceConfig | string)?): Service - assert(not started, "Cannot register Services after Roam has been started") - assert(type(service) == "table", `Service must be a table; got {type(service)}`) - - if typeof(serviceConfig) == "string" then - serviceConfig = { Name = serviceConfig } - elseif not serviceConfig then - serviceConfig = {} :: any - end - - assert(typeof(serviceConfig) == "table", `ServiceConfig must be a table; got {typeof(serviceConfig)}`) - --serviceConfig.ENV = getfenv(2) -- This is no longer supported - - local Name = serviceConfig.Name or service.Name - if not Name then - error("No name provided for service") - -- Name = serviceConfig.ENV.script.Name - -- warn(`No Service name was given; this is not recommended. Roam will attempt to continue by attempting to infer the ServiceName. [Inferred Service Name: "{Name}"]`) - end - - assert( - not serviceConfig or type(serviceConfig) == "table", - `ServiceConfig must be a table; got {type(serviceConfig)}` - ) - assert(type(Name) == "string", `Service.Name must be a string; got {type(Name)}`) - assert(#Name > 0, "Service.Name must be a non-empty string") - assert(not DoesServiceExist(Name), `Service "{Name}" already exists`) - - service[KEY_CONFIG] = table.freeze(Reconcile(serviceConfig :: any, { - Name = Name, - })) - services[Name] = service - - return service -end - ---[=[ - @deprecated 0.1.5 - @private - Creates a Service/Table with Roam to be Initialized and Started when Roam starts. - Cannot be called after Roam has been started. - - This is an alternative method to setting up services over using `registerService`. - - ```lua - local Roam = require(ReplicatedStorage.Roam) - - local MyService = Roam.createService { Name = "MyService" } - - function MyService:DoSomething() - print("yeee haw!") - end - - -- Default StartMethodName is "RoamStart" (Can be overriden in service creation config) - function MyService:RoamStart() - print("MyService started!") - self:DoSomething() + if started then + error(formatError("Registration Error", "Cannot register services after Roam has started")) end - -- Default InitMethodName is "RoamInit" (Can be overriden in service creation config) - function MyService:RoamInit() - print("MyService initialized!") + if type(service) ~= "table" then + error(formatError("Invalid Service", `Service must be a table, got {type(service)}`)) end - return MyService - ``` -]=] -function Roam.createService(serviceDef: ServiceConfig): Service - assert(not started, "Cannot create Services after Roam has been started") - assert(type(serviceDef) == "table", `Service must be a table; got {type(serviceDef)}`) - - local Name = serviceDef.Name - assert(type(Name) == "string", `Service.Name must be a string; got {type(Name)}`) - assert(#Name > 0, "Service.Name must be a non-empty string") - assert(not DoesServiceExist(Name), `Service "{Name}" already exists`) - - local service: Service = serviceDef - service[KEY_CONFIG] = table.freeze({ - Name = Name, - StartMethodName = serviceDef.StartMethodName, - InitMethodName = serviceDef.InitMethodName, - --ENV = getfenv(2), - }) + local config = validateServiceConfig(serviceConfig, service.Name) + local reconciledConfig = table.freeze(reconcile(config, { Name = config.Name })) - -- Register Service to Roam - services[Name] = service + service[KEY_CONFIG] = reconciledConfig + services[config.Name] = service return service end @@ -360,156 +534,83 @@ function Roam.start(postInitPreStart: (() -> Promise?)?): Promise return Promise.reject("Roam already started") end - assert( - not postInitPreStart or type(postInitPreStart) == "function", - `postInitPreStart must be a function or nil; got {type(postInitPreStart)}` - ) + if postInitPreStart and type(postInitPreStart) ~= "function" then + error( + formatError("Invalid Parameter", `postInitPreStart must be a function or nil, got {type(postInitPreStart)}`) + ) + end started = true - --Roam.Started = started - - local topologicallySortedServices: {Service} - do -- fetch topologically sorted services - local function sortUtil(service, adjacencyList, visited, stack) - visited[service] = true - for _, neighbor in pairs(adjacencyList[service] or {}) do - if not visited[neighbor] then - sortUtil(neighbor, adjacencyList, visited, stack) - end - end - table.insert(stack, service) - end - - local function topologicalSort(adjacencyList) - local stack, visited = {}, {} - for service in pairs(adjacencyList) do - if not visited[service] then - sortUtil(service, adjacencyList, visited, stack) - end - end - return stack - end - - -- Generate Adjacency List of Required Services - local adjacencyList = {} - for _, service in pairs(services) do - adjacencyList[service] = service[KEY_CONFIG].RequiredServices or {} - - -- Fetches services dynamically is no longer supported due to de-optimization - -- for _, envProp in pairs(service[KEY_CONFIG].ENV) do - -- if typeof(envProp) == "table" and envProp[KEY_CONFIG] then - -- if not table.find(adjacencyList[service], envProp) then - -- table.insert(adjacencyList[service], envProp) - -- end - -- end - -- end - end - topologicallySortedServices = topologicalSort(adjacencyList) + -- Validate all required services are registered + local missingServices = validateRequiredServices() + if #missingServices > 0 then + error(formatError("Missing Dependencies", table.concat(missingServices, "; "))) end + local sortedServices = getSortedServices() return Promise.new(function(resolve) table.freeze(services) - -- Init: + -- Initialize services + local initPromises = {} local totalInitTime = 0 - local promisesInitServices = {} - local servicesThatFailedToInit = {} - for _, service in topologicallySortedServices do - local ServiceConfig = service[KEY_CONFIG] - local InitMethodName = ServiceConfig.InitMethodName or Roam_INIT_METHOD_NAME - if type(service[InitMethodName]) == "function" then + for _, service in ipairs(sortedServices) do + local config = service[KEY_CONFIG] + local initPromise = createServiceInitPromise(service, config) + + if initPromise then table.insert( - promisesInitServices, - Promise.new(function(resolveService, reject) - if Roam.Debug then - print(`[{RunContext}] Initializing {ServiceConfig.Name}`) - end - local t = os.clock() - - local serviceInitFn = service[InitMethodName] - service[InitMethodName] = function() - error(`{ServiceConfig.Name} | Cannot call Init method after service has been initialized`) - end - - local successfullyInitialized = false - local initThread = task.spawn(function() - debug.setmemorycategory(ServiceConfig.Name) - serviceInitFn(service) - successfullyInitialized = true - end) - while coroutine.status(initThread) ~= "dead" do - task.wait() -- Yield until the coroutine is dead - end - if not successfullyInitialized then - table.insert(servicesThatFailedToInit, ServiceConfig.Name) - reject(`Failed to initialize {ServiceConfig.Name}`) - return - end - - t = os.clock() - t - totalInitTime += t - if Roam.Debug then - print(`[ROAM {RunContext}] Initialized {ServiceConfig.Name} in {t} seconds.`) - end - resolveService() - end):timeout(120, `Service {ServiceConfig.Name} took too long to initialize.`) + initPromises, + initPromise:andThen(function(elapsed) + totalInitTime += elapsed + end) ) end end Roam.Services = services - local InitProm = Promise.all(promisesInitServices) - :tap(function() + local initializationPromise = Promise.all(initPromises) + :andThen(function() if Roam.Debug then - print(`[{RunContext}] ROAM Initialized all services in {totalInitTime} seconds.`) + print(`[{RUN_CONTEXT}] All services initialized in {string.format("%.3f", totalInitTime)}s`) end end) - :catch(function() - task.wait() - local err = `ROAM failed to initialize services: ` .. table.concat(servicesThatFailedToInit, ", ") - return Promise.reject(err) + :catch(function(error) + return Promise.reject( + formatError( + "Initialization Failed for the following services", + table.concat(rejectedInitializations) + ) + ) end) - resolve(InitProm) - end) - :andThen(function() - if postInitPreStart then - return postInitPreStart() :: Promise? - end - return nil + resolve(initializationPromise) end) - :andThen(function() - -- Start: - for _, service in topologicallySortedServices do - local ServiceConfig = service[KEY_CONFIG] - local StartMethodName = ServiceConfig.StartMethodName or Roam_START_METHOD_NAME - if type(service[StartMethodName]) == "function" then - task.spawn(function() - if Roam.Debug then - print(`[{RunContext}] Starting {ServiceConfig.Name}`) - end - debug.setmemorycategory(ServiceConfig.Name) - local serviceStartFn = service[StartMethodName] - service[StartMethodName] = function() - error(`{ServiceConfig.Name} | Cannot call Start method after service has been initialized`) - end - serviceStartFn(service) - end) + :andThen(function() + -- Call post-init hook if provided + if postInitPreStart then + return postInitPreStart() + end + return nil + end) + :andThen(function() + -- Start services + for _, service in ipairs(sortedServices) do + local config = service[KEY_CONFIG] + startService(service, config) end - end - startedComplete = true - --Roam.Ready = startedComplete - onStartedComplete:Fire() + startedComplete = true + onStartedComplete:Fire() - task.defer(function() - onStartedComplete:Destroy() + task.defer(function() + onStartedComplete:Destroy() + end) end) - end) end --[=[ @@ -524,7 +625,7 @@ end end):catch(warn) ``` ]=] -function Roam.onStart() +function Roam.onStart(): Promise if startedComplete then return Promise.resolve() else @@ -546,6 +647,7 @@ end - `DeepSearch` -> whether it checks descendants or just children - `RequirePredicate` -> a predicate function that determines whether a module should be required - `IgnoreDescendantsPredicate` -> A Predicate for whether the Descendants of the Module should be Searched (Only matters if DeepSearch is true) + - `StopOnFailedRequire` -> whether to stop requiring modules if one fails to require (default: false). Useful for debugging, helps to clear excessive noise from the output. ```lua local pred = function(obj: ModuleScript): boolean @@ -565,58 +667,134 @@ function Roam.requireModules( parents: Instance | { Instance }, config: { DeepSearch: boolean?, + AllowYieldingRequires: boolean?, + StopOnFailedRequire: boolean?, RequirePredicate: ((obj: ModuleScript) -> boolean)?, IgnoreDescendantsPredicate: ((obj: Instance) -> boolean)?, }? -): { Service } +): { + ModuleContent: { [ModuleScript]: any }, + FailedModuleRequires: { ModuleScript }, +} if typeof(parents) == "Instance" then parents = { parents } end config = config or {} - assert(typeof(config) == "table", `config must be a table; got {typeof(config)}`) + if typeof(config) ~= "table" then + error(formatError("Invalid Config", `Config must be a table, got {typeof(config)}`)) + end + local deepSearch = config.DeepSearch or false - local predicate = config.RequirePredicate + local requirePredicate = config.RequirePredicate local ignoreDescendantsPredicate = config.IgnoreDescendantsPredicate + local successfullyRequiredModuleContent = {} + local failedModuleRequires = {} - local addedServices = {} - local function SearchInstance(obj: Instance | {Instance}) + local function searchInstance(obj: Instance | { Instance }) if typeof(obj) == "table" then - for _, v in ipairs(obj) do - SearchInstance(v) + for _, child in ipairs(obj) do + local success = searchInstance(child) + if not success and config.StopOnFailedRequire then + return false + end end - return + return true + end + + if typeof(obj) ~= "Instance" then + error(formatError("Invalid Object", `Expected Instance or table of Instances, got {typeof(obj)}`)) end - assert(typeof(obj) == "Instance", "Expected Instance or table of Instances. Got:"..tostring(obj)) - if obj:IsA("ModuleScript") and (not predicate or predicate(obj)) then - local service = EnsureUnyieldingRequire(obj) - if table.find(addedServices, service) then - warn("Already added service '" .. service[KEY_CONFIG].Name .. "' | " .. obj:GetFullName()) - return + if obj:IsA("ModuleScript") and (not requirePredicate or requirePredicate(obj)) then + if config.AllowYieldingRequires then + local success, moduleContent = pcall(function() + return require(obj) :: any + end) + if success then + successfullyRequiredModuleContent[obj] = moduleContent + return true + else + table.insert(failedModuleRequires, obj) + return false + end end - table.insert(addedServices, service) + local moduleContent = ensureUnyieldingRequire(obj) + if moduleContent == FAILED_REQUIRE_YIELD then + table.insert(failedModuleRequires, obj) + return false + end + + successfullyRequiredModuleContent[obj] = moduleContent end if deepSearch and (not ignoreDescendantsPredicate or not ignoreDescendantsPredicate(obj)) then - SearchInstance(obj:GetChildren()) + return searchInstance(obj:GetChildren()) end + return true end - - assert(typeof(parents) == "table", "Parents must be an Instance or table of Instances") - for _, parent in ipairs(parents) do - SearchInstance(parent:GetChildren()) + + if typeof(parents) ~= "table" then + error(formatError("Invalid Parents", "Parents must be an Instance or table of Instances")) end - return addedServices + searchInstance(parents) + + return { + Success = #failedModuleRequires == 0, + ModuleContent = successfullyRequiredModuleContent, + FailedModuleRequires = failedModuleRequires, + } end --[=[ + @within Roam + @private Fetches the name of a registered Service. ]=] function Roam.getNameFromService(service: Service): string - return service[KEY_CONFIG].Name + local config = service[KEY_CONFIG] + if not config then + error(formatError("Invalid Service", "Service is not registered with Roam")) + end + return config.Name +end + +--[=[ + @deprecated 0.1.5 + @private + Creates a Service/Table with Roam to be Initialized and Started when Roam starts. + Cannot be called after Roam has been started. + + This is an alternative method to setting up services over using `registerService`. + + ```lua + local Roam = require(ReplicatedStorage.Roam) + + local MyService = Roam.createService { Name = "MyService" } + + function MyService:DoSomething() + print("yeee haw!") + end + + -- Default StartMethodName is "RoamStart" (Can be overriden in service creation config) + function MyService:RoamStart() + print("MyService started!") + self:DoSomething() + end + + -- Default InitMethodName is "RoamInit" (Can be overriden in service creation config) + function MyService:RoamInit() + print("MyService initialized!") + end + + return MyService + ``` +]=] +function Roam.createService(serviceDef: ServiceConfig): Service + warn("[Roam] createService is deprecated, use registerService instead") + return Roam.registerService(serviceDef, serviceDef) end --[=[ @@ -626,11 +804,22 @@ end Cannot be called until Roam has been started. ]=] function Roam.getService(serviceName: string): Service + warn("[Roam] getService is deprecated, use Roam.Services[serviceName] instead") + if not started then - warn("!Roam has not been started yet! Services are not safe to access before Roam has been started.\n"..debug.traceback()) + warn(formatError("Early Access", "Services accessed before Roam started\n" .. debug.traceback())) + end + + if type(serviceName) ~= "string" then + error(formatError("Invalid Service Name", `ServiceName must be a string, got {type(serviceName)}`)) end - assert(type(serviceName) == "string", `ServiceName must be a string; got {type(serviceName)}`) - return assert(services[serviceName], `Could not find service "{serviceName}"`) :: Service + + local service = services[serviceName] + if not service then + error(formatError("Service Not Found", `Could not find service "{serviceName}"`)) + end + + return service end return Roam diff --git a/lib/roam/src/init.spec.luau b/lib/roam/src/init.spec.luau index 6f65826..034721a 100644 --- a/lib/roam/src/init.spec.luau +++ b/lib/roam/src/init.spec.luau @@ -1,5 +1,6 @@ -- Authors: Logan Hunt (Raildex) -- July 17, 2024 +-- THIS FILE IS OUTDATED AND NO LONGER MAINTAINED. TESTS MAY NOT WORK AS INTENDED. type table = {[any]: any} diff --git a/stylua.toml b/stylua.toml new file mode 100644 index 0000000..2343da5 --- /dev/null +++ b/stylua.toml @@ -0,0 +1,12 @@ +syntax = "All" +column_width = 120 +line_endings = "Unix" +indent_type = "Tabs" +indent_width = 4 +quote_style = "AutoPreferDouble" +call_parentheses = "NoSingleTable" +collapse_simple_statement = "Never" +space_after_function_names = "Never" + +[sort_requires] +enabled = false \ No newline at end of file From 455b36e726134ccb4d9a725a27fb93adda5c1995 Mon Sep 17 00:00:00 2001 From: Logan Hunt <2dloganh@gmail.com> Date: Fri, 16 Jan 2026 19:54:02 -0500 Subject: [PATCH 2/9] Enhance Roam docs, lifecycle, and add debug utilities Improves Roam documentation with detailed lifecycle diagrams and explanations, corrects typos, and adds advanced lifecycle hooks to the Roam.start method. Introduces service state tracking, dependency graph printing, and service state querying for debugging. Also updates DropletClientManager.luau for code style consistency and minor refactoring, and adds new static images for documentation. --- .moonwave/static/roam/GetVectored.jpg | Bin 0 -> 146820 bytes .../static/roam/RoamLifecycleAdvanced.png | Bin 0 -> 216013 bytes .rbxsync-trash/manifest.json | 3 + .vscode/settings.json | 3 +- .../src/Client/DropletClientManager.luau | 402 ++++++++--------- lib/roam/src/init.luau | 421 ++++++++++++++---- 6 files changed, 527 insertions(+), 302 deletions(-) create mode 100644 .moonwave/static/roam/GetVectored.jpg create mode 100644 .moonwave/static/roam/RoamLifecycleAdvanced.png create mode 100644 .rbxsync-trash/manifest.json diff --git a/.moonwave/static/roam/GetVectored.jpg b/.moonwave/static/roam/GetVectored.jpg new file mode 100644 index 0000000000000000000000000000000000000000..309b3f238a1c9331cddbd9d86b162c0928753c96 GIT binary patch literal 146820 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 literal 0 HcmV?d00001 diff --git a/.moonwave/static/roam/RoamLifecycleAdvanced.png b/.moonwave/static/roam/RoamLifecycleAdvanced.png new file mode 100644 index 0000000000000000000000000000000000000000..d45b19f30c210201335348f72d0105cebd29cd2b GIT binary patch literal 216013 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 >FK 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%0AB~V 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 literal 0 HcmV?d00001 diff --git a/.rbxsync-trash/manifest.json b/.rbxsync-trash/manifest.json new file mode 100644 index 0000000..c43cb32 --- /dev/null +++ b/.rbxsync-trash/manifest.json @@ -0,0 +1,3 @@ +{ + "entries": [] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 8b3e4bc..b24afa8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,6 +8,5 @@ "editor.formatOnSave": true }, "selene.selenePath": "", - "stylua.targetReleaseVersion": "latest", - + "stylua.targetReleaseVersion": "latest" } \ No newline at end of file diff --git a/lib/dropletmanager/src/Client/DropletClientManager.luau b/lib/dropletmanager/src/Client/DropletClientManager.luau index c7e8ab1..efda178 100644 --- a/lib/dropletmanager/src/Client/DropletClientManager.luau +++ b/lib/dropletmanager/src/Client/DropletClientManager.luau @@ -31,7 +31,7 @@ local LocalPlayer = Players.LocalPlayer --// Util Functions //-- -------------------------------------------------------------------------------- ---[=[ +--[[ Calculates the ejection velocity for a droplet with support for arbitrary ejection directions. @param hForce number | NumberRange -- Horizontal force (perpendicular to direction) @@ -39,44 +39,42 @@ local LocalPlayer = Players.LocalPlayer @param direction Vector3? -- Direction to eject towards (defaults to Vector3.yAxis) @param NumGen Random -- Random number generator @return Vector3 -- The calculated ejection velocity -]=] +]] local function CalculateEjectionVelocity(hForce, vForce, direction: Vector3?, NumGen: Random): Vector3 - local ejectionDirection = (direction or Vector3.yAxis).Unit -- Ensure normalized - - local HorizontalForce = DropletUtil.parse(hForce, NumGen) or NumGen:NextInteger(2, 25) - local VerticalForce = DropletUtil.parse(vForce, NumGen) or NumGen:NextInteger(25, 50) - - -- Create orthonormal basis from direction - -- We need two perpendicular vectors to the direction for the horizontal plane - local up = if math.abs(ejectionDirection.Y) < 0.99 then Vector3.yAxis else Vector3.xAxis - local right = ejectionDirection:Cross(up).Unit - local forward = right:Cross(ejectionDirection).Unit - - -- Generate a random horizontal direction in the plane perpendicular to ejection direction - local RandomRotation = NumGen:NextNumber(-math.pi, math.pi) - local horizontalX = math.cos(RandomRotation) * HorizontalForce - local horizontalZ = math.sin(RandomRotation) * HorizontalForce - - -- Combine: vertical force along direction, horizontal force perpendicular to it - local velocity = ejectionDirection * VerticalForce - + right * horizontalX - + forward * horizontalZ - - return velocity + local ejectionDirection = (direction or Vector3.yAxis).Unit -- Ensure normalized + + local HorizontalForce = DropletUtil.parse(hForce, NumGen) or NumGen:NextInteger(2, 25) + local VerticalForce = DropletUtil.parse(vForce, NumGen) or NumGen:NextInteger(25, 50) + + -- Create orthonormal basis from direction + -- We need two perpendicular vectors to the direction for the horizontal plane + local up = if math.abs(ejectionDirection.Y) < 0.99 then Vector3.yAxis else Vector3.xAxis + local right = ejectionDirection:Cross(up).Unit + local forward = right:Cross(ejectionDirection).Unit + + -- Generate a random horizontal direction in the plane perpendicular to ejection direction + local RandomRotation = NumGen:NextNumber(-math.pi, math.pi) + local horizontalX = math.cos(RandomRotation) * HorizontalForce + local horizontalZ = math.sin(RandomRotation) * HorizontalForce + + -- Combine: vertical force along direction, horizontal force perpendicular to it + local velocity = ejectionDirection * VerticalForce + right * horizontalX + forward * horizontalZ + + return velocity end local function ParseLocation(location): CFrame - if typeof(location) == "Vector3" then - return CFrame.new(location) - elseif typeof(location) == "CFrame" then - return location - elseif typeof(location) == "table" then - if location.Obj then - return location.Obj:GetPivot() - end - return location.CF - end - error("Invalid location type: "..tostring(location)) + if typeof(location) == "Vector3" then + return CFrame.new(location) + elseif typeof(location) == "CFrame" then + return location + elseif typeof(location) == "table" then + if location.Obj then + return location.Obj:GetPivot() + end + return location.CF + end + error("Invalid location type: " .. tostring(location)) end -------------------------------------------------------------------------------- @@ -84,47 +82,47 @@ end -------------------------------------------------------------------------------- local DropletClientManager = {} -local DropletStorage: {[number]: Droplet} = {} -local ResourceTypeDataMap: {[string]: ResourceTypeData} = {} +local DropletStorage: { [number]: Droplet } = {} +local ResourceTypeDataMap: { [string]: ResourceTypeData } = {} local RenderOctree: Octree.Octree = Octree.new() local MagnetOctree: Octree.Octree = Octree.new() local DistanceHeap: Heap.Heap = Heap.max() -local CollectionTracker = setmetatable({} :: {[Droplet]: boolean}, {__mode = "k"}) +local CollectionTracker = setmetatable({} :: { [Droplet]: boolean }, { __mode = "k" }) local Replicator = NetWire.Client("DropletServerManager") Replicator.DropletCreated:Connect(function(...) - (DropletClientManager :: any):_OnCreateDroplet(...) + (DropletClientManager :: any):_OnCreateDroplet(...) end) Replicator.DropletClaimed:Connect(function(...: any) - (DropletClientManager :: any):_OnClaimDroplet(...) + (DropletClientManager :: any):_OnClaimDroplet(...) end) RunService.PreSimulation:Connect(function(dt: number) - (DropletClientManager :: any):_Update(dt) + (DropletClientManager :: any):_Update(dt) end) -------------------------------------------------------------------------------- - --// METHODS //-- +--// METHODS //-- -------------------------------------------------------------------------------- --[=[ Registers a new resource type. ]=] function DropletClientManager:RegisterResourceType(resourceType: string, data: ResourceTypeData) - assert(not ResourceTypeDataMap[resourceType], "Resource type already registered") - ResourceTypeDataMap[resourceType] = data + assert(not ResourceTypeDataMap[resourceType], "Resource type already registered") + ResourceTypeDataMap[resourceType] = data end --[=[ Returns the resource type data for the given resource type ]=] function DropletClientManager:GetResourceTypeData(resourceType: string): ResourceTypeData? - return ResourceTypeDataMap[resourceType] + return ResourceTypeDataMap[resourceType] end -------------------------------------------------------------------------------- - --// Private //-- +--// Private //-- -------------------------------------------------------------------------------- --[=[ @@ -135,49 +133,49 @@ end them as being collected as well as updates the droplet visualization ]=] function DropletClientManager:_Update(dt: number) - dt = dt or 0 - - debug.profilebegin("Droplet Collection Check") - if LocalPlayer.Character and LocalPlayer.Character.PrimaryPart then - local PlayerPos = LocalPlayer.Character:GetPivot().Position - - -- Use the maximum magnetization radius from the heap to determine search radius - local maxMagnetizationRadius = DistanceHeap:Peek() or DropletUtil.DEFAULT_COLLECTION_RADIUS - - for node in MagnetOctree:ForEachInRadius(PlayerPos, maxMagnetizationRadius) do - local droplet = node.Object - if CollectionTracker[droplet] then - continue - end - local dropletPos = node.Position - local distance = (PlayerPos - dropletPos).Magnitude - - -- Check if within this droplet's specific magnetization radius - if distance <= droplet:GetMagnetizationRadius() then - -- Check if it must settle before collecting - if not droplet:MustSettleBeforeCollect() or droplet:IsSettled() then - CollectionTracker[droplet] = true - DropletClientManager:_RequestClaimDroplet(droplet) - end - end - end - end - debug.profileend() - - debug.profilebegin("Droplet Position Update") - Droplet.processRendering() - debug.profileend() - - debug.profilebegin("Droplet Visualization Update") - local RENDER_RADIUS = DropletUtil.RENDER_RADIUS - local isOnScreen = RailUtil.Camera.isOnScreen - local pos: Vector3 = (Camera.CFrame + Camera.CFrame.LookVector * (RENDER_RADIUS/2)).Position - for node in RenderOctree:ForEachInRadius(pos, RENDER_RADIUS + 1) do - if isOnScreen(node.Position) then - node.Object:_Render(dt) - end - end - debug.profileend() + dt = dt or 0 + + debug.profilebegin("Droplet Collection Check") + if LocalPlayer.Character and LocalPlayer.Character.PrimaryPart then + local PlayerPos = LocalPlayer.Character:GetPivot().Position + + -- Use the maximum magnetization radius from the heap to determine search radius + local maxMagnetizationRadius = DistanceHeap:Peek() or DropletUtil.DEFAULT_COLLECTION_RADIUS + + for node in MagnetOctree:ForEachInRadius(PlayerPos, maxMagnetizationRadius) do + local droplet = node.Object + if CollectionTracker[droplet] then + continue + end + local dropletPos = node.Position + local distance = (PlayerPos - dropletPos).Magnitude + + -- Check if within this droplet's specific magnetization radius + if distance <= droplet:GetMagnetizationRadius() then + -- Check if it must settle before collecting + if not droplet:MustSettleBeforeCollect() or droplet:IsSettled() then + CollectionTracker[droplet] = true + DropletClientManager:_RequestClaimDroplet(droplet) + end + end + end + end + debug.profileend() + + debug.profilebegin("Droplet Position Update") + Droplet.processRendering() + debug.profileend() + + debug.profilebegin("Droplet Visualization Update") + local RENDER_RADIUS = DropletUtil.RENDER_RADIUS + local isOnScreen = RailUtil.Camera.isOnScreen + local pos: Vector3 = (Camera.CFrame + Camera.CFrame.LookVector * (RENDER_RADIUS / 2)).Position + for node in RenderOctree:ForEachInRadius(pos, RENDER_RADIUS + 1) do + if isOnScreen(node.Position) then + node.Object:_Render(dt) + end + end + debug.profileend() end --[=[ @@ -185,23 +183,23 @@ end Marks a droplet to be checked for collection ]=] function DropletClientManager:_MarkForCollection(droplet: Droplet) - assert(not MagnetOctree:FindFirstNode(droplet), "Droplet already marked for collection") - local node = MagnetOctree:CreateNode(droplet:GetPosition(), droplet) - - droplet:GetSignal("PositionChanged"):Connect(function(newPos) - MagnetOctree:ChangeNodePosition(node, newPos) - end) - - -- Track magnetization radius in heap for dynamic radius checking - local magnetizationRadius = droplet:GetMagnetizationRadius() - DistanceHeap:Push(magnetizationRadius) - - local function Remove() - MagnetOctree:RemoveNode(node) - DistanceHeap:RemoveFirstOccurrence(magnetizationRadius) - end - droplet:GetSignal("TimedOut"):Once(Remove) - droplet:GetDestroyedSignal():Once(Remove) + assert(not MagnetOctree:FindFirstNode(droplet), "Droplet already marked for collection") + local node = MagnetOctree:CreateNode(droplet:GetPosition(), droplet) + + droplet:GetSignal("PositionChanged"):Connect(function(newPos) + MagnetOctree:ChangeNodePosition(node, newPos) + end) + + -- Track magnetization radius in heap for dynamic radius checking + local magnetizationRadius = droplet:GetMagnetizationRadius() + DistanceHeap:Push(magnetizationRadius) + + local function Remove() + MagnetOctree:RemoveNode(node) + DistanceHeap:RemoveFirstOccurrence(magnetizationRadius) + end + droplet:GetSignal("TimedOut"):Once(Remove) + droplet:GetDestroyedSignal():Once(Remove) end --[=[ @@ -209,16 +207,18 @@ end Marks a droplet for rendering by placing it into the octree ]=] function DropletClientManager:_MarkForRender(droplet: Droplet) - assert(not RenderOctree:FindFirstNode(droplet), "Droplet already marked for render") - local node = RenderOctree:CreateNode(droplet:GetPosition(), droplet) - - droplet:GetSignal("PositionChanged"):Connect(function(newPos) - RenderOctree:ChangeNodePosition(node, newPos) - end) - - local function Remove() RenderOctree:RemoveNode(node) end - droplet:GetSignal("TimedOut"):Once(Remove) - droplet:GetDestroyedSignal():Once(Remove) + assert(not RenderOctree:FindFirstNode(droplet), "Droplet already marked for render") + local node = RenderOctree:CreateNode(droplet:GetPosition(), droplet) + + droplet:GetSignal("PositionChanged"):Connect(function(newPos) + RenderOctree:ChangeNodePosition(node, newPos) + end) + + local function Remove() + RenderOctree:RemoveNode(node) + end + droplet:GetSignal("TimedOut"):Once(Remove) + droplet:GetDestroyedSignal():Once(Remove) end --[=[ @@ -226,102 +226,103 @@ end Called when the server informs us that a new droplet has been created ]=] function DropletClientManager:_OnCreateDroplet(networkPacket: DropletUtil.DropletNetworkPacket) - local rtData = DropletClientManager:GetResourceTypeData(networkPacket.ResourceType) - assert(rtData, `Resource type '{tostring(networkPacket.ResourceType)}' not registered`) - local DEFAULTS = rtData.Defaults - - local Seed = networkPacket.Seed - local Value = networkPacket.Value - local Count = networkPacket.Count - local LifeTime = networkPacket.LifeTime - networkPacket.Metadata = networkPacket.Metadata or DEFAULTS.Metadata - - local Droplets: {[number]: Droplet} = {} - DropletStorage[Seed] = { - NetworkPacket = networkPacket, - Droplets = Droplets, - } - - local NumGen = Random.new(Seed) - local EjectionDuration = DropletUtil.parse(networkPacket.EjectionDuration, NumGen) - - for i, rawData in DropletUtil.calculateDropletValues(Value, Count, Seed, LifeTime) do - local droplet = Droplet.new({ - Id = i, - NetworkPacket = networkPacket, - ResourceTypeData = DropletClientManager:GetResourceTypeData(networkPacket.ResourceType), - - Value = rawData.RawValue, - LifeTime = rawData.RawLifeTime, - - DropletClientManager = DropletClientManager, - }) - - droplet:AddTask(function() - Droplets[i] = nil - end) - - droplet:GetSignal("Collected"):Connect(function(collector) - if collector == LocalPlayer then - DropletClientManager:_RequestCollectDroplet(droplet) - end - end) - - - local dropletModel: Model = droplet:GetModel() - local spawnCFrame = ParseLocation(networkPacket.SpawnLocation) - dropletModel:PivotTo(spawnCFrame) - dropletModel.Parent = DropletsFolder - local dropletPrimaryPart = dropletModel.PrimaryPart - assert(dropletPrimaryPart, "Droplet model has no primary part") - - -- Extract ejection direction from spawn location if it's a CFrame, otherwise use default - local ejectionDirection = networkPacket.EjectionDirection or DEFAULTS.EjectionDirection - if not ejectionDirection and typeof(networkPacket.SpawnLocation) == "CFrame" then - ejectionDirection = networkPacket.SpawnLocation.LookVector - elseif not ejectionDirection and typeof(networkPacket.SpawnLocation) == "table" and networkPacket.SpawnLocation.CF then - ejectionDirection = networkPacket.SpawnLocation.CF.LookVector - end - - dropletPrimaryPart.AssemblyLinearVelocity = CalculateEjectionVelocity( - networkPacket.EjectionHorizontalVelocity or DEFAULTS.EjectionHorizontalVelocity, - networkPacket.EjectionVerticalVelocity or DEFAULTS.EjectionVerticalVelocity, - ejectionDirection, - NumGen - ) - - Droplets[i] = droplet - task.wait(EjectionDuration/Count) - end + local rtData = DropletClientManager:GetResourceTypeData(networkPacket.ResourceType) + assert(rtData, `Resource type '{tostring(networkPacket.ResourceType)}' not registered`) + local DEFAULTS = rtData.Defaults + + local Seed = networkPacket.Seed + local Value = networkPacket.Value + local Count = networkPacket.Count + local LifeTime = networkPacket.LifeTime + networkPacket.Metadata = networkPacket.Metadata or DEFAULTS.Metadata + + local Droplets: { [number]: Droplet } = {} + DropletStorage[Seed] = { + NetworkPacket = networkPacket, + Droplets = Droplets, + } + + local NumGen = Random.new(Seed) + local EjectionDuration = DropletUtil.parse(networkPacket.EjectionDuration, NumGen) + + for i, rawData in DropletUtil.calculateDropletValues(Value, Count, Seed, LifeTime) do + local droplet = Droplet.new { + Id = i, + NetworkPacket = networkPacket, + ResourceTypeData = DropletClientManager:GetResourceTypeData(networkPacket.ResourceType), + + Value = rawData.RawValue, + LifeTime = rawData.RawLifeTime, + + DropletClientManager = DropletClientManager, + } + + droplet:AddTask(function() + Droplets[i] = nil + end) + + droplet:GetSignal("Collected"):Connect(function(collector) + if collector == LocalPlayer then + DropletClientManager:_RequestCollectDroplet(droplet) + end + end) + + local dropletModel: Model = droplet:GetModel() + local spawnCFrame = ParseLocation(networkPacket.SpawnLocation) + dropletModel:PivotTo(spawnCFrame) + dropletModel.Parent = DropletsFolder + local dropletPrimaryPart = dropletModel.PrimaryPart + assert(dropletPrimaryPart, "Droplet model has no primary part") + + -- Extract ejection direction from spawn location if it's a CFrame, otherwise use default + local ejectionDirection = networkPacket.EjectionDirection or DEFAULTS.EjectionDirection + if not ejectionDirection and typeof(networkPacket.SpawnLocation) == "CFrame" then + ejectionDirection = networkPacket.SpawnLocation.LookVector + elseif + not ejectionDirection + and typeof(networkPacket.SpawnLocation) == "table" + and networkPacket.SpawnLocation.CF + then + ejectionDirection = networkPacket.SpawnLocation.CF.LookVector + end + + dropletPrimaryPart.AssemblyLinearVelocity = CalculateEjectionVelocity( + networkPacket.EjectionHorizontalVelocity or DEFAULTS.EjectionHorizontalVelocity, + networkPacket.EjectionVerticalVelocity or DEFAULTS.EjectionVerticalVelocity, + ejectionDirection, + NumGen + ) + + Droplets[i] = droplet + task.wait(EjectionDuration / Count) + end end - --[=[ @private Called when the server informs us that a droplet has been claimed ]=] function DropletClientManager:_OnClaimDroplet(collector: Player, seed: number, dropletId: number) - local dropletRequest = DropletStorage[seed] - assert(dropletRequest, `No Droplet-Request found with seed '{seed}'`) + local dropletRequest = DropletStorage[seed] + assert(dropletRequest, `No Droplet-Request found with seed '{seed}'`) - local droplet = dropletRequest.Droplets[dropletId] - if not droplet then - warn(dropletRequest.Droplets) - error(`No Droplet found for [{seed}][{dropletId}]`) - end + local droplet = dropletRequest.Droplets[dropletId] + if not droplet then + warn(dropletRequest.Droplets) + error(`No Droplet found for [{seed}][{dropletId}]`) + end - droplet:Claim(collector) + droplet:Claim(collector) end - --[=[ @private Ask the server to claim the droplet so that it can be collected by the player ]=] function DropletClientManager:_RequestClaimDroplet(droplet: Droplet) - local seed, dropletId = droplet:Identify() - --print(`Requesting claim of droplet [{seed}][{dropletId}]`) - Replicator.DropletClaimed:Fire(seed, dropletId) + local seed, dropletId = droplet:Identify() + --print(`Requesting claim of droplet [{seed}][{dropletId}]`) + Replicator.DropletClaimed:Fire(seed, dropletId) end --[=[ @@ -329,10 +330,9 @@ end Inform the server the client successfully collected the droplet. ]=] function DropletClientManager:_RequestCollectDroplet(droplet: Droplet) - local seed, dropletId = droplet:Identify() - --print(`Requesting collect of droplet [{seed}][{dropletId}]`) - Replicator.DropletCollected:Fire(seed, dropletId) + local seed, dropletId = droplet:Identify() + --print(`Requesting collect of droplet [{seed}][{dropletId}]`) + Replicator.DropletCollected:Fire(seed, dropletId) end - -return DropletClientManager \ No newline at end of file +return DropletClientManager diff --git a/lib/roam/src/init.luau b/lib/roam/src/init.luau index 4730ecb..09de9c1 100644 --- a/lib/roam/src/init.luau +++ b/lib/roam/src/init.luau @@ -13,8 +13,8 @@ functionality, and instead focuses on providing a simple methodology to easily initialize Services given to it. - Roam gathers a collection of specified services and initializes 'syncronously'. - Once all services have been fully initialized, it then starts them 'asyncronously' by + Roam gathers a collection of specified services and initializes 'synchronously'. + Once all services have been fully initialized, it then starts them 'asynchronously' by spawning their 'RoamStart' method in a new thread. Roam is RunContext agnostic, meaning it can be used on both the server and client in the same manner. @@ -59,6 +59,37 @@ Roam does not inherently have networking functionality. However, it can easily be added through the use of NetWire's **[.setupServiceNetworking](https://raild3x.github.io/ModulesOnRails/api/ServerNetWire/#setupServiceNetworking)** funtion. ::: + + ---- + LIFECYCLE + ---- + For those interested in the full execution order roam follows for booting services, see the diagrams below: + + **Initialization Phase (Synchronous):** + - `GlobalPreInit` - Called once before ANY service initializes (global setup) + - For each service (in dependency order): + - Await dependencies to finish initializing + - `PreInit(service)` - Called before this service's RoamInit + - Service's `RoamInit()` method executes + - `PostInit(service)` - Called after this service's RoamInit + - `GlobalPostInit` - Called once after ALL services finish initializing + + **Start Phase (Fully Async - Does Not Block):** + - `GlobalPreStart` - Called once before ANY service starts. + - For each service (in dependency order): + - `PreStart(service)` - Called before this service's RoamStart + - Service's `RoamStart()` method executes + - `PostStart(service)` - Called after this service's RoamStart + - `GlobalPostStart` - Called once after ALL services start + + + **Key Concepts:** + - **Parallel Initialization**: Services without dependencies initialize concurrently via coroutines + - **Dependency Blocking**: Services wait for their dependencies' PostInit before starting their PreInit + - **Synchronous Init Phase**: The Initialization Phase completes fully before Start Phase begins + - **Async Start Phase**: The Start Phase spawns services lifecycle methods asynchronously + + ![Advanced Roam Lifecycle Diagram](../roam/RoamLifecycleAdvanced.png) ]=] local RunService = game:GetService("RunService") @@ -106,7 +137,7 @@ export type Service = table return MyService ``` - :::caution Deffering RequiredServices + :::caution Deferring RequiredServices Do NOT add services to the RequiredServices after you have created or registered the service. This will cause undefined behavior. ::: ]=] @@ -115,9 +146,41 @@ export type ServiceConfig = { RequiredServices: { Service }?, -- The Services that this Service depends on. Roam will ensure that these Services are initialized before this Service. StartMethodName: string?, -- Overrides default StartMethodName of "RoamStart" InitMethodName: string?, -- Overrides default InitMethodName of "RoamInit" + InitTimeout: number?, -- Overrides default init timeout in seconds (default: 120) [any]: any, } +--[=[ + @within Roam + @tag debug + @type ServiceState "REGISTERED" | "AWAITING_DEPENDENCIES" | "PRE_INIT" | "ROAM_INIT" | "POST_INIT" | "INITIALIZED" | "PRE_START" | "ROAM_START" | "POST_START" | "STARTED" | "FAILED" + + Represents the current lifecycle state of a service: + - `REGISTERED` - Service has been registered but not yet initialized + - `AWAITING_DEPENDENCIES` - Service is waiting for its RequiredServices to finish initializing + - `PRE_INIT` - Calling PreInit with service + - `ROAM_INIT` - Calling Service:RoamInit method + - `POST_INIT` - Calling PostInit with service + - `INITIALIZED` - Service has completed all initialization steps + - `PRE_START` - Calling PreStart with service + - `ROAM_START` - Calling Service:RoamStart method + - `POST_START` - Calling PostStart with service + - `ACTIVE` - Service is actively running and has completed its startup routine + - `FAILED` - Service initialization failed +]=] +export type ServiceState = + "REGISTERED" + | "AWAITING_DEPENDENCIES" + | "PRE_INIT" + | "ROAM_INIT" + | "POST_INIT" + | "INITIALIZED" + | "PRE_START" + | "ROAM_START" + | "POST_START" + | "STARTED" + | "FAILED" + type Promise = typeof(Promise.new()) -------------------------------------------------------------------------------- @@ -135,6 +198,7 @@ local RUN_CONTEXT = RunService:IsServer() and "SERVER" or "CLIENT" -------------------------------------------------------------------------------- local services: { [string]: Service } = {} +local serviceStates: { [Service]: ServiceState } = {} -- Track state of each service local started = false local startedComplete = false local onStartedComplete = Instance.new("BindableEvent") @@ -147,19 +211,15 @@ local function serviceNameMatch(obj: Instance): boolean return obj.Name:match("Service$") ~= nil end -local function reconcile(primary: T?, secondary: T): T - primary = primary or {} :: any - secondary = secondary or {} :: any - for key, value in pairs(secondary :: any) do - (primary :: any)[key] = (primary :: any)[key] or value - end - return primary :: T +local function setServiceState(service: Service, state: ServiceState): () + serviceStates[service] = state end local function serviceExists(service: string | table): boolean if type(service) == "string" then return services[service] ~= nil elseif type(service) == "table" then + -- Check if the service table is registered for _, registeredService in pairs(services) do if registeredService == service then return true @@ -185,6 +245,7 @@ local function ensureUnyieldingRequire(module: ModuleScript) end) if coroutine.status(current) ~= "dead" then + -- This is not a great traceback. I wish it could find the original yield point, but I cant detect which modules are being required. error( `Roam Require detected yield. Check the following module and the modules it requires: {module:GetFullName()}` ) @@ -301,13 +362,12 @@ end --// Service Management //-- -------------------------------------------------------------------------------- -local rejectedInitializations = {} local function createServiceInitPromise(service: Service, config: ServiceConfig): Promise? local initMethodName = config.InitMethodName or DEFAULT_INIT_METHOD local initMethod = service[initMethodName] if type(initMethod) ~= "function" then - return nil + return Promise.resolve(0) end return Promise.new(function(resolve, reject) @@ -323,30 +383,28 @@ local function createServiceInitPromise(service: Service, config: ServiceConfig) error(`{config.Name} | Cannot call Init method after service has been initialized`) end - local success = false + local elapsed local initThread = task.spawn(function() - debug.setmemorycategory(config.Name) + debug.setmemorycategory(config.Name .. "_Init") initFunction(service) - success = true + elapsed = os.clock() - startTime end) while coroutine.status(initThread) ~= "dead" do task.wait() end - if not success then - table.insert(rejectedInitializations, "\n - " .. config.Name) + if not elapsed then reject(`Failed to initialize {config.Name}`) return end - local elapsed = os.clock() - startTime if Roam.Debug then print(`[{RUN_CONTEXT}] Initialized {config.Name} in {string.format("%.3f", elapsed)}s`) end resolve(elapsed) - end):timeout(INIT_TIMEOUT_SECONDS, `Service {config.Name} took too long to initialize`) + end):timeout(config.InitTimeout or INIT_TIMEOUT_SECONDS, `Service {config.Name} took too long to initialize`) end local function startService(service: Service, config: ServiceConfig): () @@ -362,7 +420,7 @@ local function startService(service: Service, config: ServiceConfig): () print(`[{RUN_CONTEXT}] Starting {config.Name}`) end - debug.setmemorycategory(config.Name) + debug.setmemorycategory(config.Name .. "_Start") local startFunction = service[startMethodName] -- Prevent re-starting @@ -420,15 +478,6 @@ end --// Main Roam Module //-- -------------------------------------------------------------------------------- ---[=[ - @private - @within Roam - @tag ReadOnly - @prop ClassName "Roam" - The ClassName of the Roam module. -]=] -Roam.ClassName = "Roam" - --[=[ @within Roam @prop Services {[string]: Service} @@ -453,14 +502,15 @@ Roam.DEFAULT_SRC_NAME = "src" A table of generic bootstrappers for Roam that you can use to quickly setup new projects. ```lua local Roam = require(Packages.Roam) - + Roam.Bootstrappers.Server(script) :andThenCall(print, "Roam Server Bootstrapped!") ``` ]=] +type BootStrapper = (script: Script, config: { [string]: any }?) -> Promise Roam.Bootstrappers = { -- Generic Bootstrappers for Roam / Orion - Server = require(script:FindFirstChild("Bootstrappers"):FindFirstChild("ServerBootstrapper")) :: (script: Script, config: { [string]: any }?) -> Promise, - Client = require(script:FindFirstChild("Bootstrappers"):FindFirstChild("ClientBootstrapper")) :: (script: Script, config: { [string]: any }?) -> Promise, + Server = require(script:FindFirstChild("Bootstrappers"):FindFirstChild("ServerBootstrapper")) :: BootStrapper, + Client = require(script:FindFirstChild("Bootstrappers"):FindFirstChild("ClientBootstrapper")) :: BootStrapper, } --[=[ @@ -496,25 +546,37 @@ function Roam.registerService(service: Service, serviceConfig: (ServiceConfig | end local config = validateServiceConfig(serviceConfig, service.Name) - local reconciledConfig = table.freeze(reconcile(config, { Name = config.Name })) - service[KEY_CONFIG] = reconciledConfig + service[KEY_CONFIG] = config services[config.Name] = service + serviceStates[service] = "REGISTERED" -- Track initial state return service end --[=[ - @param postInitPreStart (() -> (Promise?))? - @return Promise + @within Roam Starts Roam. Should only be called once. Calling multiple times will result in a promise rejection. - Optional argument `postInitPreStart` is a function that is called - after all services have been initialized, but before they are started. - + Optional config argument provides lifecycle hooks in execution order: + Init lifecycle hooks can recieve a promise as a return value to delay progression until resolved. + ```lua - Roam.start() + Roam.start({ + GlobalPreInit = function() + print("=== Initialization Phase Starting ===") + end, + PreInit = function(service) + print("Initializing:", Roam.getServiceName(service)) + end, + PostInit = function(service) + print("āœ“ Initialized:", Roam.getServiceName(service)) + end, + GlobalPostInit = function() + print("=== All Services Initialized ===") + end, + }) :andThenCall(print, "Roam started!") :catch(warn) ``` @@ -524,22 +586,61 @@ end calling `Start`. Services cannot be added later. ::: - :::tip Bootstrapping - You can use the [Roam.Bootstrappers](Roam#Bootstrappers) table/methods to quickly bootstrap Roam in your project. - This is reccomended as it will provide a consistent starting point for your projects. - ::: ]=] -function Roam.start(postInitPreStart: (() -> Promise?)?): Promise +function Roam.start(config: { + GlobalPreInit: (() -> Promise?)?, + PreInit: ((service: Service) -> Promise?)?, + PostInit: ((service: Service) -> Promise?)?, + GlobalPostInit: (() -> Promise?)?, + GlobalPreStart: (() -> ())?, + PreStart: ((service: Service) -> ())?, + PostStart: ((service: Service) -> ())?, + GlobalPostStart: (() -> ())?, +}?): Promise if started then return Promise.reject("Roam already started") end - if postInitPreStart and type(postInitPreStart) ~= "function" then - error( - formatError("Invalid Parameter", `postInitPreStart must be a function or nil, got {type(postInitPreStart)}`) - ) + -- Validate and extract lifecycle hooks from config + local function validateHook(hookName: string): ((...any) -> any)? + if not config then + return nil + end + + local hookValue = (config :: any)[hookName] + if hookValue ~= nil and type(hookValue) ~= "function" then + error(formatError("Invalid Parameter", `{hookName} must be a function or nil, got {type(hookValue)}`)) + end + return hookValue end + -- Helper to call a lifecycle hook and handle Promise results + local function callLifecycleHook(hook: ((service: Service?) -> Promise?)?, service: Service?, async: boolean?) + if not hook then + return + end + + if async then + task.defer(hook, service) + else + local result = hook(service) + -- If the hook returns a Promise, await it + if result and typeof(result) == "table" and result.await then + result:await() + end + end + end + + -- Extract and validate all lifecycle hooks + local globalPreInit = validateHook("GlobalPreInit") + local preInit = validateHook("PreInit") + local postInit = validateHook("PostInit") + local globalPostInit = validateHook("GlobalPostInit") + local globalPreStart = validateHook("GlobalPreStart") + local preStart = validateHook("PreStart") + local postStart = validateHook("PostStart") + local globalPostStart = validateHook("GlobalPostStart") + started = true -- Validate all required services are registered @@ -550,67 +651,124 @@ function Roam.start(postInitPreStart: (() -> Promise?)?): Promise local sortedServices = getSortedServices() - return Promise.new(function(resolve) + return Promise.new(function(resolve, reject) + local startTime = os.clock() table.freeze(services) + Roam.Services = services + + -- GlobalPreInit hook + callLifecycleHook(globalPreInit) - -- Initialize services - local initPromises = {} - local totalInitTime = 0 + -- Track completion promises for each service (for dependency blocking) + local rejectedInitializations: { string } = {} + local serviceCompletionPromises: { [Service]: Promise } = {} + local initPromises: { Promise } = {} + -- Initialize services with dependency-aware parallelization for _, service in ipairs(sortedServices) do - local config = service[KEY_CONFIG] - local initPromise = createServiceInitPromise(service, config) - - if initPromise then - table.insert( - initPromises, - initPromise:andThen(function(elapsed) - totalInitTime += elapsed - end) - ) + local serviceConfig = service[KEY_CONFIG] + + local dependencyPromises = {} + if serviceConfig.RequiredServices then + for _, requiredService in ipairs(serviceConfig.RequiredServices) do + local depPromise = serviceCompletionPromises[requiredService] + if depPromise then + table.insert(dependencyPromises, depPromise) + else + warn( + formatError( + "Missing Dependency Promise", + `Service "{serviceConfig.Name}" has a required service that lacks a completion promise` + ) + ) + end + end end - end - - Roam.Services = services - local initializationPromise = Promise.all(initPromises) - :andThen(function() - if Roam.Debug then - print(`[{RUN_CONTEXT}] All services initialized in {string.format("%.3f", totalInitTime)}s`) - end - end) - :catch(function(error) - return Promise.reject( - formatError( - "Initialization Failed for the following services", - table.concat(rejectedInitializations) - ) - ) + serviceStates[service] = "AWAITING_DEPENDENCIES" + local errMsg = "\n - " .. serviceConfig.Name + + local servicePromise = Promise.all(dependencyPromises):andThen(function() + -- Dependencies are ready + return Promise.resolve() + :andThenCall(setServiceState, service, "PRE_INIT") + :andThenCall(callLifecycleHook, preInit, service) + :andThenCall(setServiceState, service, "ROAM_INIT") + :andThenCall(createServiceInitPromise, service, serviceConfig) + :andThenCall(setServiceState, service, "POST_INIT") + :andThenCall(callLifecycleHook, postInit, service) + :andThenCall(setServiceState, service, "INITIALIZED") + :catch(function(err) + table.insert(rejectedInitializations, errMsg) + serviceStates[service] = "FAILED" + return Promise.reject(err) + end) + end, function(err) + table.insert(rejectedInitializations, errMsg .. " (Dependency Failed) [" .. tostring(err) .. "]") + serviceStates[service] = "FAILED" + return Promise.reject(err) end) - resolve(initializationPromise) - end) - :andThen(function() - -- Call post-init hook if provided - if postInitPreStart then - return postInitPreStart() + -- Track this service's completion for dependent services + serviceCompletionPromises[service] = servicePromise + table.insert(initPromises, servicePromise) + end + + -- Wait for all services to complete initialization + local success: boolean = Promise.all(initPromises):await() + + if success then + -- GlobalPostInit hook + callLifecycleHook(globalPostInit) + local totalInitTime = os.clock() - startTime + if Roam.Debug then + print(`[{RUN_CONTEXT}] All services initialized in {string.format("%.3f", totalInitTime)}s`) end - return nil - end) - :andThen(function() - -- Start services - for _, service in ipairs(sortedServices) do - local config = service[KEY_CONFIG] - startService(service, config) + resolve(totalInitTime) + else + local errMsg = + formatError("Initialization Failed for the following services", table.concat(rejectedInitializations)) + reject(errMsg) + end + end):andThen(function() + --------------------------------------------------------------------- + -- START Phase (Fully Async - Does Not Block) -- + --------------------------------------------------------------------- + + -- GlobalPreStart hook + callLifecycleHook(globalPreStart, nil, true) + + -- Start services with interleaved hooks (respects dependency order) + for _, service in ipairs(sortedServices) do + if serviceStates[service] == "FAILED" then + continue -- skip starting failed services end + local serviceConfig = service[KEY_CONFIG] + -- PreStart hook + serviceStates[service] = "PRE_START" + callLifecycleHook(preStart, service, true) - startedComplete = true - onStartedComplete:Fire() + -- Service Start + serviceStates[service] = "ROAM_START" + startService(service, serviceConfig) - task.defer(function() - onStartedComplete:Destroy() - end) + -- PostStart hook + serviceStates[service] = "POST_START" + callLifecycleHook(postStart, service, true) + + serviceStates[service] = "STARTED" + end + + -- GlobalPostStart hook + callLifecycleHook(globalPostStart, nil, true) + + startedComplete = true + onStartedComplete:Fire() + + task.defer(function() + onStartedComplete:Destroy() end) + end) end --[=[ @@ -645,8 +803,9 @@ end way to quickly load all services that might be in a folder. Takes an optional predicate function to filter which modules are loaded. Services collected this way must not yield. - `DeepSearch` -> whether it checks descendants or just children + - `AllowYieldingRequires` -> whether to allow required modules to yield (default: false) - `RequirePredicate` -> a predicate function that determines whether a module should be required - - `IgnoreDescendantsPredicate` -> A Predicate for whether the Descendants of the Module should be Searched (Only matters if DeepSearch is true) + - `IgnoreDescendantsPredicate` -> A Predicate for whether the Descendants of an instance should be Searched (Only matters if DeepSearch is true) - `StopOnFailedRequire` -> whether to stop requiring modules if one fails to require (default: false). Useful for debugging, helps to clear excessive noise from the output. ```lua @@ -673,6 +832,7 @@ function Roam.requireModules( IgnoreDescendantsPredicate: ((obj: Instance) -> boolean)?, }? ): { + Success: boolean, ModuleContent: { [ModuleScript]: any }, FailedModuleRequires: { ModuleScript }, } @@ -751,15 +911,78 @@ end --[=[ @within Roam @private + @tag debug + Prints the dependency graph of all registered services to the output. +]=] +function Roam.printDependencyGraph(): () + print("Service Dependency Graph:") + for serviceName, service in pairs(services) do + local config = service[KEY_CONFIG] + print(` {serviceName}:`) + if config.RequiredServices then + for _, dep in ipairs(config.RequiredServices) do + local depName = dep[KEY_CONFIG].Name + print(` -> {depName}`) + end + else + print(" (no dependencies)") + end + end +end + +--[=[ + @within Roam + @private + @tag debug + Returns the current lifecycle state of a service. + + @param serviceName string | Service -- Either the name of the service or the service table itself + @return ServiceState? -- The current state of the service, or nil if not found + + ```lua + local state = Roam.getServiceState("MyService") + if state == "STARTED" then + print("MyService is fully running!") + end + ``` +]=] +function Roam.getServiceState(serviceName: string | Service): ServiceState? + local service: Service? + + if type(serviceName) == "string" then + service = services[serviceName] + elseif type(serviceName) == "table" then + service = serviceName + else + error( + formatError( + "Invalid Argument", + `getServiceState expects a string or Service table, got {type(serviceName)}` + ) + ) + end + + if not service then + return nil + end + + return serviceStates[service] +end + +--[=[ + @within Roam + @private + @tag debug Fetches the name of a registered Service. ]=] -function Roam.getNameFromService(service: Service): string +function Roam.getServiceName(service: Service): string local config = service[KEY_CONFIG] if not config then error(formatError("Invalid Service", "Service is not registered with Roam")) end return config.Name end +Roam.getNameFromService = Roam.getServiceName -- backwards compat --[=[ @deprecated 0.1.5 From f6d98d002f6fb2ecd833657faef7782d999146e5 Mon Sep 17 00:00:00 2001 From: Logan Hunt <2dloganh@gmail.com> Date: Mon, 19 Jan 2026 14:36:56 -0500 Subject: [PATCH 3/9] Add StartConfig support to Roam bootstrappers Introduces the StartConfig type to Roam and updates ClientBootstrapper and ServerBootstrapper to accept and pass custom lifecycle hooks to Roam.start. Refactors config handling for module requiring and improves error handling. Updates example setup to use new requireModules options. Bumps wally.toml version to 0.2.0. --- .../src/Bootstrappers/ClientBootstrapper.luau | 112 ++++++++++-------- .../src/Bootstrappers/ServerBootstrapper.luau | 40 ++++--- lib/roam/src/Bootstrappers/_ExampleSetup.luau | 22 ++-- lib/roam/src/init.luau | 11 ++ lib/roam/wally.toml | 2 +- 5 files changed, 105 insertions(+), 82 deletions(-) diff --git a/lib/roam/src/Bootstrappers/ClientBootstrapper.luau b/lib/roam/src/Bootstrappers/ClientBootstrapper.luau index 9ed97a8..836adb6 100644 --- a/lib/roam/src/Bootstrappers/ClientBootstrapper.luau +++ b/lib/roam/src/Bootstrappers/ClientBootstrapper.luau @@ -4,57 +4,67 @@ local ReplicatedStorage = game:GetService("ReplicatedStorage") local BootstrapperModule = script +local Roam = require(BootstrapperModule.Parent.Parent) +local Promise = require(BootstrapperModule.Parent.Parent.Parent.Promise) -local function StartGame(script, requireConfig: { - AllowYieldingRequires: boolean?; -- Default: false - StopOnFailedRequire: boolean?; -- Default: true -}?) - local Promise = require(BootstrapperModule.Parent.Parent.Parent.Promise) - if script.Name == "start" then -- We may want to remove this check later. It doesnt allow nice custom structures since its tailored to my opinion. - script:Destroy() - return Promise.reject() - end - - local Roam = require(BootstrapperModule.Parent.Parent) - local SRC_NAME = Roam.DEFAULT_SRC_NAME - -- Roam.Debug = true -- Enables prints to see when services Init and Start - - -- Require modules under the Client folder that end in "Service" or "Controller" - local result = Roam.requireModules({ - ReplicatedStorage[SRC_NAME].Client; - ReplicatedStorage[SRC_NAME].Shared; - }, { - DeepSearch = true; - StopOnFailedRequire = if requireConfig and requireConfig.StopOnFailedRequire ~= nil then requireConfig.StopOnFailedRequire else true; - AllowYieldingRequires = if requireConfig and requireConfig.AllowYieldingRequires ~= nil then requireConfig.AllowYieldingRequires else false; - RequirePredicate = function(obj: ModuleScript) -- Only require modules that end in "Service" or "Controller" - local isService = obj.Name:match("Service$") or obj.Name:match("Controller$") - return isService - end; - IgnoreDescendantsPredicate = function(obj: Instance) -- Ignore anything under "Server" - return obj.Name == "Server" - end; - }) - - if not result.Success then - return Promise.reject("šŸ›‘ [CLIENT] Failed module requires during client bootstrap šŸ›‘") - end - - -- Wait for the server to start - if not workspace:GetAttribute("RoamStarted") then - workspace:GetAttributeChangedSignal("RoamStarted"):Wait() - end - - -- Start Roam - return Roam.start():andThen(function() - print("[CLIENT] Roam Started!") - return true - end) - :catch(function(err) - local sanitizedError = tostring(err):gsub("%[(.-):", "") - task.spawn(error, "šŸ›‘ [CLIENT] Roam Failed to Start! šŸ›‘" .. sanitizedError) - return false - end) +local function checkConfig(config: any, field: string, default: any?) + if config and config[field] ~= nil then + return config[field] + end + return default end -return StartGame \ No newline at end of file +local function StartGame( + script, + config: ({ + AllowYieldingRequires: boolean?, -- Default: false + StopOnFailedRequire: boolean?, -- Default: true + } & Roam.StartConfig)? +) + if script.Name == "start" then -- We may want to remove this check later. It doesnt allow nice custom structures since its tailored to my opinion. + script:Destroy() + return Promise.resolve(false) + end + + -- Require modules under the Client and Shared folder that end in "Service" or "Controller" + local SRC_NAME = Roam.DEFAULT_SRC_NAME + local result = Roam.requireModules({ + ReplicatedStorage[SRC_NAME].Client, + ReplicatedStorage[SRC_NAME].Shared, + }, { + DeepSearch = true, + StopOnFailedRequire = checkConfig(config, "StopOnFailedRequire", true), + AllowYieldingRequires = checkConfig(config, "AllowYieldingRequires", false), + RequirePredicate = function(obj: ModuleScript) -- Only require modules that end in "Service" or "Controller" + local isService = obj.Name:match("Service$") or obj.Name:match("Controller$") + return isService + end, + IgnoreDescendantsPredicate = function(obj: Instance) -- Ignore anything under "Server" + return obj.Name == "Server" + end, + }) + + if not result.Success then + task.spawn(error, "šŸ›‘ [CLIENT] Failed module requires during client bootstrap šŸ›‘") + return Promise.resolve(false) + end + + -- Wait for the server to start + if not workspace:GetAttribute("RoamStarted") then + workspace:GetAttributeChangedSignal("RoamStarted"):Wait() + end + + -- Start Roam + return Roam.start(config) + :andThen(function() + print("[CLIENT] Roam Started!") + return true + end) + :catch(function(err) + local sanitizedError = tostring(err):gsub("%[(.-):", "") -- Replaces failure warning so I can add a fancier looking one + task.spawn(error, "šŸ›‘ [CLIENT] Roam Failed to Start! šŸ›‘" .. sanitizedError) + return false + end) +end + +return StartGame diff --git a/lib/roam/src/Bootstrappers/ServerBootstrapper.luau b/lib/roam/src/Bootstrappers/ServerBootstrapper.luau index 264dfc5..9f365af 100644 --- a/lib/roam/src/Bootstrappers/ServerBootstrapper.luau +++ b/lib/roam/src/Bootstrappers/ServerBootstrapper.luau @@ -8,6 +8,8 @@ local ReplicatedStorage = game:GetService("ReplicatedStorage") local ServerScriptService = game:GetService("ServerScriptService") local BootstrapperModule = script +local Roam = require(BootstrapperModule.Parent.Parent) +local Promise = require(BootstrapperModule.Parent.Parent.Parent.Promise) local function ShutdownServer(err) local shutdownMsg = `This server has shutdown due to ROAM failing to boot, please contact a dev:\n{err}` @@ -25,28 +27,34 @@ local function ShutdownServer(err) end end -local function StartGame(script, requireConfig: { - AllowYieldingRequires: boolean?; -- Default: false - StopOnFailedRequire: boolean?; -- Default: true - }?) - local Promise = require(BootstrapperModule.Parent.Parent.Parent.Promise) +local function checkConfig(config: any, field: string, default: any?) + if config and config[field] ~= nil then + return config[field] + end + return default +end + +local function StartGame( + script, + config: ({ + AllowYieldingRequires: boolean?, -- Default: false + StopOnFailedRequire: boolean?, -- Default: true + } & Roam.StartConfig)? +) if script.Name == "start" then -- We may want to remove this check later. It doesnt allow nice custom structures since its tailored to my opinion. script:Destroy() - return Promise.reject() + return Promise.resolve(false) end - local Roam = require(BootstrapperModule.Parent.Parent) + -- Register modules under the Server and Shared folders. local SRC_NAME = Roam.DEFAULT_SRC_NAME - -- Roam.Debug = true -- Enables prints to see when services Init and Start - - -- Register modules under the Server folder. local result = Roam.requireModules({ ServerScriptService[SRC_NAME].Server, ReplicatedStorage[SRC_NAME].Shared, }, { DeepSearch = true, - StopOnFailedRequire = if requireConfig and requireConfig.StopOnFailedRequire ~= nil then requireConfig.StopOnFailedRequire else true, - AllowYieldingRequires = if requireConfig and requireConfig.AllowYieldingRequires ~= nil then requireConfig.AllowYieldingRequires else false, + StopOnFailedRequire = checkConfig(config, "StopOnFailedRequire", true), + AllowYieldingRequires = checkConfig(config, "AllowYieldingRequires", false), RequirePredicate = function(obj: ModuleScript) -- Only require modules that end in "Service" local isService = obj.Name:match("Service$") return isService @@ -59,22 +67,22 @@ local function StartGame(script, requireConfig: { if result.Success == false then task.spawn(error, "šŸ›‘ [SERVER] Failed module requires during server bootstrap šŸ›‘") ShutdownServer("Failed module requires during server bootstrap") - return Promise.reject() + return Promise.resolve(false) end -- Start Roam - return Roam.start() + return Roam.start(config) :andThen(function() print("[SERVER] Roam Started!") workspace:SetAttribute("RoamStarted", true) -- Alert the Client that the Server is ready return true end) :catch(function(err) - local sanitizedError = tostring(err):gsub("%[(.-):", "") + local sanitizedError = tostring(err):gsub("%[(.-):", "") -- Replaces failure warning so I can add a fancier looking one task.spawn(error, "šŸ›‘ [SERVER] Roam Failed to Start! šŸ›‘" .. sanitizedError) ShutdownServer(err) return false end) end -return StartGame \ No newline at end of file +return StartGame diff --git a/lib/roam/src/Bootstrappers/_ExampleSetup.luau b/lib/roam/src/Bootstrappers/_ExampleSetup.luau index 53e6461..2bd3ca5 100644 --- a/lib/roam/src/Bootstrappers/_ExampleSetup.luau +++ b/lib/roam/src/Bootstrappers/_ExampleSetup.luau @@ -13,15 +13,11 @@ local Roam = require(Packages.Roam) local function StartGame() -- Register modules under the Server folder. - Roam.requireModules( - { - ServerScriptService.Server, - }, - true, - function(obj: ModuleScript) -- Only require modules that end in "Service" - return obj.Name:match("Service$") ~= nil - end - ) + Roam.requireModules({ + ServerScriptService.Server, + }, { + DeepSearch = true, + }) -- Start Roam return Roam.start() @@ -48,11 +44,9 @@ local Roam = require(Packages.Roam) local function StartGame() -- Require modules under the Client folder that end. - Roam.requireModules( - { - ReplicatedStorage.Client, - } - ) + Roam.requireModules { + ReplicatedStorage.Client, + } -- Wait for the server to start Roam if not workspace:GetAttribute("RoamStarted") then diff --git a/lib/roam/src/init.luau b/lib/roam/src/init.luau index 09de9c1..481a641 100644 --- a/lib/roam/src/init.luau +++ b/lib/roam/src/init.luau @@ -554,6 +554,17 @@ function Roam.registerService(service: Service, serviceConfig: (ServiceConfig | return service end +export type StartConfig = { + GlobalPreInit: (() -> Promise?)?, + PreInit: ((service: Service) -> Promise?)?, + PostInit: ((service: Service) -> Promise?)?, + GlobalPostInit: (() -> Promise?)?, + GlobalPreStart: (() -> ())?, + PreStart: ((service: Service) -> ())?, + PostStart: ((service: Service) -> ())?, + GlobalPostStart: (() -> ())?, +} + --[=[ @within Roam diff --git a/lib/roam/wally.toml b/lib/roam/wally.toml index 6808aeb..8856e7e 100644 --- a/lib/roam/wally.toml +++ b/lib/roam/wally.toml @@ -2,7 +2,7 @@ name = "raild3x/roam" description = "Roam is a service initialization framework for Roblox." authors = ["Logan Hunt (Raildex)"] -version = "0.1.6" +version = "0.2.0" license = "MIT" registry = "https://github.com/UpliftGames/wally-index" realm = "shared" From 6c02f4076c30c9489f0aa42efb8c6af1817cce89 Mon Sep 17 00:00:00 2001 From: Logan Hunt <2dloganh@gmail.com> Date: Mon, 19 Jan 2026 14:40:01 -0500 Subject: [PATCH 4/9] Refactor module loading in _ExampleSetup.luau Replaced Roam.requireModules with direct iteration and require of ModuleScript descendants for both Server and Client folders. This simplifies module registration and removes dependency on Roam's module loading utility. --- lib/roam/src/Bootstrappers/_ExampleSetup.luau | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/lib/roam/src/Bootstrappers/_ExampleSetup.luau b/lib/roam/src/Bootstrappers/_ExampleSetup.luau index 2bd3ca5..3bbf8d6 100644 --- a/lib/roam/src/Bootstrappers/_ExampleSetup.luau +++ b/lib/roam/src/Bootstrappers/_ExampleSetup.luau @@ -12,12 +12,9 @@ local Packages = ReplicatedStorage.Packages local Roam = require(Packages.Roam) local function StartGame() - -- Register modules under the Server folder. - Roam.requireModules({ - ServerScriptService.Server, - }, { - DeepSearch = true, - }) + for _, module in ServerScriptService.Server:QueryDescendants("ModuleScript") do + require(module) + end -- Start Roam return Roam.start() @@ -43,10 +40,9 @@ local Packages = ReplicatedStorage.Packages local Roam = require(Packages.Roam) local function StartGame() - -- Require modules under the Client folder that end. - Roam.requireModules { - ReplicatedStorage.Client, - } + for _, module in ReplicatedStorage.Client:QueryDescendants("ModuleScript") do + require(module) + end -- Wait for the server to start Roam if not workspace:GetAttribute("RoamStarted") then From 9c738a4a7a966a3913c8c5806b61aaac350ff1f7 Mon Sep 17 00:00:00 2001 From: Logan Hunt <2dloganh@gmail.com> Date: Mon, 19 Jan 2026 15:57:29 -0500 Subject: [PATCH 5/9] Improve Roam documentation and type annotations Expanded and clarified documentation in init.luau, including example service and startup usage, contracts, and lifecycle hook details. Added and refined type annotations for StartConfig and other internal properties. Minor spelling corrections in comments and warnings for better clarity. --- .../src/Bootstrappers/ClientBootstrapper.luau | 2 +- .../src/Bootstrappers/ServerBootstrapper.luau | 2 +- lib/roam/src/init.luau | 137 +++++++++++------- 3 files changed, 88 insertions(+), 53 deletions(-) diff --git a/lib/roam/src/Bootstrappers/ClientBootstrapper.luau b/lib/roam/src/Bootstrappers/ClientBootstrapper.luau index 836adb6..dd362cd 100644 --- a/lib/roam/src/Bootstrappers/ClientBootstrapper.luau +++ b/lib/roam/src/Bootstrappers/ClientBootstrapper.luau @@ -21,7 +21,7 @@ local function StartGame( StopOnFailedRequire: boolean?, -- Default: true } & Roam.StartConfig)? ) - if script.Name == "start" then -- We may want to remove this check later. It doesnt allow nice custom structures since its tailored to my opinion. + if script.Name == "start" then -- We may want to remove this check later. It doesn't allow nice custom structures since its tailored to my opinion. script:Destroy() return Promise.resolve(false) end diff --git a/lib/roam/src/Bootstrappers/ServerBootstrapper.luau b/lib/roam/src/Bootstrappers/ServerBootstrapper.luau index 9f365af..a172f0b 100644 --- a/lib/roam/src/Bootstrappers/ServerBootstrapper.luau +++ b/lib/roam/src/Bootstrappers/ServerBootstrapper.luau @@ -41,7 +41,7 @@ local function StartGame( StopOnFailedRequire: boolean?, -- Default: true } & Roam.StartConfig)? ) - if script.Name == "start" then -- We may want to remove this check later. It doesnt allow nice custom structures since its tailored to my opinion. + if script.Name == "start" then -- We may want to remove this check later. It doesn't allow nice custom structures since its tailored to my opinion. script:Destroy() return Promise.resolve(false) end diff --git a/lib/roam/src/init.luau b/lib/roam/src/init.luau index 481a641..289180a 100644 --- a/lib/roam/src/init.luau +++ b/lib/roam/src/init.luau @@ -9,37 +9,42 @@ initialize and start services in a topologically sorted manner without the need to manually order and start services. - Roam follows a design pattern similar to [Knit](https://sleitnick.github.io/Knit/), but is more lightweight. It removes all networking and replication - functionality, and instead focuses on providing a simple methodology to easily - initialize Services given to it. - - Roam gathers a collection of specified services and initializes 'synchronously'. - Once all services have been fully initialized, it then starts them 'asynchronously' by - spawning their 'RoamStart' method in a new thread. + Roam follows a design pattern similar to [Knit](https://sleitnick.github.io/Knit/), but is more lightweight. + It removes all networking and replication functionality, and instead focuses on providing a simple methodology + to easily initialize and start Services given to it. Roam is RunContext agnostic, meaning it can be used on both the server and client in the same manner. It makes no distinction between the two, and instead focuses on providing a simple interface for initializing and starting services. This means you could create a service and register it on both the server and client, and it will be initialized and started on both ends. - **[CONTRACTS]** - - Services must be created/registered before Roam is started. - - Services must be created/registered with a unique name. - - Services with `RoamInit` and `RoamStart` methods will have those methods - called when Roam is started at the appropriate time. (Names are configurable) - - `RequiredServices` boot in proper topological order if specified in the ServiceConfig. - - Roam functions the same regardless of RunContext (Server/Client). + **[EXAMPLE SERVICE]** + ```lua + -- MyService.lua + local MyService = {} + + function MyService:RoamInit() + print("MyService initialized!") + end + + function MyService:RoamStart() + print("MyService started!") + end + + -- Register the service table with Roam + local Roam = require(ReplicatedStorage.Roam) + Roam.registerService(MyService, "MyService") + + return MyService + ``` **[EXAMPLE STARTUP]** - ```lua -- ServerBootstrapper.Server.lua + ```lua + -- ServerBootstrapper.server.lua local Roam = require(ReplicatedStorage.Roam) - -- Just iterates through all the children of the given parents - -- and requires any module scripts that match the given predicate - Roam.requireModules({ - ReplicatedStorage.Shared; - ServerScriptService.Server; - }) + -- Require your services. (Tip: Roam.requireModules can help abstract this process!) + require(ReplicatedStorage.MyService) -- Start Roam Roam.start() @@ -47,6 +52,14 @@ :catch(warn) ``` + **[CONTRACTS]** + - Services must be created/registered before Roam is started. + - Services must be created/registered with a unique name. + - Services with `RoamInit` and `RoamStart` methods will have those methods + called when Roam is started at the appropriate time. (Names are configurable) + - `RequiredServices` boot in proper topological order if specified in the ServiceConfig. + - Roam functions the same regardless of RunContext (Server/Client). + :::info Setting up Services Services can be set up in a variety of ways. The most common way is to create a ModuleScript that returns a table with the methods you want to define, and then register it with Roam just prior @@ -152,6 +165,7 @@ export type ServiceConfig = { --[=[ @within Roam + @private @tag debug @type ServiceState "REGISTERED" | "AWAITING_DEPENDENCIES" | "PRE_INIT" | "ROAM_INIT" | "POST_INIT" | "INITIALIZED" | "PRE_START" | "ROAM_START" | "POST_START" | "STARTED" | "FAILED" @@ -183,6 +197,33 @@ export type ServiceState = type Promise = typeof(Promise.new()) +--[=[ + @within Roam + @interface StartConfig + .GlobalPreInit (() -> ())? -- Called once before ANY service initializes + .PreInit ((service: Service) -> ())? -- Called before each service's RoamInit + .PostInit ((service: Service) -> ())? -- Called after each service's RoamInit + .GlobalPostInit (() -> ())? -- Called once after ALL services finish initializing + .GlobalPreStart (() -> ())? -- Called once before ANY service starts. (Async) + .PreStart ((service: Service) -> ())? -- Called before each service's RoamStart (Async) + .PostStart ((service: Service) -> ())? -- Called after each service's RoamStart (Async) + .GlobalPostStart (() -> ())? -- Called once after ALL services start (Async) + + Yielding in `Init` lifecycle hooks will prevent Roam from progressing to the next step. + + `Start` lifecycle hooks are fully asynchronous and do not block progression at any point. +]=] +export type StartConfig = { + GlobalPreInit: (() -> Promise?)?, + PreInit: ((service: Service) -> Promise?)?, + PostInit: ((service: Service) -> Promise?)?, + GlobalPostInit: (() -> Promise?)?, + GlobalPreStart: (() -> ())?, + PreStart: ((service: Service) -> ())?, + PostStart: ((service: Service) -> ())?, + GlobalPostStart: (() -> ())?, +} + -------------------------------------------------------------------------------- --// Constants //-- -------------------------------------------------------------------------------- @@ -245,7 +286,7 @@ local function ensureUnyieldingRequire(module: ModuleScript) end) if coroutine.status(current) ~= "dead" then - -- This is not a great traceback. I wish it could find the original yield point, but I cant detect which modules are being required. + -- This is not a great traceback. I wish it could find the original yield point, but I can't detect which modules are being required. error( `Roam Require detected yield. Check the following module and the modules it requires: {module:GetFullName()}` ) @@ -480,6 +521,7 @@ end --[=[ @within Roam + @deprecated 0.1.6 @prop Services {[string]: Service} A table of Services. Only properly accessible after Roam has been started. ]=] @@ -489,11 +531,20 @@ Roam.ServiceNameMatch = serviceNameMatch --[=[ @within Roam + @tag debug + @private @prop Debug boolean Whether or not to print debug messages. Default is false. ]=] Roam.Debug = false -- Whether or not to print debug messages +--[=[ + @within Roam + @private + @prop DEFAULT_SRC_NAME string + The default name of the source folder where your modules are located. Default is "src". + This is only used by the generic Bootstrappers provided with Roam. +]=] Roam.DEFAULT_SRC_NAME = "src" --[=[ @@ -554,25 +605,13 @@ function Roam.registerService(service: Service, serviceConfig: (ServiceConfig | return service end -export type StartConfig = { - GlobalPreInit: (() -> Promise?)?, - PreInit: ((service: Service) -> Promise?)?, - PostInit: ((service: Service) -> Promise?)?, - GlobalPostInit: (() -> Promise?)?, - GlobalPreStart: (() -> ())?, - PreStart: ((service: Service) -> ())?, - PostStart: ((service: Service) -> ())?, - GlobalPostStart: (() -> ())?, -} - --[=[ @within Roam Starts Roam. Should only be called once. Calling multiple times will result in a promise rejection. - - Optional config argument provides lifecycle hooks in execution order: - Init lifecycle hooks can recieve a promise as a return value to delay progression until resolved. - + + Optional config argument provides lifecycle hooks. + ```lua Roam.start({ GlobalPreInit = function() @@ -596,18 +635,8 @@ export type StartConfig = { Be sure that all services have been created _before_ calling `Start`. Services cannot be added later. ::: - ]=] -function Roam.start(config: { - GlobalPreInit: (() -> Promise?)?, - PreInit: ((service: Service) -> Promise?)?, - PostInit: ((service: Service) -> Promise?)?, - GlobalPostInit: (() -> Promise?)?, - GlobalPreStart: (() -> ())?, - PreStart: ((service: Service) -> ())?, - PostStart: ((service: Service) -> ())?, - GlobalPostStart: (() -> ())?, -}?): Promise +function Roam.start(config: StartConfig?): Promise if started then return Promise.reject("Roam already started") end @@ -786,10 +815,10 @@ end @return Promise Returns a promise that is resolved once Roam has started. This is useful for any code that needs to tie into Roam services but is not the script - that called `Start`. + that called `start`. ```lua Roam.onStart():andThen(function() - local MyService = Roam.Services.MyService + local MyService = require(ReplicatedStorage.MyService) MyService:DoSomething() end):catch(warn) ``` @@ -919,6 +948,9 @@ function Roam.requireModules( } end +-------------------------------------------------------------------------------- +--// DEBUG //-- +-------------------------------------------------------------------------------- --[=[ @within Roam @private @@ -995,6 +1027,9 @@ function Roam.getServiceName(service: Service): string end Roam.getNameFromService = Roam.getServiceName -- backwards compat +-------------------------------------------------------------------------------- +--// DEPRECATED //-- +-------------------------------------------------------------------------------- --[=[ @deprecated 0.1.5 @private @@ -1038,7 +1073,7 @@ end Cannot be called until Roam has been started. ]=] function Roam.getService(serviceName: string): Service - warn("[Roam] getService is deprecated, use Roam.Services[serviceName] instead") + warn("[Roam] getService is deprecated. Prefer to use direct requires") if not started then warn(formatError("Early Access", "Services accessed before Roam started\n" .. debug.traceback())) From 232e1de56fa57b67c428ff30f0abefe9891f5ac2 Mon Sep 17 00:00:00 2001 From: Logan Hunt <2dloganh@gmail.com> Date: Tue, 20 Jan 2026 12:44:49 -0500 Subject: [PATCH 6/9] Improve printDependencyGraph with tree visualization Enhanced the Roam.printDependencyGraph function to display a full recursive dependency tree for each service using tree symbols. The output now shows circular references and sorts dependencies alphabetically for clarity. Updated documentation and code examples for better accuracy and consistency. --- lib/roam/src/init.luau | 109 +++++++++++++++++++++++++++++++++-------- 1 file changed, 89 insertions(+), 20 deletions(-) diff --git a/lib/roam/src/init.luau b/lib/roam/src/init.luau index 289180a..2a7ccaf 100644 --- a/lib/roam/src/init.luau +++ b/lib/roam/src/init.luau @@ -522,10 +522,11 @@ end --[=[ @within Roam @deprecated 0.1.6 + @private @prop Services {[string]: Service} A table of Services. Only properly accessible after Roam has been started. ]=] -Roam.Services = services -- A table of Services. Only properly accessible after Roam has been started. +Roam.Services = services Roam.ServiceNameMatch = serviceNameMatch @@ -552,8 +553,6 @@ Roam.DEFAULT_SRC_NAME = "src" @prop Bootstrappers {Server: (script: Script) -> Promise, Client: (script: Script) -> Promise} A table of generic bootstrappers for Roam that you can use to quickly setup new projects. ```lua - local Roam = require(Packages.Roam) - Roam.Bootstrappers.Server(script) :andThenCall(print, "Roam Server Bootstrapped!") ``` @@ -568,23 +567,20 @@ Roam.Bootstrappers = { -- Generic Bootstrappers for Roam / Orion Registers a Service/Table with Roam to be Initialized and Started when Roam starts. Cannot be called after Roam has been started. - ```lua -- MyRegisteredService.lua - local MyRegisteredService = {} + ```lua -- MyService.lua + local MyService = {} - function MyRegisteredService:RoamStart() - print("MyRegisteredService started!") + function MyService:RoamInit() + print("MyService initialized!") end - function MyRegisteredService:RoamInit() - print("MyRegisteredService initialized!") + function MyService:RoamStart() + print("MyService started!") end ---------------------------------------------------------------- - local Roam = require(Packages.Roam) - Roam.registerService(MyRegisteredService, "MyRegisteredService") - - return MyRegisteredService + Roam.registerService(MyService, "MyService") ``` ]=] function Roam.registerService(service: Service, serviceConfig: (ServiceConfig | string)?): Service @@ -956,21 +952,94 @@ end @private @tag debug Prints the dependency graph of all registered services to the output. + Shows the full recursive dependency tree for each service with tree symbols. ]=] function Roam.printDependencyGraph(): () + local function printDependencyTree( + service: Service, + prefix: string, + isLast: boolean, + visited: { [Service]: boolean } + ) + local config = service[KEY_CONFIG] + local serviceName = config.Name + + -- Choose the appropriate tree symbol + local connector = isLast and "└─ " or "ā”œā”€ " + + -- Check for circular dependencies + if visited[service] then + print(`{prefix}{connector}{serviceName} (circular reference)`) + return + end + + visited[service] = true + print(`{prefix}{connector}{serviceName}`) + + if config.RequiredServices then + local deps = config.RequiredServices + -- Sort dependencies alphabetically for consistent display + local sortedDeps = {} + for _, dep in ipairs(deps) do + table.insert(sortedDeps, dep) + end + table.sort(sortedDeps, function(a, b) + return a[KEY_CONFIG].Name < b[KEY_CONFIG].Name + end) + + -- Extend the prefix for nested dependencies + local childPrefix = prefix .. (isLast and " " or "│ ") + + for i, dep in ipairs(sortedDeps) do + local isLastDep = (i == #sortedDeps) + printDependencyTree(dep, childPrefix, isLastDep, visited) + end + end + + visited[service] = nil -- Allow same service in different branches + end + print("Service Dependency Graph:") - for serviceName, service in pairs(services) do + print( + "═══════════════════════════════════════" + ) + + -- Get all services and sort them alphabetically + local sortedServiceNames = {} + for serviceName in pairs(services) do + table.insert(sortedServiceNames, serviceName) + end + table.sort(sortedServiceNames) + + -- Print each service and its dependencies + for i, serviceName in ipairs(sortedServiceNames) do + local service = services[serviceName] local config = service[KEY_CONFIG] - print(` {serviceName}:`) + + print(`\n{serviceName}`) if config.RequiredServices then - for _, dep in ipairs(config.RequiredServices) do - local depName = dep[KEY_CONFIG].Name - print(` -> {depName}`) + local deps = config.RequiredServices + -- Sort dependencies alphabetically + local sortedDeps = {} + for _, dep in ipairs(deps) do + table.insert(sortedDeps, dep) end - else - print(" (no dependencies)") + table.sort(sortedDeps, function(a, b) + return a[KEY_CONFIG].Name < b[KEY_CONFIG].Name + end) + + for j, dep in ipairs(sortedDeps) do + local isLastDep = (j == #sortedDeps) + printDependencyTree(dep, "", isLastDep, {}) + end + -- else + -- print("└─ (no dependencies)") end end + + print( + "\n═══════════════════════════════════════" + ) end --[=[ From 92082dfb4546c1c1ee23230b371ea0b3f6bd689e Mon Sep 17 00:00:00 2001 From: Logan Hunt <2dloganh@gmail.com> Date: Tue, 20 Jan 2026 13:27:23 -0500 Subject: [PATCH 7/9] Improve type safety and fix minor issues in Roam Added explicit type annotations and type assertions throughout the code to improve type safety. Fixed a typo in documentation, updated service state from 'ACTIVE' to 'STARTED', and enhanced checks for coroutine and Promise handling. Also clarified comments and variable naming for better readability. --- lib/roam/src/init.luau | 60 ++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/lib/roam/src/init.luau b/lib/roam/src/init.luau index 2a7ccaf..c13c52f 100644 --- a/lib/roam/src/init.luau +++ b/lib/roam/src/init.luau @@ -70,7 +70,7 @@ :::tip Networking Roam does not inherently have networking functionality. However, it can easily be added through the use of NetWire's - **[.setupServiceNetworking](https://raild3x.github.io/ModulesOnRails/api/ServerNetWire/#setupServiceNetworking)** funtion. + **[.setupServiceNetworking](https://raild3x.github.io/ModulesOnRails/api/ServerNetWire/#setupServiceNetworking)** function. ::: ---- @@ -179,7 +179,7 @@ export type ServiceConfig = { - `PRE_START` - Calling PreStart with service - `ROAM_START` - Calling Service:RoamStart method - `POST_START` - Calling PostStart with service - - `ACTIVE` - Service is actively running and has completed its startup routine + - `STARTED` - Service is actively running and has completed its startup routine - `FAILED` - Service initialization failed ]=] export type ServiceState = @@ -276,16 +276,17 @@ local FAILED_REQUIRE_YIELD = Symbol("FailedRequireYield") local function ensureUnyieldingRequire(module: ModuleScript) local moduleContent = FAILED_REQUIRE_YIELD task.spawn(function() - local current + local current: thread? = nil task.spawn(function() current = coroutine.running() local success, msg = pcall(function() moduleContent = require(module) :: any + return moduleContent end) assert(success, `Failed to load module: {module.Name}\n{msg}`) end) - if coroutine.status(current) ~= "dead" then + if current and coroutine.status(current) ~= "dead" then -- This is not a great traceback. I wish it could find the original yield point, but I can't detect which modules are being required. error( `Roam Require detected yield. Check the following module and the modules it requires: {module:GetFullName()}` @@ -329,7 +330,7 @@ local function validateServiceConfig(serviceConfig: any, serviceName: string?): end if serviceConfig.RequiredServices then - for i, requiredService in ipairs(serviceConfig.RequiredServices) do + for i, requiredService in ipairs(serviceConfig.RequiredServices :: { Service }) do if type(requiredService) ~= "table" then error( formatError( @@ -338,7 +339,7 @@ local function validateServiceConfig(serviceConfig: any, serviceName: string?): ) ) end - if not serviceExists(requiredService) then + if not serviceExists(requiredService :: Service) then warn( formatError( "Unregistered Required Service", @@ -349,11 +350,11 @@ local function validateServiceConfig(serviceConfig: any, serviceName: string?): end end - -- remove duplicates from RequiredServices + -- Detect and remove duplicates from RequiredServices if serviceConfig.RequiredServices then local seen = {} local uniqueRequiredServices = {} - for i, reqService in ipairs(serviceConfig.RequiredServices) do + for i, reqService in ipairs(serviceConfig.RequiredServices :: { Service }) do if not seen[reqService] then seen[reqService] = true table.insert(uniqueRequiredServices, reqService) @@ -661,8 +662,8 @@ function Roam.start(config: StartConfig?): Promise else local result = hook(service) -- If the hook returns a Promise, await it - if result and typeof(result) == "table" and result.await then - result:await() + if result and typeof(result) == "table" and result.await and type(result.await) == "function" then + (result :: any):await() end end end @@ -706,7 +707,7 @@ function Roam.start(config: StartConfig?): Promise local dependencyPromises = {} if serviceConfig.RequiredServices then - for _, requiredService in ipairs(serviceConfig.RequiredServices) do + for _, requiredService in ipairs(serviceConfig.RequiredServices :: { Service }) do local depPromise = serviceCompletionPromises[requiredService] if depPromise then table.insert(dependencyPromises, depPromise) @@ -722,7 +723,7 @@ function Roam.start(config: StartConfig?): Promise end serviceStates[service] = "AWAITING_DEPENDENCIES" - local errMsg = "\n - " .. serviceConfig.Name + local errMsg: string = "\n - " .. serviceConfig.Name local servicePromise = Promise.all(dependencyPromises):andThen(function() -- Dependencies are ready @@ -876,14 +877,15 @@ function Roam.requireModules( parents = { parents } end - config = config or {} - if typeof(config) ~= "table" then - error(formatError("Invalid Config", `Config must be a table, got {typeof(config)}`)) - end + config = config or {} :: any + assert(typeof(config) == "table", formatError("Invalid Config", `Config must be a table, got {typeof(config)}`)) + + local deepSearch: boolean = config.DeepSearch or false + local requirePredicate: ((obj: ModuleScript) -> boolean)? = config.RequirePredicate + local ignoreDescendantsPredicate: ((obj: Instance) -> boolean)? = config.IgnoreDescendantsPredicate + local allowYieldingRequires: boolean = config.AllowYieldingRequires + local stopOnFailedRequire: boolean = config.StopOnFailedRequire - local deepSearch = config.DeepSearch or false - local requirePredicate = config.RequirePredicate - local ignoreDescendantsPredicate = config.IgnoreDescendantsPredicate local successfullyRequiredModuleContent = {} local failedModuleRequires = {} @@ -891,7 +893,7 @@ function Roam.requireModules( if typeof(obj) == "table" then for _, child in ipairs(obj) do local success = searchInstance(child) - if not success and config.StopOnFailedRequire then + if not success and stopOnFailedRequire then return false end end @@ -903,7 +905,7 @@ function Roam.requireModules( end if obj:IsA("ModuleScript") and (not requirePredicate or requirePredicate(obj)) then - if config.AllowYieldingRequires then + if allowYieldingRequires then local success, moduleContent = pcall(function() return require(obj) :: any end) @@ -979,12 +981,12 @@ function Roam.printDependencyGraph(): () if config.RequiredServices then local deps = config.RequiredServices -- Sort dependencies alphabetically for consistent display - local sortedDeps = {} + local sortedDeps: { Service } = {} for _, dep in ipairs(deps) do - table.insert(sortedDeps, dep) + table.insert(sortedDeps, dep :: Service) end - table.sort(sortedDeps, function(a, b) - return a[KEY_CONFIG].Name < b[KEY_CONFIG].Name + table.sort(sortedDeps, function(a: Service, b: Service) + return (a[KEY_CONFIG] :: ServiceConfig).Name < (b[KEY_CONFIG] :: ServiceConfig).Name end) -- Extend the prefix for nested dependencies @@ -1020,12 +1022,12 @@ function Roam.printDependencyGraph(): () if config.RequiredServices then local deps = config.RequiredServices -- Sort dependencies alphabetically - local sortedDeps = {} + local sortedDeps: { Service } = {} for _, dep in ipairs(deps) do - table.insert(sortedDeps, dep) + table.insert(sortedDeps, dep :: Service) end - table.sort(sortedDeps, function(a, b) - return a[KEY_CONFIG].Name < b[KEY_CONFIG].Name + table.sort(sortedDeps, function(a: Service, b: Service) + return (a[KEY_CONFIG] :: ServiceConfig).Name < (b[KEY_CONFIG] :: ServiceConfig).Name end) for j, dep in ipairs(sortedDeps) do From 58786eb1889642f00e25ee78fc9f1675862d3b8d Mon Sep 17 00:00:00 2001 From: Logan Hunt <2dloganh@gmail.com> Date: Tue, 20 Jan 2026 14:14:26 -0500 Subject: [PATCH 8/9] Move Roam type definitions to separate types.luau file Extracted Service, ServiceConfig, ServiceState, and StartConfig type definitions from init.luau into a new types.luau module. Updated ClientBootstrapper.luau, ServerBootstrapper.luau, and init.luau to import and use the new types module, improving code organization and maintainability. --- .../src/Bootstrappers/ClientBootstrapper.luau | 5 +- .../src/Bootstrappers/ServerBootstrapper.luau | 5 +- lib/roam/src/init.luau | 114 ++--------------- lib/roam/src/types.luau | 117 ++++++++++++++++++ 4 files changed, 131 insertions(+), 110 deletions(-) create mode 100644 lib/roam/src/types.luau diff --git a/lib/roam/src/Bootstrappers/ClientBootstrapper.luau b/lib/roam/src/Bootstrappers/ClientBootstrapper.luau index dd362cd..5b9f937 100644 --- a/lib/roam/src/Bootstrappers/ClientBootstrapper.luau +++ b/lib/roam/src/Bootstrappers/ClientBootstrapper.luau @@ -4,8 +4,8 @@ local ReplicatedStorage = game:GetService("ReplicatedStorage") local BootstrapperModule = script -local Roam = require(BootstrapperModule.Parent.Parent) local Promise = require(BootstrapperModule.Parent.Parent.Parent.Promise) +local types = require(BootstrapperModule.Parent.Parent.types) local function checkConfig(config: any, field: string, default: any?) if config and config[field] ~= nil then @@ -19,8 +19,9 @@ local function StartGame( config: ({ AllowYieldingRequires: boolean?, -- Default: false StopOnFailedRequire: boolean?, -- Default: true - } & Roam.StartConfig)? + } & types.StartConfig)? ) + local Roam = require(BootstrapperModule.Parent.Parent) if script.Name == "start" then -- We may want to remove this check later. It doesn't allow nice custom structures since its tailored to my opinion. script:Destroy() return Promise.resolve(false) diff --git a/lib/roam/src/Bootstrappers/ServerBootstrapper.luau b/lib/roam/src/Bootstrappers/ServerBootstrapper.luau index a172f0b..394dd28 100644 --- a/lib/roam/src/Bootstrappers/ServerBootstrapper.luau +++ b/lib/roam/src/Bootstrappers/ServerBootstrapper.luau @@ -8,7 +8,7 @@ local ReplicatedStorage = game:GetService("ReplicatedStorage") local ServerScriptService = game:GetService("ServerScriptService") local BootstrapperModule = script -local Roam = require(BootstrapperModule.Parent.Parent) +local types = require(BootstrapperModule.Parent.Parent.types) local Promise = require(BootstrapperModule.Parent.Parent.Parent.Promise) local function ShutdownServer(err) @@ -39,8 +39,9 @@ local function StartGame( config: ({ AllowYieldingRequires: boolean?, -- Default: false StopOnFailedRequire: boolean?, -- Default: true - } & Roam.StartConfig)? + } & types.StartConfig)? ) + local Roam = require(BootstrapperModule.Parent.Parent) if script.Name == "start" then -- We may want to remove this check later. It doesn't allow nice custom structures since its tailored to my opinion. script:Destroy() return Promise.resolve(false) diff --git a/lib/roam/src/init.luau b/lib/roam/src/init.luau index c13c52f..e7e8749 100644 --- a/lib/roam/src/init.luau +++ b/lib/roam/src/init.luau @@ -110,6 +110,7 @@ local RunService = game:GetService("RunService") local Packages = script.Parent local Promise = require(Packages.Promise) local Symbol = require(Packages.Symbol) +local Types = require(script.types) local Roam = {} @@ -117,112 +118,13 @@ local Roam = {} --// Types //-- -------------------------------------------------------------------------------- -type table = { [any]: any } -export type Service = table - ---[=[ - @within Roam - @interface ServiceConfig - @field Name string -- Name of the Service. Must be unique. Used when accessing via .getService - @field RequiredServices {Service}? -- The Services that this Service depends on. Roam will ensure that these Services are initialized before this Service. - @field StartMethodName string? -- Overrides default StartMethodName of "RoamStart" - @field InitMethodName string? -- Overrides default InitMethodName of "RoamInit" - - ```lua - local myOtherService = require(ReplicatedStorage.MyOtherService) - - ------------------------------------------------- - - local MyService = {} - - function MyService:CustomStartMethod() - print("MyService started!") - end - - ------------------------------------------------- - - Roam.registerService(MyService, { - Name = "MyService", - RequiredServices = {myOtherService}, - StartMethodName = "CustomStartMethod", - }) - - return MyService - ``` - - :::caution Deferring RequiredServices - Do NOT add services to the RequiredServices after you have created or registered the service. This will cause undefined behavior. - ::: -]=] -export type ServiceConfig = { - Name: string, -- Name of the Service. Must be unique. Used when accessing via .getService - RequiredServices: { Service }?, -- The Services that this Service depends on. Roam will ensure that these Services are initialized before this Service. - StartMethodName: string?, -- Overrides default StartMethodName of "RoamStart" - InitMethodName: string?, -- Overrides default InitMethodName of "RoamInit" - InitTimeout: number?, -- Overrides default init timeout in seconds (default: 120) - [any]: any, -} - ---[=[ - @within Roam - @private - @tag debug - @type ServiceState "REGISTERED" | "AWAITING_DEPENDENCIES" | "PRE_INIT" | "ROAM_INIT" | "POST_INIT" | "INITIALIZED" | "PRE_START" | "ROAM_START" | "POST_START" | "STARTED" | "FAILED" - - Represents the current lifecycle state of a service: - - `REGISTERED` - Service has been registered but not yet initialized - - `AWAITING_DEPENDENCIES` - Service is waiting for its RequiredServices to finish initializing - - `PRE_INIT` - Calling PreInit with service - - `ROAM_INIT` - Calling Service:RoamInit method - - `POST_INIT` - Calling PostInit with service - - `INITIALIZED` - Service has completed all initialization steps - - `PRE_START` - Calling PreStart with service - - `ROAM_START` - Calling Service:RoamStart method - - `POST_START` - Calling PostStart with service - - `STARTED` - Service is actively running and has completed its startup routine - - `FAILED` - Service initialization failed -]=] -export type ServiceState = - "REGISTERED" - | "AWAITING_DEPENDENCIES" - | "PRE_INIT" - | "ROAM_INIT" - | "POST_INIT" - | "INITIALIZED" - | "PRE_START" - | "ROAM_START" - | "POST_START" - | "STARTED" - | "FAILED" +export type Service = Types.Service +export type ServiceConfig = Types.ServiceConfig +export type ServiceState = Types.ServiceState +export type StartConfig = Types.StartConfig type Promise = typeof(Promise.new()) - ---[=[ - @within Roam - @interface StartConfig - .GlobalPreInit (() -> ())? -- Called once before ANY service initializes - .PreInit ((service: Service) -> ())? -- Called before each service's RoamInit - .PostInit ((service: Service) -> ())? -- Called after each service's RoamInit - .GlobalPostInit (() -> ())? -- Called once after ALL services finish initializing - .GlobalPreStart (() -> ())? -- Called once before ANY service starts. (Async) - .PreStart ((service: Service) -> ())? -- Called before each service's RoamStart (Async) - .PostStart ((service: Service) -> ())? -- Called after each service's RoamStart (Async) - .GlobalPostStart (() -> ())? -- Called once after ALL services start (Async) - - Yielding in `Init` lifecycle hooks will prevent Roam from progressing to the next step. - - `Start` lifecycle hooks are fully asynchronous and do not block progression at any point. -]=] -export type StartConfig = { - GlobalPreInit: (() -> Promise?)?, - PreInit: ((service: Service) -> Promise?)?, - PostInit: ((service: Service) -> Promise?)?, - GlobalPostInit: (() -> Promise?)?, - GlobalPreStart: (() -> ())?, - PreStart: ((service: Service) -> ())?, - PostStart: ((service: Service) -> ())?, - GlobalPostStart: (() -> ())?, -} +type table = { [any]: any } -------------------------------------------------------------------------------- --// Constants //-- @@ -883,8 +785,8 @@ function Roam.requireModules( local deepSearch: boolean = config.DeepSearch or false local requirePredicate: ((obj: ModuleScript) -> boolean)? = config.RequirePredicate local ignoreDescendantsPredicate: ((obj: Instance) -> boolean)? = config.IgnoreDescendantsPredicate - local allowYieldingRequires: boolean = config.AllowYieldingRequires - local stopOnFailedRequire: boolean = config.StopOnFailedRequire + local allowYieldingRequires: boolean? = config.AllowYieldingRequires + local stopOnFailedRequire: boolean? = config.StopOnFailedRequire local successfullyRequiredModuleContent = {} local failedModuleRequires = {} diff --git a/lib/roam/src/types.luau b/lib/roam/src/types.luau new file mode 100644 index 0000000..20bff66 --- /dev/null +++ b/lib/roam/src/types.luau @@ -0,0 +1,117 @@ +--!strict +-- Logan Hunt (Raildex) +-- January 20, 2026 +-- Type definitions for Roam + +type table = { [any]: any } + +--[=[ + @within Roam + @type Service table + A service is a table that can be registered with Roam. +]=] +export type Service = table + +--[=[ + @within Roam + @interface ServiceConfig + @field Name string -- Name of the Service. Must be unique. Used when accessing via .getService + @field RequiredServices {Service}? -- The Services that this Service depends on. Roam will ensure that these Services are initialized before this Service. + @field StartMethodName string? -- Overrides default StartMethodName of "RoamStart" + @field InitMethodName string? -- Overrides default InitMethodName of "RoamInit" + + ```lua + local myOtherService = require(ReplicatedStorage.MyOtherService) + + ------------------------------------------------- + + local MyService = {} + + function MyService:CustomStartMethod() + print("MyService started!") + end + + ------------------------------------------------- + + Roam.registerService(MyService, { + Name = "MyService", + RequiredServices = {myOtherService}, + StartMethodName = "CustomStartMethod", + }) + + return MyService + ``` + + :::caution Deferring RequiredServices + Do NOT add services to the RequiredServices after you have created or registered the service. This will cause undefined behavior. + ::: +]=] +export type ServiceConfig = { + Name: string, -- Name of the Service. Must be unique. Used when accessing via .getService + RequiredServices: { Service }?, -- The Services that this Service depends on. Roam will ensure that these Services are initialized before this Service. + StartMethodName: string?, -- Overrides default StartMethodName of "RoamStart" + InitMethodName: string?, -- Overrides default InitMethodName of "RoamInit" + InitTimeout: number?, -- Overrides default init timeout in seconds (default: 120) + [any]: any, +} + +--[=[ + @within Roam + @private + @tag debug + @type ServiceState "REGISTERED" | "AWAITING_DEPENDENCIES" | "PRE_INIT" | "ROAM_INIT" | "POST_INIT" | "INITIALIZED" | "PRE_START" | "ROAM_START" | "POST_START" | "STARTED" | "FAILED" + + Represents the current lifecycle state of a service: + - `REGISTERED` - Service has been registered but not yet initialized + - `AWAITING_DEPENDENCIES` - Service is waiting for its RequiredServices to finish initializing + - `PRE_INIT` - Calling PreInit with service + - `ROAM_INIT` - Calling Service:RoamInit method + - `POST_INIT` - Calling PostInit with service + - `INITIALIZED` - Service has completed all initialization steps + - `PRE_START` - Calling PreStart with service + - `ROAM_START` - Calling Service:RoamStart method + - `POST_START` - Calling PostStart with service + - `STARTED` - Service is actively running and has completed its startup routine + - `FAILED` - Service initialization failed +]=] +export type ServiceState = + "REGISTERED" + | "AWAITING_DEPENDENCIES" + | "PRE_INIT" + | "ROAM_INIT" + | "POST_INIT" + | "INITIALIZED" + | "PRE_START" + | "ROAM_START" + | "POST_START" + | "STARTED" + | "FAILED" + +--[=[ + @within Roam + @interface StartConfig + .GlobalPreInit (() -> ())? -- Called once before ANY service initializes + .PreInit ((service: Service) -> ())? -- Called before each service's RoamInit + .PostInit ((service: Service) -> ())? -- Called after each service's RoamInit + .GlobalPostInit (() -> ())? -- Called once after ALL services finish initializing + .GlobalPreStart (() -> ())? -- Called once before ANY service starts. (Async) + .PreStart ((service: Service) -> ())? -- Called before each service's RoamStart (Async) + .PostStart ((service: Service) -> ())? -- Called after each service's RoamStart (Async) + .GlobalPostStart (() -> ())? -- Called once after ALL services start (Async) + + Yielding in `Init` lifecycle hooks will prevent Roam from progressing to the next step. + + `Start` lifecycle hooks are fully asynchronous and do not block progression at any point. +]=] +export type StartConfig = { + GlobalPreInit: (() -> any)?, + PreInit: ((service: Service) -> any)?, + PostInit: ((service: Service) -> any)?, + GlobalPostInit: (() -> any)?, + GlobalPreStart: (() -> ())?, + PreStart: ((service: Service) -> ())?, + PostStart: ((service: Service) -> ())?, + GlobalPostStart: (() -> ())?, +} + +return {} From e425715e0bd98a1907b0c545f8aae254f917894c Mon Sep 17 00:00:00 2001 From: Logan Hunt <2dloganh@gmail.com> Date: Tue, 20 Jan 2026 14:16:14 -0500 Subject: [PATCH 9/9] Update Roam package version in README Bumped the documented version of the Roam package from 0.1.6 to 0.2.0 in the README to reflect the latest release. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 20e471e..33fa142 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ ModulesOnRails is a collection of Wally packages to streamline Roblox developmen | [PromValue](https://raild3x.github.io/ModulesOnRails/api/PromValue) | `PromValue = "raild3x/promvalue@0.1.0"` | An object class that allows for delayed setting | | [Queue](https://raild3x.github.io/ModulesOnRails/api/Queue) | `Queue = "raild3x/queue@1.0.0"` | A generic queue implementation in luau. | | [RemoteComponent](https://raild3x.github.io/ModulesOnRails/api/RemoteComponent) | `RemoteComponent = "raild3x/remotecomponent@0.1.3"` | A component extension to provide easy networking functionality. | -| [Roam](https://raild3x.github.io/ModulesOnRails/api/Roam) | `Roam = "raild3x/roam@0.1.6"` | Roam is a service initialization framework for Roblox. | +| [Roam](https://raild3x.github.io/ModulesOnRails/api/Roam) | `Roam = "raild3x/roam@0.2.0"` | Roam is a service initialization framework for Roblox. | | [TableManager](https://raild3x.github.io/ModulesOnRails/api/TableManager) | `TableManager = "raild3x/tablemanager@0.2.2"` | A class for managing and observing data in a table. Includes some additional classes for extending functionality. | | [TableReplicator](https://raild3x.github.io/ModulesOnRails/api/ServerTableReplicator) | `TableReplicator = "raild3x/tablereplicator@0.2.7"` | A set of classes for replicating tables and their changes between server and client with minimal effort. |