How to Make a Plugin

This will guide you through the steps of coding a plugin.

by CeaselessQuokka

Author Avatar

Introduction: What is a Plugin?

Think of a plugin like a Chrome Extension; they add functionality to Google Chrome that isn't native, or already supported. Plugins do the exact same thing in Roblox Studio: they add extra functionality. For example, Building Tools by F3X is a very popular plugin with over 300,000 takes at the time of writing.

What You Need to know

You will need a basic understanding of Lua syntax and some experience with Roblox Studio and coding within the Roblox environment. If you do not have any experience then you may find this tutorial hard to follow. Anyway, that's enough babbling let's get into it!

Getting Down and Dirty

To start off, you will need to insert a Script into the Explorer. This script will house the main code needed to actually create a plugin. You can name the script anything you want; it will not affect the plugin whatsoever. We first create the toolbar via the CreateToolbar method. The toolbar is what contains all the buttons of the plugin. It is shown under the Plugins tab in Roblox Studio.

-- Create the Toolbar
local Toolbar = plugin:CreateToolbar("My First Plugin!")
-- "plugin" is a Roblox keyword that is directly linked to their plugin API
-- "My First Plugin!" will be the name displayed under the buttons. Name it whatever you want, go wild (but not too wild)

Congratulations! You have completed the first step in creating your own plugin, now we have to actually make the button to activate the plugin. We do this with the CreateButton method (note: the CreateButton method is a method of a the toolbar, not the plugin).

-- Create the Toolbar
local Toolbar = plugin:CreateToolbar("My First Plugin!")

-- Create the Button
local PrintButton = Toolbar:CreateButton(
    "Print",
    "This will spam your output with randomly generated numbers.",
    "rbxassetid://156552337",
    "Print"
)

-- The first argument is the name of the button,
-- in this case we named the button, "Print",
-- the second argument we passed to the method is the description
-- of the button. The description will show after hovering over the
-- button for a  certain period of time, the third argument is the
-- icon for the button, and the last argument is the name that is
-- displayed under the icon if the icon is present; otherwise,
-- the name of the button is displayed.

You may be wondering, why are we making a plugin that just spams the output? Are we monsters? No, we are not. You know why? Because we are going to create a second button that stops the spam of your output. See, not monsters. But you may also be wondering, "Isn't this just a useless plugin?" Why yes, yes it is.

Speaking of that second button, let's make it!

-- Create the Toolbar
local Toolbar = plugin:CreateToolbar("My First Plugin!")

-- Create the Buttons
local PrintButton = Toolbar:CreateButton(
    "Print",
    "This will spam your output with randomly generated numbers.",
    "rbxassetid://156552337",
    "Print"
)

local StopButton = Toolbar:CreateButton(
    "Stop",
    "This will stop spamming your output once started.",
    "rbxassetid://156552337",
    "Stop"
)

-- Why am I using the same icon you may ask? Because I'm awful. That's why.
-- Note: if you leave the fourth argument blank, it will just display the icon.

Now we have our two buttons, where do we go from there? We have to make them work, of course! Let's start with the PrintButton. We do this via the button's Click event.

-- Services
local RunService = game:GetService("RunService")

-- Create the Toolbar
local Toolbar = plugin:CreateToolbar("My First Plugin!")

-- Create the Buttons
local PrintButton = Toolbar:CreateButton(
    "Print",
    "This will spam your output with randomly generated numbers.",
    "rbxassetid://156552337",
    "Print"
)

local StopButton = Toolbar:CreateButton(
    "Stop",
    "This will stop spamming your output once started.",
    "rbxassetid://156552337",
    "Stop"
)

-- Connect the PrintButton Event
local Connection = nil

PrintButton.Click:Connect(function()
    -- Note: we are using an anonymous function
    Connection = RunService.Heartbeat:Connect(function()
        print(Random.new():NextNumber())
    end)
end)

Whoaaaa nelly! Why did we create a variable named "Connection"? This will help us stop the plugin once we press the Stop button. It will also help us with Deactivation and Unloading which will we talk about soon.

-- Services
local RunService = game:GetService("RunService")

-- Create the Toolbar
local Toolbar = plugin:CreateToolbar("My First Plugin!")

-- Create the Buttons
local PrintButton = Toolbar:CreateButton("Print",
    "This will spam your output with randomly generated numbers.",
    "rbxassetid://156552337",
    "Print"
)

local StopButton = Toolbar:CreateButton("Stop",
    "This will stop spamming your output once started.",
    "rbxassetid://156552337",
    "Stop"
)

-- Connect the PrintButton Event
local Connection = nil

PrintButton.Click:Connect(function()
    -- Note: we are using an anonymous function
    Connection = RunService.Heartbeat:Connect(function()
        print(Random.new():NextNumber())
    end)
end)

-- Connect the StopButton Event
StopButton.Click:Connect(function()
    if Connection then
        Connection:Disconnect()
        Connection = nil
    end
end)

You may have noticed something, if we press the PrintButton twice and press the StopButton twice, it still prints. Why is that? It's because we have created two events but didn't disconnect it when making a new one. It's a bit confusing. Let me try to lay it out:

