How could I improve/simplify this plugin script?

Hey all, so i have this neat plugin i made, which allows you to place blocks that will randomly change their size between a minimum and a maximum value on each axis, each time you click! You can also customize the values. In my opinion, i think i did a great job with the code. Also this is my first plugin ever, so please be nice! :sweat_smile:

The plugin

Asset link:
https://www.roblox.com//library/4765607937/asset

Local Plugin download:
Random Sized Block Placer.rbxmx (51.0 KB)

Some feedback will be very much appreciated!

plugin = plugin -- All this does it remove that annoying blue line you see 24/7
local ChangeHistoryService = game:GetService("ChangeHistoryService")

local Opened = false
local cam = game.Workspace.CurrentCamera
local mouse = plugin:GetMouse()

local toolbar = plugin:CreateToolbar("Random Sized Block Placer")
local Button = toolbar:CreateButton("Random Sized Block Placer", "Create a randomly sized block with a 'minimum' and 'maximum' value on each axis (X, Y, Z)", "rbxassetid://4765601210")

-- GUI
local GuiContent = script.Parent:WaitForChild("GuiContent")
local MainFrame = GuiContent:WaitForChild("MainFrame")
local HelpUi = GuiContent:WaitForChild("HelpText")

-- Interface
Interface = plugin:CreateDockWidgetPluginGui(
	"Random Sized Block Placer interface",
	DockWidgetPluginGuiInfo.new(
		Enum.InitialDockState.Float,  -- Widget will be initialized in floating panel
		false,   -- Widget will be initially enabled
		true,  -- Don't override the previous enabled state
		310,    -- Default width of the floating window
		200,    -- Default height of the floating window
		310,    -- Minimum width of the floating window (optional)
		200     -- Minimum height of the floating window (optional)
	)
)
Interface.Title = "Random Sized Block Placer"
MainFrame.Parent = Interface
HelpUi.Parent = Interface

-- GUI buttons
-- X
local MinX = MainFrame:WaitForChild("MinX")
local MaxX = MainFrame:WaitForChild("MaxX")
-- Y
local MinY = MainFrame:WaitForChild("MinY")
local MaxY = MainFrame:WaitForChild("MaxY")
-- Z
local MinZ = MainFrame:WaitForChild("MinZ")
local MaxZ = MainFrame:WaitForChild("MaxZ")


-- Functions

Interface.Changed:Connect(function()
	if Interface.Enabled == true then
		Opened = true
	else
		Opened = false
	end
end)

function ToggleGui()
	if not Opened then
		plugin:Activate(true)
		Opened = true
		Interface.Enabled = true
	else
		plugin:Activate(false)
		Opened = false
		Interface.Enabled = false
	end
end

Button.Click:Connect(function()
	ToggleGui()
end)

function ChangeToNumber(TextBox)
	if tonumber(TextBox.Text) or TextBox.Text == "" or TextBox.Text == nil then
    	-- Text is fine
    else
        TextBox.Text = 0.05
    end
end

mouse.Button1Down:Connect(function()
	if Opened then
		local Part = Instance.new("Part", workspace)
		Part.Position = mouse.hit.p
		Part.Size = tonumber(Vector3.new(math.random(MinX.Text, MaxX.Text), math.random(MinY.Text, MaxY.Text), math.random(MinZ.Text, MaxZ.Text)))
		print("Created Part | Size: (" .. tostring(Part.Size)..")")
		ChangeHistoryService:SetWaypoint("Randomly sized part placed")
	end
end)

-- Check if all axis settings are numbers

-- X
MinX:GetPropertyChangedSignal("Text"):Connect(function()
	ChangeToNumber(MinX)
end)
MaxX:GetPropertyChangedSignal("Text"):Connect(function()
	ChangeToNumber(MaxX)
end)

-- Y
MinY:GetPropertyChangedSignal("Text"):Connect(function()
	ChangeToNumber(MinY)
end)
MaxY:GetPropertyChangedSignal("Text"):Connect(function()
	ChangeToNumber(MaxY)
end)

-- Z
MinZ:GetPropertyChangedSignal("Text"):Connect(function()
	ChangeToNumber(MinZ)
end)
MaxZ:GetPropertyChangedSignal("Text"):Connect(function()
	ChangeToNumber(MaxZ)
end)

print("Successfully loaded Ethanthegrand14's 'Random Sized Part Placer' plugin!")

Empty if-blocks look a bit odd in my opinion.

	if tonumber(TextBox.Text) or TextBox.Text == "" or TextBox.Text == nil then
    	-- Text is fine
    else
        TextBox.Text = 0.05
    end

You can just negate the condition and remove the else

if blahblah then
    -- do nothing
else
  doSomething()
end

is the same as

if not blahblah then
   doSomething()
end

I notice you’re repeating a lot of code near the bottom, in regards to checking the Text property changing. You should be able to pack these all instances into a table and loop over them to add the event listener.

local Axes = {MinX, MaxX, MinY, MaxY, MinZ, MaxZ}

for _, axis in pairs(Axes) do
    axis:GetPropertyChangedSignal("Text"):Connect(function()
        ChangeToNumber(axis)
    end)
end

Should do the same thing as the code you provided.
For your ToggleGui function, there’s a neat trick you can do to tidy things
Instead of using explicitly true or false, you can use the value of Opened since it’s a boolean as well and that’s the only condition you’re checking.

function ToggleGui()
    plugin:Activate(not Opened)
    Interface.Enabled = not Opened
    Opened = not Opened -- change the toggle variable last
end

The rest of it looks very good at a glance, unfortunately I can’t spend more time looking over it right now, those are just what stuck out to me. I’ve also never delved into plugin development myself, so there may be some things to change that I don’t know about.
Congratulations on your first plugin, it seems like a really cool idea! :smiley:

3 Likes

Thanks for the heads up! i’ll try and use these techniques more often!

1 Like