How to connect multiple services without creating direct dependencies between them?
18:09 04 Jun 2026

(Translated by translator)
I use Roblox Studio for development.

In short, I'm having trouble connecting multiple services. For example, when an event is triggered in Service #1, I need Service #2 to respond to it, but I can’t make Service #2 dependent on Service #1 because that doesn’t look clean. I created setup modules, but that’s only a temporary solution—I don’t want to keep creating setup modules just to make everything work together. What should I do?

Of course, I came up with a solution involving setup modules that link several services and some simple logic, but judging by their names, I already feel like I’m doing something wrong. When I ask the AI, I get some strange suggestions for solving this problem, but they still don’t seem like the best options to me

.
EXAMPLE

I initialize the modules on the client like this
Example from my game:

if not game:IsLoaded() then
    game.Loaded:Wait()
end

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local LinkHandler = require(ReplicatedStorage.Shared.Modules.LinkHandler)
local safeRequire = require(ReplicatedStorage.Shared.Modules.Utils.safeRequire)
local PlayerLinkServiceClient = require(ReplicatedStorage.Shared.Services.PlayerLinkService.PlayerLinkServiceClient)
local MountUI = require(ReplicatedStorage.UI.MountUI)

local DataService = require(ReplicatedStorage.Packages.DataService).client
DataService:init()

PlayerLinkServiceClient:SetLinkHandler(LinkHandler)

local function bootstrapServices()
    local bootstrapedServices = {}
    for _, serviceModule: ModuleScript in ReplicatedStorage.Shared.Services:GetDescendants() do
        if not serviceModule:IsA("ModuleScript") then
            continue
        end
        local service, requireResult = safeRequire(serviceModule)
        if not service then
            warn(`[{script.Name}] Could not bootstrap service "{serviceModule}": {requireResult}`)
            continue
        end
        if type(service) ~= "table" or type(service.Init) ~= "function" then
            --warn(`[{script.Name}] Service "{serviceModule}" does not have an init function.`)
            continue
        end
        local success, initResult = pcall(service.Init, service)
        if not success then
            warn(`[{script.Name}] Failed to initialize service "{serviceModule}": {initResult}`)
            continue
        end
        table.insert(bootstrapedServices, serviceModule.Name)
    end
    return bootstrapedServices
end

local services = bootstrapServices()
print(`[{script.Name}] Successfully bootstrapped services: {table.concat(services, ", ")}`)

local function bootstrapSetupModules()
    local bootstrapedModules = {}
    local setupModules = ReplicatedStorage.Shared.Modules.Setup:GetDescendants()
    table.sort(setupModules, function(left: Instance, right: Instance)
        return left:GetFullName() < right:GetFullName()
    end)

    for _, setupModule in setupModules do
        if not setupModule:IsA("ModuleScript") then
            continue
        end

        local setup, requireResult = safeRequire(setupModule)
        if not setup then
            warn(`[{script.Name}] Could not bootstrap setup module "{setupModule:GetFullName()}": {requireResult}`)
            continue
        end

        if type(setup) ~= "function" then
            warn(`[{script.Name}] Setup module "{setupModule:GetFullName()}" is not a function`)
            continue
        end

        local success, initResult = pcall(setup)
        if not success then
            warn(`[{script.Name}] Failed to initialize setup module "{setupModule:GetFullName()}": {initResult}`)
            continue
        end

        table.insert(bootstrapedModules, setupModule:GetFullName())
    end

    return bootstrapedModules
end

local setupModules = bootstrapSetupModules()
print(`[{script.Name}] Successfully bootstrapped setup modules: {table.concat(setupModules, ", ")}`)

MountUI()
print(`[{script.Name}] Successfully mounted UI`)

task.wait(5)

local PlayerReadyServiceClient = require(ReplicatedStorage.Shared.Services.PlayerReadyService.PlayerReadyServiceClient)
PlayerReadyServiceClient:Ready()

print(`[{script.Name}] Player is ready now for PlayerReadyService`)
lua roblox luau roblox-studio