Organising your messy code

Feb 01, 2026 3 min read

Look, we've all been there. You open up a script you write two weeks ago and it's just chaos. Variables everywhere, functions doing ten different things, and you have no idea what past-you was thinking. I'm here to fix that. This guide is everything I have learnt over the years, including some tips and tricks I've been gatekeeping.

Structure: Where does everything go?

First things first, you need a good structure where your scripts actually live. Don't just throw everything in ServerScriptService and call it a day.

Here's what works pretty well:

  • ServerScriptService: For server-side scripts, organized into folders like "PlayerData", "Combat", and "Systems".
  • ReplicatedStorage: For modules, assets, and events that both sides need to access.
  • StarterPlayer: For client-side logic, grouped by functionality (UI, Camera, etc).

The key is consistency. Once you pick a structure you like, stick with it. Your future self will thank you.

Styling: Make your code simple and easy to read

This isn't about making your code pretty for fun (though that's a nice bonus). It's about being able to actually understand what you wrote.

Name things properly. None of this "x", "temp" or "thing2" bullshit. If it's a variable holding player health, call it PlayerHealth or currentHealth. Functions should be verbs like UpdateHealth or CheckInventory.

Use local variables. Seriously, almost everything should be local unless you specifically need it to be global. It's faster and prevents weird bugs where scripts mess with each other's variables.

Comments are good, but don't overdo it. Comment the WHY, and not the WHAT. If someone reading your code can't tell that "player.Health = 0" sets health to zero, they've got bigger problems.

Spacing matters. Group related stuff together. It's like paragraphs in writing; it makes everything easier to follow.

Here's a quick example:

-- Bad
local function f(p,d)
local h=p.Character:FindFirstChild("Humanoid")
if h then h.Health=h.Health-d end
end

-- Good
local function DamagePlayer(player, damageAmount)
    local character = player.Character
    if not character then return end
    
    local humanoid = character:FindFirstChild("Humanoid")
    if humanoid then
        humanoid.Health = humanoid.Health - damageAmount
    end
end

Services: Get them once, use them everywhere

At the top of your script, grab all the services you need right away. Don't scatter GetService calls throughout your code.

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")

And for the love of all that is holy, use GetService. Don't do game.Players or game.Workspace. It's slower and can break in weird edge cases.

ModuleScripts: Your new best friend

If you're not using ModuleScripts, you're making life harder than it needs to be. They're perfect for code you want to reuse across multiple scripts.

local MathUtils = {}

function MathUtils.Round(number, decimalPlaces)
    local mult = 10^(decimalPlaces or 0)
    return math.floor(number * mult + 0.5) / mult
end

return MathUtils

Handling Events properly

When you're connecting to events, clean up after yourself. Especially in LocalScripts that deal with the player's character, because characters respawn and you don't want a million connections piling up.

local connections = {}

local function setupCharacter(character)
    -- Clean up old connections
    for _, connection in connections do
        connection:Disconnect()
    end
    connections = {}
    
    local humanoid = character:WaitForChild("Humanoid")
    
    connections[1] = humanoid.Died:Connect(function()
        print("Player died!")
    end)
end

Final Tips

  • Use CollectionService for tagging objects.
  • Learn to use BindableEvents for script-to-script communication.
  • Consider a framework like Knit if your game is getting complex.

And honestly, most important thing? Just be consistent. Your code doesn't have to be perfect; it just has to make sense to you (and anyone else working on your game).

Happy coding, and may your bugs be few and your frame rate be high.