How to create your own plugin

Edit: Thanks @EOASTUDIO and @GamersInternational for noticing some important mistakes!

Note: you need know roblox basic scripting!

Hello! So im pretty sure you wanted to create your own plugin but didn’t knew how. In this tutorial I will explain you how to create your own plugin! Let’s do for example a script inserter plugin.

Steps

Step 1 - Creating plugin on toolbar
Step 2 - Scripting button
Step 3 - Adding gui for our plugin
Step 4 - Creating non widget gui
Step 5 - Publishing plugin
Step 6 - The End

Step 1 - Creating plugin on toolbar

So first we need add our plugin onto plugins toolbar. To do this we need create a new script. You can paste it anywhere.
After what you must type this:

local toolbar = plugin:CreateToolbar("Plugin Name")

We have created a toolbar on plugins. Plugin Name is a name of your toolbar. You can name it whatever you want! Okay we added a toolbar but what about buttons?

local pluginButton = toolbar:CreateButton(
"Insert Script", --Text that will appear below button
"Button to insert a script", --Text that will appear if you hover your mouse on button
"rbxassetid://8740888472") --Button icon

Note: button image must be Image ID and not Decal ID. Its the best if button icon is 16x16 or 32x32 and not an GFX. Since its only example I took random image from toolbox

The simplest way to turn Decal ID into Image ID is to put Decal ID into ImageLabel Image property and boom! You got Image ID

So what we just did is created a button onto our plugin. To test it you must save your plugin:
gfdgfdg
And your plugin will appear on toolbar!

However it does nothing if you click it. So let’s make it work. You will need to repeat this step everytime you adding something new to script in order to test it!

Step 2 - Scripting button

pluginButton.Click:Connect(function()
print("Button has been clicked.")
end)

If in your output it printed out Button has been clicked. then everything works fine! You can do your own plugin now! However my plugin is about to insert script so im going to finish it.

pluginButton.Click:Connect(function()
local scrp = Instance.new("Script")
scrp.Source = ""
scrp.Name = "EmptyScript"
scrp.Parent = game.ServerScriptService
end)

Great! Our plugin creates a script as we wanted! But what about if we want insert a local scirpt? Sure we can create another button that inserts local script… But we don’t like easy ways! Right?
Actually I just need a reason to create a gui for plugin.

Step 3 - Adding gui for our plugin

So you can create gui in normal way you want to. I will use this one:

So now we must drag our gui inside script. However I recommend creating a folder which contains plugin source. Also if you insert ScreenGui nothing gonna work.
fgdfdgfdg

So now we must make it that our gui appears when plugin clicks. We going to make it in widget form!
But first we need widget information.

local info = DockWidgetPluginGuiInfo.new(
	Enum.InitialDockState.Right, --From what side gui appears
	false, --Widget will be initially enabled
	false, --Don't overdrive previouse enabled state
	200, --default weight
	300, --default height
	150, --minimum weight (optional)
	150 --minimum height (optional)
)

But it won’t create actual widget. To create actual widget we need create it.

local widget = plugin:CreateDockWidgetPluginGui(
"TestPlugin", --A unique and consistent identifier used to storing the widget’s dock state and other internal details
info --dock widget info
)

But if we test it now nothing gonna happen. Why? Because we didn’t finished some things!

widget.Title = "Insert Script GUI" --Giving title to our widget gui

Cool! But what about our gui that we want to be in our widget? To do it we need parent it to our widget

script.Parent.MainFrame.Parent = widget

I lied. :coefficients: The widget doesn’t shows because we didn’t enabled it. So let’s do this!

pluginButton.Click:Connect(function()
widget.Enabled = not widget.Enabled
end)

Now if we test it now it will appear! So let’s now script our buttons. You can script them as you usual. Nothing changed here so im not going to explain anything here.

local buttonScript = mainFrame.InsertScript
local buttonLocal = mainFrame.InsertLocalScript

buttonScript.MouseButton1Click:Connect(function()
local new = Instance.new("Script")
new.Source = ""; new.Name = "EmptyScript"; new.Parent = game.ServerScriptService
end)
buttonLocal.MouseButton1Click:Connect(function()
local new = Instance.new("LocalScript")
new.Source = ""; new.Name = "EmptyLocalScript"; new.Parent = game.ServerScriptService
end)

Great! But what if I don’t want create it as a widget? Well let’s do this then!

Step 4 - Creating non widget gui

So this time we will need screen gui. This time we need parent gui to CoreGui. You may ask “Why not in StargetGui or PlayerGui?” Well the answer is simple. Not StarterGui Because if user will run the game plugin will be in the game too. User also will be able to modify the gui which we don’t want. Not PlayerGui because there no any player. It’s almost just like with widget but without info table.

local CoreGui = game:GetService("CoreGui") --Getting CoreGui
local gui = CoreGui:FindFirstChild("PluginGui") or script.Parent.PluginGui
gui.Enabled = false --Making gui invisible
gui.Parent = CoreGui --Parenting gui to coregui

pluginButton.Click:Connect(function()
gui.Enabled = not gui.Enabled --Enabling/Disabling gui after button clicked
end)

