Compress huge classes to make them extremely easy to manage!

Context

When you’re building games, your code base grows and some class grow correspondingly. The class below may represent a class that has grown a significant amount.

--[[Services]]
--MyService1
--MyService2
--MyService3
--MyService4

--[[Modules]]
--MyModule1
--MyModule2
--MyModule3
--MyModule4
--MyModule5

--[[Assets/Folders/Misc]]
--MyThing1
--MyThing2
--MyThing3
--MyThing4
--MyThing5
--MyThing6

--[[Helpers]]
local function MyLocalHelper()
end

local function MyLocalHelper2()
end

local function MyLocalHelper3()
end

local module = {}
module.__index = module

function module.New()
	local self = setmetatable({}, module)
	return self
end

function module:MyMethod()
	--Super long code
end

function module:MyMethod2()
	--Super long code
end

function module:MyMethod3()
	--Super long code
end

function module:MyMethod4()
	--Super long code
end

--[[Helpers]]
function module:MyHelper()
end

function module:MyHelper2()
end

function module:MyHelper3()
end

So overwhelming!

Why is this code bad?

  • Code can reach hundreds to thousands of lines long, making expansion harder
  • Unneeded variables and functions that were used in deleted or changed methods can accumulate and tracking them down is hard with so much code
  • Locating a desired method can also be hard because of so much code

What’s the solution?

Compartmentalize each method!

Instead of storing all the methods where you create the class, split them up into individual modules

Inside each module would look like this:

--Services

--Modules

--Misc

local function MyLocalHelper()
end

local function MyLocalHelper2()
end

local module = {}

function module:Fragment() --MAKE SURE TO USE ":" INSTEAD OF "."
	print(self.apples)
end

return module

This is so much easier read!

This allows us read our code without needing to see irrelevant variables and functions that are used by other methods. We can now focus only on this method without any conflicts with other methods.

Now to add all the function to the main module we can do this:

do
	local fragments = script.Fragments

	for i, fragment: ModuleScript in fragments:GetChildren() do
		local name = fragment.Name
		module[name] = require(fragment).Fragment
	end
end

The End!

Thank you so much for reading. I hope this post can help you tackle scalability and code management!

1 Like

I would recommend to add in task.spawn each time it loops because so modules may need to wait for some things to load, are adding a extra wait time for the modules getting loaded after that.

1 Like

Oh this is actually pretty neat, never thought of seperating functions into their own ModuleScripts, but that’s something to keep in mind for sure.