Is it possible to optimize my scripts?

Sorry if this is in the wrong topic.

  1. Basically, I want to optimize my scripts as much as I can.

  2. I don’t see a way to optimize my scripts any further.

    Images of Locations, and more
    Locations

    image


    Scripts
    Script in "FinalPart"
    local this_buttonGotHit = false
    local CompRoom = false
    local RoomFolder = script.Parent.Parent -- Choose where the current room folder should be.
    
    local door = RoomFolder.Door -- Choose
    
    local registeredPart = false
    if registeredPart == false then
     registeredPart = true
     wait(0.1)
     RoomFolder:SetAttribute("RequiredButtons",RoomFolder:GetAttribute("RequiredButtons") + 1)
    end
    
    
    local function TweenDoor()
     local duration = 1
     local style = 2
     local direction = 1
     local ts = game:GetService("TweenService")
     local tween1 = TweenInfo.new(duration,style,direction)
    
     local properties1 = {
     	Position = Vector3.new(door.Position.X,10,door.Position.Z),
     	Size = Vector3.new(11,0.05,1.75)
     }
    
    
    
     local create1 = ts:Create(door,tween1,properties1)
     
     create1:Play()
    end
    
    local function CheckToTween()
     if RoomFolder:GetAttribute("ButtonsHit") >= RoomFolder:GetAttribute("RequiredButtons") and 
    CompRoom == false then
     	CompRoom = true
     	wait(0.1)
     	TweenDoor()
     end
    end
    
    
    script.Parent.Touched:Connect(function(hit)
     if game.Players:GetPlayerFromCharacter(hit.Parent) then
     	if this_buttonGotHit == false then
     		if RoomFolder:GetAttribute("ButtonsHit") == 
    RoomFolder:GetAttribute("RequiredButtons") - 1 then
     		this_buttonGotHit = true
     		wait(0.1)
     		script.Sound:Play()
     		script.Parent.BrickColor = BrickColor.Red()
     		if RoomFolder:GetAttribute("ButtonsHit") < 
    RoomFolder:GetAttribute("RequiredButtons") then
     			RoomFolder:SetAttribute("ButtonsHit",RoomFolder:GetAttribute("ButtonsHit") + 1)
     				CheckToTween()
     			end	
     		end	
     	end
     end
    end)
    

    Script in every "Part"
    local this_buttonGotHit = false
    local CompRoom = false
    local RoomFolder = script.Parent.Parent -- Choose where the current room folder should be.
    
    local door = RoomFolder.Door -- Choose
    
    local registeredPart = false
    if registeredPart == false then
     registeredPart = true
     wait(0.1)
     RoomFolder:SetAttribute("RequiredButtons",RoomFolder:GetAttribute("RequiredButtons") + 1)
    end
    
    
    local function TweenDoor()
     local duration = 1
     local style = 2
     local direction = 1
     local ts = game:GetService("TweenService")
     local tween1 = TweenInfo.new(duration,style,direction)
    
     local properties1 = {
     	Position = Vector3.new(door.Position.X,10,door.Position.Z),
     	Size = Vector3.new(11,0.05,1.75)
     }
    
    
    
     local create1 = ts:Create(door,tween1,properties1)
     
     create1:Play()
    end
    
    
    script.Parent.Touched:Connect(function(hit)
     if game.Players:GetPlayerFromCharacter(hit.Parent) then
     	if RoomFolder:GetAttribute("ButtonsHit") >= RoomFolder:GetAttribute("RequiredButtons") 
    and CompRoom == false then
     		CompRoom = true
     		wait(0.1)
     		TweenDoor()
     	end
     	if this_buttonGotHit == false then
     		this_buttonGotHit = true
     		wait(0.1)
     		script.Sound:Play()
     		script.Parent.BrickColor = BrickColor.Red()
     		if RoomFolder:GetAttribute("ButtonsHit") < 
    RoomFolder:GetAttribute("RequiredButtons") then
     			RoomFolder:SetAttribute("ButtonsHit",RoomFolder:GetAttribute("ButtonsHit") + 1)
     		end	
     	end
     end
    end)
    

    Script in "Room1"
    local RoomFolder = script.Parent
    local FinalButton = RoomFolder.FinalPart
    
    RoomFolder:GetAttributeChangedSignal("ButtonsHit"):Connect(function()
     if RoomFolder:GetAttribute("ButtonsHit") == RoomFolder:GetAttribute("RequiredButtons") - 1 then
     	FinalButton.Color = Color3.fromRGB(0,255,0)
     end
    end)
    

    Model if your confused:
    https://www.roblox.com/library/6475992743/

    Thank you for putting the time into reading this and helping out!

3 Likes

Optimize isn’t necessarily a word I’d use in relation to “performance” in this case; but I would say you can optimize your scalability - your long-term potential for this game/model/etc.

If you have multiple scripts with the exact same source, then you should centralize this. Consider you have an obby with 1,032 lava bricks each with scripts in every one of them.

  • You have overhead of the startup time each script will take. At 1,000 this will be a bit laggy
  • You have 0 scalability - if you want to make changes you have to do it to 1,000+ scripts.

Additionally, when your scripts are all over the place, your code is hard to keep up with.

Roblox Studio is great because you get a lot of freedom - but freedom can cause bad habits. You should consider centralizing all your code in singular locations to make it manageable and future-proof.

image
image

Above is an example of how I organize my Stronghold Castle SIM game.

2 Likes

Hello,

If you want to optimize any working scripts you have, I would recommend checking out code review.