Step 5 - Publishing plugin

Thats it! But how do you make it so everyone can use your plugin? You must publish it!
ddddddddddddddd
Configure it as you need. After you done you must enable sale so people can install it:

And then you can submit it!

Step 6 - The end

That’s it! You have created your own plugin! Bye!

122 Likes

This is a good tutorial! This is really useful for people who are getting into plugins.

10 Likes

I cant add it as a UI, only a widget…? I do not know if i need to remove some lines of code or something else…?

1 Like

There a step where it explains how to create it as a UI

3 Likes

This mistake is meant to say CoreGui not CorgeGui

3 Likes

It’s not a bad tutorial, but there’s certainly some flaws.

You should clarify here that you need to use an image ID and not a decal ID. You should also tell people how they can change a decal ID to an image ID (e.g. using @Elttob’s Imiji plugin, or creating an imagelabel somewhere, pasting a decal ID in, and then copying the image ID).

This is just general advice, but you should encourage people to use a 16x16 or 32x32 icon (and not a GFX lol), else it won’t look clear if a lot is happening in the icon. You can achieve this with software/websites such as Figma, Lunacy or Inkscape.

Please make sure to add gui.Archivable = false, otherwise, the plugin GUI will be embedded into the game file, and when you publish. I’m not sure whether this is true, but it could also cause your experience to be taken down.

Even though it’s not needed in most cases, I would personally run a FindFirstChild to prevent the event of multiple copies of the plugins GUI to show up (this can occur when a player updates the plugin, or a plugin developer forgets to make Archivable false) (run it before moving the GUI into the CoreGui, and make sure that if the condition is true, that you delete it).

8 Likes

Thanks! I would never notice that mistake!

1 Like

Thanks a lot! I probably would not get that for a long time!

2 Likes

I have a question, what does source do?

1 Like

Example plugin in the source creates script or local script.

1 Like

This post helped me a lot. Thank you!

Sorry for bumping, but how do you create something like this in the widget?
image

3 Likes

You’ll have to code it just like any other Roblox Studio UI, here’s a good resource for pre-made studio widget modules provided: GitHub - Roblox/StudioWidgets

6 Likes

When i save it, i get this error:
MainFrame is not a valid member of Plugin “user_EmptyScriptInserter.lua”
Help please?

Can you show your code you are using?

It’s slightly different - i made it so it uses the same toolbar each time but that code works (I’ve tested it). My script is a script in a folder in ServerScriptService.
Code:

local Toolbar
local ToolbarName = "Mac's plugins"
local ToolbarCombiner = game:GetService("CoreGui"):FindFirstChild(ToolbarName)
if ToolbarCombiner then
	Toolbar = ToolbarCombiner.Value
else
	Toolbar = plugin:CreateToolbar(ToolbarName)
	ToolbarCombiner = Instance.new("ObjectValue")
	ToolbarCombiner.Value = Toolbar
	ToolbarCombiner.Name = "ToolbarName"
	ToolbarCombiner.Parent = game:GetService("CoreGui")
end

local PluginButton = Toolbar:CreateButton(
	"Empty script inserter!",
	"Button to insert a script - my first plugin.",
	"rbxassetid://11570626761"
)

local DockWidgetInfo = DockWidgetPluginGuiInfo.new(
	Enum.InitialDockState.Float,
	false,
	false,
	200,
	200
)
local Widget = plugin:CreateDockWidgetPluginGui(
	"EmptyScriptInserter",
	DockWidgetInfo
)
Widget.Title = "Empty script inserter"
script.Parent.MainFrame.Parent = Widget
local WindowOpen = false

function OnClick()
	if PluginButton.Enabled == true then
		Widget.Enabled = true
	else
		Widget.Enabled = false
	end
end

PluginButton.Click:Connect(OnClick)

What exactly do you save as plugin? The folder or the script? If it’s the folder then make sure MainFrame is inside the folder, or if MainFrame inside the script then delete the .Parent part.
If it’s the script then overwrite it by saving the folder.
If it won’t help, I have no idea how to fix it then.

2 Likes

Ty, works a treat! Saved the folder and it works!

2 Likes

it work not there stay in output MainFrame is not a valid member of Plugin "user_plugin.lua"

  • with this script
local toolbar = plugin:CreateToolbar('nil')

local pluginButton = toolbar:CreateButton(
	'nil',
	'nil',
	''
)

local info = DockWidgetPluginGuiInfo.new(
	Enum.InitialDockState.Right,
	false,
	false,
	200,
	300,
	150,
	150
)



local widget = plugin:CreateDockWidgetPluginGui(
	'nil',
	info
)

widget.Title = 'nil'
script.Parent.MainFrame = widget

pluginButton.Click:Connect(function()
	widget.Enabled = true
end)

  1. serverstorage
  2. map
  3. child script
  4. child mainframe

i have saved script

it plugin have a name but i will not that somone my idea stole

that means theres no such thing as “MainFrame” in the script’s parent which is the plugin object; make sure the path is correct and no we will not “steal” your plugin

1 Like