How can I better structure/organize my scripts

Hey,

I’ve been working on a deployment system which uses parts with surfaceUis inorder to portray a 3d “hologram”.

Along with this, I also have other scripts which interact seperately on their own Ui elements. This doesn’t seem very organized or modular when it comes to where I’m putting my interface logic. It’s all seperated in different areas.

For example, I have my Interactables Client script, which manages it’s own interface portion.
image

(screenshot because this doesn’t need to be copied)

image

My idea with starting this whole game framework setup was that I would have a module on the client solely for managing the interface, however this requires a ton of extra work that I just don’t have the time for, along with the fact that I literally have no clue what an interface framework would need.

Managing my scripts isn’t a problem when it comes to handling the interface, it’s just I’m afraid that this issue will grow out of hand.

On this note, my deployment script feels like it’s spread too thin. What I mean by this is that it seems like the scope of it’s job is too large for a single script, but I don’t really feel like rewriting it and I haven’t got a clue myself of how I would subdivide it.

local MessagingService = game:GetService("MessagingService")
local TeleportService = game:GetService("TeleportService")
local PlayerService = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")

-- // player stuff

local Player = PlayerService.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()

local Humanoid = Character:FindFirstChildWhichIsA("Humanoid")

-- // remotes

local Remotes = ReplicatedStorage.Shared.Remotes

local TeleportEvent = Remotes.TeleportEvent
local SaveDataEvent = Remotes.SaveColonyData

-- // modules

local Modules = ReplicatedStorage.Shared.Modules

local Tween = require(Modules.Tween)

-- // console stuff

local Ship = workspace.Ship

local Console = Ship.Console
local Interactable = Console:WaitForChild("Screen").Interactable

-- // tweeninfo

local HoloInfo = TweenInfo.new(0.5, Enum.EasingStyle.Quad)

-- // config

local Ui = {
	["Left"] = Console.UI.Left,
	["Deployment"] = Console.UI.Deployment,
	["Description"] = Console.UI.Description,
}

local Holograms = {
	["Left"] = Console.Holograms.Left,
	["Deployment"] = Console.Holograms.Deployment,
	["Description"] = Console.Holograms.Description,
	["Circle"] = Console.Holograms.Circle,
}

local BasePositions = {
	["Left"] = Holograms.Left.Position,
	["Deployment"] = Holograms.Deployment.Position,
	["Description"] = Holograms.Description.Position,
	["Circle"] = Holograms.Circle.Position,
}

-- // sounds

local Click = Console.Screen.ClickSound

-- // bools

local Open = false

-- // values

local TargetPosition: Vector3 = Vector3.new()
local GlobeOriginCFrame: CFrame = workspace.Ship.GlobeOrigin.CFrame

local GlobeInputs = {
	X = 0,
	Y = 0,
}

-- // util

local function GetTargetRelative()
	return GlobeOriginCFrame:VectorToObjectSpace(TargetPosition)
end

local function GetSeed()
	local Seed = 1234567890
	
	print(GetTargetRelative())
	
	return Seed
end

local function MoveHolos(Up: boolean)
	task.spawn(function()
		for HoloScreen, GivenPosition in (BasePositions) do
			HoloScreen = Console.Holograms[HoloScreen]
			
			local TweenPosition = GivenPosition
			
			if not Up then
				TweenPosition *= Vector3.new(1,-1,1)
			end
			
			Tween(HoloScreen, HoloInfo, {Position = TweenPosition})
			
			task.wait()
		end
	end)
end

local function ClickSFX()
	Click:Play()
	-- stuff
end

local function TeleportPlayer()
	TeleportEvent:FireServer()
end

-- // init

local module = {}

-- // function

local function OpenUi()
	Open = true
	
	MoveHolos(true)
	Console.Screen.HoloBeam:Play()
	
	Character.PrimaryPart.Anchored = true
	Humanoid.WalkSpeed = 0
end

local function CloseUi()
	Open = false
	
	MoveHolos(false)
	Console.Screen.HoloClose:Play()
	
	Character.PrimaryPart.Anchored = false
	Humanoid.WalkSpeed = Humanoid:GetAttribute("DefaultWalkSpeed")
end

local function GoToSaves()
	ClickSFX()
	
	Ui.Left.Browser.Visible = false
	Ui.Left.Saves.Visible = true
	
	task.wait(0.1)
end

local function ReturnToBrowser()
	ClickSFX()
	
	Ui.Left.Browser.Visible = true
	Ui.Left.Saves.Visible = false
	Ui.Left.Password.Visible = false
	
	task.wait(0.1)
end

local function CreateColony()
	Ui.Deployment.CreateButton.Visible = false
	Ui.Deployment.NameBox.Visible = true
	
	Ui.Deployment.NameBox.FocusLost:Connect(function()
		local ColonyName = Ui.Deployment.NameBox.Text
		
		local ColonyData = {
			["Models"] = {},
			["Seed"] = GetSeed(),
		}
	end)
end

local function InputBegan(Input: InputObject, IsTyping: boolean)
	if not IsTyping and Open then
		if Input.KeyCode == Enum.KeyCode.W then
			GlobeInputs.X = 1
		elseif Input.KeyCode == Enum.KeyCode.S then
			GlobeInputs.X = -1
		elseif Input.KeyCode == Enum.KeyCode.A then
			GlobeInputs.Y = 1
		elseif Input.KeyCode == Enum.KeyCode.D then
			GlobeInputs.Y = -1
		end
	end
end

local function InputEnded(Input: InputObject)
	if Input.KeyCode == Enum.KeyCode.W or Input.KeyCode == Enum.KeyCode.S then
		GlobeInputs.X = 0.000001
	elseif Input.KeyCode == Enum.KeyCode.A or Input.KeyCode == Enum.KeyCode.D then
		GlobeInputs.Y = 0.000001
	end
end

local function Update(DeltaTime: number)
	local X = GlobeInputs.X * 6
	local Y = GlobeInputs.Y * -6
	
	local InputY = CFrame.fromAxisAngle(Vector3.xAxis, math.rad(Y))
	
	local CF = Ship.Globe.PrimaryPart.CFrame * CFrame.Angles(0, math.rad(X), 0)
	
	Ship.Globe:SetPrimaryPartCFrame(CF * InputY)
	
end

-- // connections

Interactable:GetAttributeChangedSignal("Active"):Connect(function()
	if Interactable:GetAttribute("Active") then
		if not Open then
			OpenUi()
		else
			CloseUi()
		end
	end
end)

Ui.Left.Browser.Scroll.SavesButton.MouseButton1Down:Connect(GoToSaves)
Ui.Left.Saves.Scroll.BackButton.MouseButton1Down:Connect(ReturnToBrowser)

Ui.Deployment.CreateButton.MouseButton1Down:Connect(CreateColony)

UserInputService.InputBegan:Connect(InputBegan)
UserInputService.InputEnded:Connect(InputEnded)

RunService.Heartbeat:Connect(Update)

-- // on start

CloseUi()

-- // return

return module

image

Any help is appreciated, thanks.

1 Like

There is really no right way. Whatever works for you. But in terms of organization i would recommend keeping constants like these:

In a seperate module and functions related to that in the module too. Also instead of being very specific with variables like:

local sound1 = SoundFolder.Sound1
local sound2 = SoundFolder.Sound2

Instead of doing that you could just put the variable into one variable and grab the sounds later down the line.

Example

local Folder = workspace.SoundFolder

--later

print(Folder.Sound1)
1 Like