To add onto MrNicNac’s post, one way of improving the scalability of this can come with usage of the CollectionService, which essentially allows you to create one script for use in every Part, preventing duplicate scripts from needing to be placed in every single Part that requires it.

Additionally, this makes it easier to change one script and have the changes applied to each instance that is “tagged” (more info about CollectionService can be found from the following guide on the Developer Forum).


Based off of the code outlined in your post under the “Script in every ‘Part’” section, here’s an example of how it could be restructured. Take note that there are still improvements that could be made to what I provide below – this is moreover a proof of concept toward making it modular and more streamlined. I’ve included brief explanations of the changes I’ve made as well.

Example of CollectionService and Modular Implementation.rbxl (25.6 KB) – Place file that contains the scripts along with example buttons & doors. To create “Room2”, I simply duplicated “Room1” and added more parts inside to demonstrate that the code would still function without needing to alter the script.

Server Script

local CollectionService = game:GetService("CollectionService")

local roomFunctions = require(script.roomFunctionsModule)



local function forTaggedParts(part) -- This function will be activated for each of the buttons
	
	local RoomFolder = part.Parent -- References the Folder in relation to each part
	local Door = RoomFolder:FindFirstChild("Door") -- Looks for the door inside of that folder

	part.Touched:Connect(function(hit) -- Whenever the part is touched...

		local partCheck = roomFunctions.partTouched(part,hit) -- The "partTouched" function will be activated in the ModuleScript, sending through both the part that was touched and the object that touched it

		if partCheck then -- If a value of "true" was returned fron the ModuleScript, then...
			
			RoomFolder:SetAttribute("ButtonsActivated", RoomFolder:GetAttribute("ButtonsActivated") + 1) -- The ButtonsActivated attribute will be updated
			print(RoomFolder.Name.." has "..RoomFolder:GetAttribute("ButtonsActivated").." completed buttons!") -- This will print in the Output to show how many buttons have been activated

			local roomCheck = roomFunctions.roomCompletionCheck(RoomFolder) -- This will be used to check if the room has been completed

			if roomCheck and Door then -- If the function returns true and the Door exists in this room, then...

				warn(RoomFolder.Name.." has been completed") -- Warns that the room has been completed

				roomFunctions.tweenDoor(Door) -- This will tween the door so it opens
			end
		end
	end)
end






for _,item in ipairs(workspace.RoomFolders:GetChildren()) do -- Loops through a folder in the Workspace called "RoomFolders", which contain the folders for each room
	
	if item:IsA("Folder") then -- This will ensure that only folders are checked through
		
		local folderContents = item:GetChildren()
		
		if folderContents then
			
			local numberOfButtons = 0 -- This variable will change depending on how many buttons are inside of the room
			
			for _,folderObject in ipairs(folderContents) do -- Loops through the folder
				
				if folderObject:IsA("Part") and folderObject.Name ~= "Door" then -- If the object inside of the folder is a "Part", and its name isn't "Door", we can continue. This can be altered depending on how you'd like to distinguish buttons from other Instances within the room
					CollectionService:AddTag(folderObject,"NameOfTag") -- This adds the button to the list of items in the CollectionService that are tagged with "NameOfTag"
					
					numberOfButtons += 1 -- Increases the numberOfButtons variable
				end
			end
			
			-- After the loop has concluded...
			
			item:SetAttribute("RequiredButtons", numberOfButtons) -- The "RequiredButtons" attribute will be updated to the number stored in the numberOfButtons variable
			item:SetAttribute("ButtonsActivated", 0)
			
		end
	end
	
end




for _, part in pairs(CollectionService:GetTagged("NameOfTag")) do -- For each of the parts with the tag name "NameOfTag"...
	forTaggedParts(part) -- The function called "forTaggedParts" will be activated, sending the part through
end


ModuleScript

(Placed inside of Server Script)

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

local roomFunctions = {} -- This table will store all of the functions below


function roomFunctions.partTouched(part, hit)

	local playerCheck = Players:GetPlayerFromCharacter(hit.Parent)

	if playerCheck and part.BrickColor ~= BrickColor.new("Really red") then -- If a player touched the part and the button has not been activated before, then...

		part.BrickColor = BrickColor.new("Really red") -- It'll update the color of the part and then...
		--part.Sound:Play()

		return true -- Returns true so that partHandler script knows to update the "ButtonsActivated" attribute

	else
		return false -- If the part has already been touched or if it was touched by something that was not a player's Character, then false will be returned so nothing is updated
	end
end


function roomFunctions.tweenDoor(Door)
-- This function has remained relatively untouched from the code provided in your post, aside from defining the TweenService at the top of the script
	local duration = 1
	local style = 2
	local direction = 1

	local tween1 = TweenInfo.new(duration,style,direction)

	local properties1 = {

		Position = Vector3.new(Door.Position.X,10,Door.Position.Z),
		Size = Vector3.new(11,0.05,1.75)

	}

	local create1 = TweenService:Create(Door,tween1,properties1)

	create1:Play()
end


function roomFunctions.roomCompletionCheck(RoomFolder)
	
	-- The following two variables will check for the value of the attributes
	local ButtonsActivatedAttribute = RoomFolder:GetAttribute("ButtonsActivated")
	local RequiredButtonsAttribute = RoomFolder:GetAttribute("RequiredButtons")

	if -- If both attributes exist and if the amount of ButtonsActivated exceeds or reaches the required amount, them...
		ButtonsActivatedAttribute
		and RequiredButtonsAttribute
		and ButtonsActivatedAttribute >= RequiredButtonsAttribute

	then
		return true -- "True" will be returned so the partHandler script knows the door can be opened
	end
end

return roomFunctions