All articles
Building a plugin
Write your first plugin
Create a plugin with the PrusaSlicer CLI, see what its Lua file holds and run it in PrusaSlicer.
A plugin is one Lua file. It describes itself in an info table and does its work in an
execute function. Plugins travel in a bundle: a folder with manifest.json
and one or more plugin files. Everything the Lua code can call is in the
Lua API reference.
Some of the following commands assume the PrusaSlicer 3 executable is on your PATH as PrusaSlicer.
On macOS it is /Applications/PrusaSlicer.app/Contents/MacOS/PrusaSlicer.
1. Create the bundle
The plugin init command asks a few questions and writes a bundle with a hello world plugin:
cd ~/plugins
PrusaSlicer plugin init com.example.my-plugin
It creates the folder com.example.my-plugin with manifest.json and one Lua file. What you
answered lands in manifest.json, where you can change it later. For the licence, Tab completes
or lists the known SPDX identifiers.
The id is reverse-DNS and becomes the plugin’s identity in the marketplace for good, so pick it from one of your namespaces.
2. Run it in PrusaSlicer
PrusaSlicer loads plugins from the lua folder in its configuration folder (Help → Show
Configuration Folder). Link the bundle there instead of copying it, and every edit is picked up
on the next rescan:
ln -s ~/plugins/com.example.my-plugin "<configuration folder>/lua/com.example.my-plugin"
Then choose Plugins → Rescan. The plugin appears in the Plugins menu under the path its
info.menu names.
3. What the Lua file holds
info = {
id = "com.example.my-plugin.hello",
type = "project.plugin",
title = "Hello world",
menu = "Minimal/Hello world",
params = {
{ name = "num", label = "Your lucky number", type = "int", default = 42 },
},
}
function execute(params)
print("Hello no " .. params.num .. "!")
end
The info table
| Key | What it is |
|---|---|
id |
The plugin’s own id, reverse-DNS like the bundle’s. |
type |
The kind of plugin. Today only "project.plugin". |
title |
The name PrusaSlicer shows. |
menu |
Where it goes under Plugins, e.g. Calibration/My pattern. |
params |
The values the person fills in before it runs (below). |
Each entry of params becomes one control in the dialog PrusaSlicer opens before the plugin runs:
| Key | What it is |
|---|---|
name |
The key the value has in the table execute receives. |
label |
The control’s label. |
type |
float or int (a number field) or bool (a checkbox). |
default |
The value the control starts with. |
The execute function
execute(params) runs when the person confirms the dialog. params holds what they entered,
keyed by each parameter’s name, so the example reads its number as params.num.
4. Do something with the project
The api module builds geometry and the project takes it. This plugin adds a
cube of the size the person asks for:
info = {
id = "com.example.my-plugin.cube",
type = "project.plugin",
title = "Cube",
menu = "Examples/Cube",
params = {
{ name = "size", label = "Size [mm]", type = "float", default = 20 },
},
}
function execute(params)
local cube = api.make_cube(params.size, params.size, params.size)
api.project:add_object({ mesh = cube })
end
api.make_cube returns a Mesh, and
add_object takes an
ObjectDefinition: a table whose mesh is the geometry, with
an optional position, rotation and print settings.
What a plugin may touch
The plugin runtime is a sandbox on purpose:
- The standard
osandiomodules are not there. emboss_svg,load_stlandrequirereach only files in the plugin’s own folder.
So a plugin brings what it needs inside its bundle, and cannot read or change anything else on the computer.
Next
- Set up your editor for completion and type checks against the API.
- The plugin bundle: every field of
manifest.jsonand the files a bundle may hold. - Sign it and publish it.