Core ConceptsAdvanced

Three-Service Dependency Chain

DataService, InventoryService, and ShopService a real dependency graph and the OwlInit order it guarantees.

DependenciesOwlInitTopological Sort
ServerScriptService/Services/DataService.lua
local DataService = Owl.CreateService({
    Name = "DataService",
    Dependencies = {},
})
 
function DataService:OwlInit()
    print("[DataService] Ready.")
end
 
function DataService:OwlStart()
end
 
return DataService
ServerScriptService/Services/InventoryService.lua
local InventoryService = Owl.CreateService({
    Name = "InventoryService",
    Dependencies = { "DataService" },
})
 
function InventoryService:OwlInit()
    self.DataService = self.GetService("DataService")
    print("[InventoryService] Ready, DataService was already initialized.")
end
 
function InventoryService:OwlStart()
end
 
return InventoryService
ServerScriptService/Services/ShopService.lua
local ShopService = Owl.CreateService({
    Name = "ShopService",
    Dependencies = { "DataService", "InventoryService" },
})
 
function ShopService:OwlInit()
    self.DataService = self.GetService("DataService")
    self.InventoryService = self.GetService("InventoryService")
    print("[ShopService] Ready, both dependencies were already initialized.")
end
 
function ShopService:OwlStart()
end
 
return ShopService
What's happening here
  • Owl computes a topological sort from these three Dependencies tables the OwlInit order is always DataService, then InventoryService, then ShopService.
  • Even though ShopService lists two dependencies, Owl only guarantees THIS Service's own dependencies finished first not a global order across every unrelated Service.
  • Removing "DataService" from ShopService.Dependencies while still calling self.GetService("DataService") in OwlInit would keep working most of the time until a load-order change makes it fail intermittently, exactly the bug class this graph exists to prevent.