Game Initializer | A dependency-based Module Initialization System

Introduction

Hello all! I’ve decided to share my Initializer module - a lightweight and robust initialization system for your Roblox game.
This utility manages module dependencies and initialization of modules based on passed tables, working on both client and server sides.

The Problem

When developing games on Roblox, especially if you are using ModuleScripts and a Service type architecture where modules are supposed to run on runtime, managing the initialization order of modules become very tedious and challenging.

  • Some modules depend on others being initialized first. What if DataService depends on PlayerService being initialized?
  • Circular dependencies can cause VERY tedious errors
  • Proper cleanup of modules during game teardown is quite overlooked

Solution: Initializer Module!

Initializer creates a clean and fluent API for module initialization.
Here are some of the key features:

  • Dependency Management: You can define which modules depend on others!
  • Priority-Based Initialization: Assign priorities to module references to control initialization sequence!
  • Init Queue Handling: Modules with unmet dependencies are queued and processed once dependencies are met!
  • Error Handling: Robust error handling during require() and init() processes with logging!
  • Cleanup Support: Automatic cleanup of modules that have a .cleanup() function on the server during game closure!
  • Script Context: Works pretty much identically on both client and server, with a bit different log messages!

Module Requirements

For a module to work with the Initializer, it should ideally:

  • First of all, return a table of course
  • Have a .init() function that gets called during… you guessed it, initialization!
  • Optionally have a .cleanup() function that gets called manually or on the server automatically when :BindToClose is fired

Code Example

Here’s how to use the Initializer in your game:

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local Initializer = require(ReplicatedStorage.SharedModules.Classes.Initializer) -- Wherever your path is

-- Module refs
-- IMPORTANT: Make sure the modules aren't the returned value of require()
local ModuleA = ReplicatedStorage.ModuleA
local ModuleB = ReplicatedStorage.ModuleB
local ModuleC = ReplicatedStorage.ModuleC

-- here you can define dependencies
local dependencies = {
    [ModuleB] = {ModuleA},
    [ModuleC] = [ModuleA, ModuleB}
}

-- here you can define modules to actually initialize
local modules = {
    [ModuleA] = 1, -- Lowest priority value, initializes first
    [ModuleB] = 2,
    [ModuleC] = 3 -- Highest priority value, initializes last
}

-- Create and start initializer
local initializer = Initializer.new(dependencies, modules)
initializer:Initialize()
-- BOOM whole game initialized!

Module Structure:

Module structure needs to look like this:

local Module = {}

-- Initialize function
function Module.init()

end

-- You can have any functions here!

-- Optionally at the end...
function Module.cleanup()

end

Conclusion

Well, that’s it! Nothing too special, but no less important because of that!
I hope this system finds you well, GL!

→ Below you can find the ‘Initializer’ class module! ←

Download

→ You can get it here: Initializer

3 Likes

This is a nice module, I could see this being used in top games on roblox!

1 Like