We click the PrintButton and we set the Connection to the RBXScriptSignal Roblox returns from calling Connect on an event. The RBXScriptSignal is what allows us to disconnect the event when we call Disconnect on it.

We click the PrintButton again, but recall how we didn't disconnect the previous event we created. So we create a new but overwrite the Connection variable. That event is still being executed because we didn't disconnect it. All we did was overwrite the variable. In order to prevent this, let's make sure the Connection variable is nil before setting it.

-- Services
local RunService = game:GetService("RunService")

-- Create the Toolbar
local Toolbar = plugin:CreateToolbar("My First Plugin!")

-- Create the Buttons
local PrintButton = Toolbar:CreateButton(
    "Print",
    "This will spam your output with randomly generated numbers.",
    "rbxassetid://156552337",
    "Print"
)

local StopButton = Toolbar:CreateButton(
    "Stop",
    "This will stop spamming your output once started.",
    "rbxassetid://156552337",
    "Stop"
)

-- Connect the PrintButton Event
local Connection = nil

PrintButton.Click:Connect(function()
    if not Connection then -- Note: we don't have to explicity check if Connection is nil because nil is a "falsy value"
        Connection = RunService.Heartbeat:Connect(function()
            print(Random.new():NextNumber())
        end)
    end
end)

-- Connect the StopButton Event
StopButton.Click:Connect(function()
    if Connection then
        Connection:Disconnect()
        Connection = nil
    end
end)

Congratulations! You have just made your first plugin. Granted, it's absolutely useless, but it's the thought that counts. But we aren't done yet, we still have to Activate the PrintButton once we click it, so we know it's in use. We do this via the SetActive method.

-- Services
local RunService = game:GetService("RunService")

-- Create the Toolbar
local Toolbar = plugin:CreateToolbar("My First Plugin!")

-- Create the Buttons
local PrintButton = Toolbar:CreateButton(
    "Print",
    "This will spam your output with randomly generated numbers.",
    "rbxassetid://156552337",
    "Print"
)

local StopButton = Toolbar:CreateButton(
    "Stop",
    "This will stop spamming your output once started.",
    "rbxassetid://156552337",
    "Stop"
)

-- Connect the PrintButton Event
local Connection = nil

PrintButton.Click:Connect(function()
    if not Connection then
        PrintButton:SetActive(true) -- This will highlight PrintButton a bluish color
        StopButton:SetActive(false)

        Connection = RunService.Heartbeat:Connect(function()
            print(Random.new():NextNumber())
        end)
    end
end)

-- Connect the StopButton Event
StopButton.Click:Connect(function()
    if Connection then
        Connection:Disconnect()
        Connection = nil
    end

    -- SetActive
    PrintButton:SetActive(false)
    StopButton:SetActive(false)
end)

We are almost finished, phew! Now we have to go over the Deactivation and Unloading events.

-- Services
local RunService = game:GetService("RunService")

-- Create the Toolbar
local Toolbar = plugin:CreateToolbar("My First Plugin!")

-- Create the Buttons
local PrintButton = Toolbar:CreateButton(
    "Print",
    "This will spam your output with randomly generated numbers.",
    "rbxassetid://156552337",
    "Print"
)

local StopButton = Toolbar:CreateButton(
    "Stop",
    "This will stop spamming your output once started.",
    "rbxassetid://156552337",
    "Stop"
)

-- Connect the PrintButton Event
local Connection = nil

PrintButton.Click:Connect(function()
    if not Connection then
        PrintButton:SetActive(true) -- This will highlight PrintButton a bluish color
        StopButton:SetActive(false)

        Connection = RunService.Heartbeat:Connect(function()
            print(Random.new():NextNumber())
        end)
    end
end)

-- Connect the StopButton Event
StopButton.Click:Connect(function()
    if Connection then
        Connection:Disconnect()
        Connection = nil
    end

    -- SetActive
    PrintButton:SetActive(false)
    StopButton:SetActive(false)
end)

-- Connect Deactivation and Unloading Events
plugin.Deactivation:Connect(function()
    -- This event is fired when a different plugin is selected

    if Connection then
        Connection:Disconnect()
        Connection = nil
    end

    -- SetActive
    PrintButton:SetActive(false)
    StopButton:SetActive(false)
end)

plugin.Unloading:Connect(function()
    -- This event is fired before the plugin unloads or is reloaded;
    -- this happens when the plugin is being uninstalled or updated.
    -- This event is important because it allows the plugin to clean
    -- up anything it has made (like connections) before being
    -- uninstalled/updated. In our case it's to disconnect the
    -- Connection variable so the output isn't being spammed once
    -- removed from Roblox Studio.

    if Connection then
        Connection:Disconnect()
        Connection = nil
    end

    -- SetActive
    PrintButton:SetActive(false)
    StopButton:SetActive(false)
end)

And there you have it: your first plugin! Congratulations, I know you will make something awesome.

Notes

If you release your plugin, then any user can insert the plugin into their game to see the source code. You can access installed plugins via this path: C:\Users\USER\AppData\Local\Roblox\InstalledPlugins. The plugin folder will be named after its AssetId.

To upload your plugin, right click on the script you used to write your plugin, then click "Publish as Plugin..." and take it from there.

Glossary

View in-game to comment, award, and more!