This is the problem I always have with games, once there starts to become too much code it becomes hard to navigate it and add stuff or make changes. How do you organize your code so that it doesnt get out of hand when the game gets too big?
Use either multiple scripts, but limit the amount, or use one to two scripts but label them appropriately.
I like to try to keep it to like 10 server scripts and any amount of required client scripts.
Just name them appropriately, and for long control scripts that run multiple things use comments to label which part of the script you’re at.
I also suggest using a key to indicate a header section and a key to indicate a subsection of script functions.
This is what I usually do to keep it from feeling overwhelming.
i recommend using module scripts in this case
having seen several projects over the last few years, I think the way the code is organized looks a lot like a book.
Each folder can represent a specific component, module, or functionality, much like a chapter in a book addresses a particular topic. Within these folders, subfolders can further break down the information, similar to subchapters in a book.
This hierarchical organization helps developers quickly locate parts of the code, facilitates maintenance, team collaboration, and a comprehensive understanding of the project, much like how a book’s structure aids readers in navigating and better understanding its content.
I like making a folder called modules then under it folders containing the modules and the type of work they do.
For example:
Modules.CameraControlModules.GetDataModule
i like to put Module Under that Script which is going to require it
The one i was talking about was for server scripts but sometimes i might put under script only if that module is used by one script if not i create a folder in a place thats easy to access
you can try to space it our like this
--- get service
local service game...
local service game...
local service game...
local service game...
--- get object variables
local part game.Workspace...
local part game.Workspace...
local part game.Workspace...
local part game.Workspace...
--- get variables
local var = ...
local var = ...
local var = ...
local var = ...
--- functions
local function...
end)
local function...
end)
local function...
end)
--- other codes
idk just some code that not fit into the categorize
--- main script
something:Connect(fucntion()
...
end)
normally I’ll space the variables out into groups like obj variables will stay in the same group and player variables stay in the same group
and here a tips, always space it out for each function like this like of script will get the variables and the next line will minus it so I’ll space it out too
and the lasy tip, if you want to do something like while true do to check a variables, its better to use runservice for that, it will reduce lag, because while loop still run even there’s nothing satified but the runservice only run when the if function is satified
Personally I prefer many smaller scripts over just a few very big ones.
In my opinion scripts shouldn’t have more than 200 or so lines each. If it gets that big, you can use modules to separate the code. Code separation is usually a good practice as it means your pieces of code can work separately (low coupling).
Then organize the scripts in folders. For example a folder for MapScripts, one for PlayerScripts and one for NPC scripts. Then you can use as much subfolders as you see necessary. Find your own style.
i know that you may already have gived up on this post, but i’ll revive it anyways, if you don’t want module scripts, then do this (also sorry for the bump):
do
--code here
end
This could be good, and you could also add a comment on top like this, so it is even more easier to read:
--//title or section idk
do
--code here
end
here’s what i managed to come up with:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TweenService = game:GetService("TweenService")
local Events = ReplicatedStorage:WaitForChild("Events")
local LevelCompleteEvent = Events:WaitForChild("LevelCompleteEvent")
local CanAccessLevelFunction = Events:WaitForChild("CanAccessLevelFunction")
local ObstacleRushButton = script.Parent.ObstacleRush
local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local LoadUI = Player.PlayerGui:WaitForChild("LoadUI")
local MissionsUI = Player.PlayerGui:WaitForChild("MissionsUI")
local DB = false
local CanTalk = ReplicatedStorage:WaitForChild("CanTalk")
local ObstacleRushMap = ReplicatedStorage:WaitForChild("Models").ObstacleRush
local Map = workspace.Map
local SpawnPart = ObstacleRushMap:WaitForChild("SpawnPart")
local levelId = "ObstacleRush"
function OpenLoadScreen()
LoadUI.Background.Visible = true
LoadUI.Background.Position = UDim2.fromScale(0.5, -0.5)
TweenService:Create(
LoadUI.Background,
TweenInfo.new(1, Enum.EasingStyle.Bounce, Enum.EasingDirection.Out),
{Position = UDim2.fromScale(0.5, 0.5)}
):Play()
end
function CloseLoadScreen()
TweenService:Create(
LoadUI.Background,
TweenInfo.new(0.5, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut),
{Position = UDim2.fromScale(0.5, -0.5)}
):Play()
task.delay(0.5, function()
LoadUI.Background.Visible = false
end)
end
--//OBSTACLE RUSH
do
ObstacleRushButton.MouseButton1Up:Connect(function()
if Character and DB == false then
-- Verificar com o servidor se o jogador pode acessar o nível
DB = true
ObstacleRushMap.Parent = workspace
MissionsUI.Background.Visible = false
Character.HumanoidRootPart.Anchored = false
OpenLoadScreen()
task.wait(3)
CloseLoadScreen()
Map.Parent = ReplicatedStorage
DB = false
Character:MoveTo(SpawnPart.Position)
-- Detectar quando o jogador termina o nível
ObstacleRushMap.EndPad.Touched:Once(function(Hit)
local Player = game.Players:GetPlayerFromCharacter(Hit.Parent)
if Player then
local canAccess = CanAccessLevelFunction:InvokeServer(levelId)
if not canAccess then
print("Você já completou este nível e não pode mais ganhar novamente.")
else
LevelCompleteEvent:FireServer(levelId)
end
Player.Character.HumanoidRootPart.Anchored = false
OpenLoadScreen()
task.wait(2.5)
CloseLoadScreen()
ObstacleRushMap.Parent = ReplicatedStorage
Map.Parent = workspace
Character:MoveTo(Map.SpawnLocation.Position)
CanTalk.Value = true
Map.NPCS.Missionkeeper.HumanoidRootPart.PromptAttachment.ProximityPrompt.Enabled = true
end
end)
end
end)
end
--//BOX DELIVER
do
local BoxDeliverButton = script.Parent.BoxDeliver
BoxDeliverButton.MouseButton1Up:Connect(function()
if Character and DB == false then
-- Verificar com o servidor se o jogador pode acessar o nível
DB = true
MissionsUI.Background.Visible = false
Character.HumanoidRootPart.Anchored = false
OpenLoadScreen()
task.wait(3)
CloseLoadScreen()
DB = false
Character:MoveTo(Map.BoxDeliver.SpawnPart.Position)
end
end)
end
as you can see, you can just close the lines you want