
SkDialogs
Create dialog forms, button menus, and confirmation pop-ups in plain Skript, and read every input a player submits.
I don't know my version or loader


SkDialogs
A Skript addon for Paper's dialog API, the modal windows added to Minecraft in 1.21.6. It adds the syntax to build and show them from a script: forms with text fields, toggles, sliders, and dropdowns, buttons that run commands or open other dialogs, and a click event with everything the player entered.
For example, rules every player must accept before playing:
on join:
if {rules accepted::%player's uuid%} is true:
stop
create dialog "rules":
set title to "&6Server rules"
set close on escape to false
add body "&71. Be kind."
add body "&72. No griefing."
add button "accept" labeled "&2I accept the rules"
add button "decline" labeled "&cDecline"
show dialog "rules" to player
on dialog click "rules":
if the clicked button is "accept":
set {rules accepted::%event-player's uuid%} to true
send "&aThanks for accepting. Have fun!" to event-player
else:
kick event-player due to "&cYou must accept the rules to play."
Install
- Install Skript 2.12 or newer on Paper 1.21.8 or newer.
- Drop
skdialogs-<version>.jarfrom the latest release intoplugins/. - Restart the server.
Every example on this page is complete. Paste one into a file in plugins/Skript/scripts/, run
/sk reload all, and try it in game. examples/ has all of them as files, plus a few
bigger ones.
How it works
Every dialog follows the same three steps.
create dialog "id":defines a dialog and registers it under an id. The lines inside the section set its title, content, inputs, and buttons.show dialog "id" to playerdisplays it. One dialog can be shown many times, to any players.on dialog click "id":fires when a button is pressed. Inside it,the clicked buttonis the button's id anddialog input "key"is what the player entered.
Buttons can also carry an action (run a command, open a link) and then skip step 3 entirely. All
strings go through Skript's chat format, the same as send: & colour codes, hex colours, and
tags like <translate:item.minecraft.filled_map>, which each client renders in its own language.
Ask for input
A dialog can hold four kinds of input: a text field, a toggle, a slider, and a dropdown. Each input has a key, and the click handler reads each value by that key.
command /character:
trigger:
create dialog "character":
set title to "Create your character"
add body "This cannot be changed later."
add text input "name" labeled "Name" with default "%player%" with max length 16
add toggle input "hardcore" labeled "Hardcore mode?" with default false
add slider input "level" labeled "Starting level" from 1 to 10 with step 1 with default 1
add dropdown input "class" labeled "Class" with options "knight", "ranger" and "mage" with default "knight"
add button "confirm" labeled "&2Confirm"
show dialog "character" to player
on dialog click "character":
set {_name} to dialog input "name"
set {_class} to dialog input "class"
set {_level} to dialog input "level"
send "&aWelcome, %{_name}% the %{_class}%, starting at level %{_level}%." to event-player
A dropdown can also list its choices as a section, so each choice shows a label different from the id you read back:
add dropdown input "class" labeled "Class":
option "knight" labeled "&fThe Knight" as default
option "ranger" labeled "&aThe Ranger"
option "mage" labeled "&bThe Mage"
Buttons that act on their own
A button with an action clause needs no click handler. It runs a command, opens a link, copies text, pre-fills the chat box, or opens another dialog.
command /menu:
trigger:
create dialog "menu":
set title to "&6Server menu"
add button labeled "&aSpawn" that runs "/spawn"
add button labeled "&bWiki" that opens "https://docs.papermc.io"
add button labeled "Copy server IP" that copies "play.example.com"
add button labeled "Message an admin" that suggests "/msg admin "
add exit button "close" labeled "Close"
show dialog "menu" to player
that runs can take input straight from the dialog. A $(key) placeholder is filled with that
input's value at click time, which turns a dialog into a form that submits to a command:
command /rename:
trigger:
create dialog "rename":
set title to "Rename yourself"
add text input "name" labeled "New name" with max length 16
add button labeled "&2Apply" that runs "/nick $(name)"
add exit button "cancel" labeled "Cancel"
show dialog "rename" to player
Note the two substitutions in play. $(name) is filled by the dialog when clicked, while Skript's
own %player% is filled when the dialog is created.
A menu of dialogs
add dialog "id" to the list turns a dialog into a menu whose entries open other dialogs. A button
with that shows links back, so the menu loops.
command /hub:
trigger:
create dialog "hub-rules":
set title to "&eRules"
add body "1. Be kind. 2. No griefing. 3. Have fun."
add button "back" labeled "← Back" that shows "hub"
create dialog "hub-kit":
set title to "&aStarter kit"
add button "warrior" labeled "Warrior"
add button "mage" labeled "Mage"
add button "back" labeled "← Back" that shows "hub"
create dialog "hub":
set title to "&6Server hub"
add dialog "hub-rules" to the list
add dialog "hub-kit" to the list
add exit button "close" labeled "Close"
show dialog "hub" to player
on dialog click "hub-kit":
if the clicked button is "warrior" or "mage":
send "&aYou chose the %the clicked button% kit." to event-player
Keep the dialog open
By default a dialog closes when a button is pressed. set after click to keep open leaves it on
screen, so a player can press a button several times and each click re-reads the inputs as they
stand.
command /volume:
trigger:
create dialog "volume":
set title to "Music volume"
set after click to keep open
add slider input "level" labeled "Volume" from 0 to 100 with step 5 with default 50
add button "apply" labeled "Apply"
add exit button "done" labeled "Done"
show dialog "volume" to player
on dialog click "volume":
if the clicked button is "apply":
set {volume::%event-player's uuid%} to dialog input "level"
send "&7Volume set to &f%{volume::%event-player's uuid%}%&7." to event-player
Syntax reference
The complete set of patterns, in Skript's own notation: [square brackets] are optional, (a|b)
is a choice, and %string% is any expression of that type.
Create a dialog
(create|make) dialog [(named|with id)] %string%:
Opens a section that defines a dialog and registers it under the given id. The section body runs once, immediately; only the effects below are valid inside it. Creating a dialog with an id that already exists replaces the old one.
The id is how you refer to the dialog everywhere else: show dialog, on dialog click,
that shows, and add dialog ... to the list.
Properties
set [the] title [of [the] dialog] to %string%
set [the] external title [of [the] dialog] to %string%
set [the] columns [of [the] dialog] to %number%
set (closing|close) on escape [of [the] dialog] to %boolean%
set [the] after[ ]click [behaviour|behavior] [of [the] dialog] to (close|keep open|wait [for response])
| Property | Default | Meaning |
|---|---|---|
title |
the dialog's id | Text shown at the top of the window. |
external title |
the title | Label shown where a client lists the dialog outside itself. |
columns |
2 | How many columns of buttons a multi-action or list dialog lays out. |
close on escape |
true | Whether the escape key closes the dialog. |
after click |
close | What the dialog does once a button is pressed. |
The after click choices are close (the dialog closes), keep open (it stays on screen, so a
player can press a button several times and each click re-reads the inputs), and wait for response
(it greys out until the server replies).
Vanilla's pause-menu and quick-action buttons come from data pack tags resolved at load, so dialogs created at runtime cannot appear there.
Body
add [a] [plain] body %string% [with width %number%]
add [an] item body %itemstack% [with description %string%] [without tooltip] [without decorations] [sized %number% by %number%]
Adds a line of content: a message, or a rendered item. An item's description is shown next to it,
without tooltip hides its hover tooltip, without decorations hides its count and durability
bar, and sized sets the box it renders in (width by height, 16 by 16 unless set).
Inputs
Every input takes a key (its name in the click event) and an optional labeled label, which
defaults to the key.
add text input %string% [labeled %string%] [with default %string%] [with max[imum] length %number%] [with width %number%] [multiline [up to %number% lines]]
add (boolean|toggle) input %string% [labeled %string%] [with default %boolean%] [with values %string% and %string%]
add (slider|number) input %string% [labeled %string%] (from|between) %number% (to|and) %number% [(by|with step) %number%] [with default %number%] [with format %string%] [with width %number%]
add (dropdown|choice) input %string% [labeled %string%] with options %strings% [with default %string%] [with width %number%]
| Input | Player sees | dialog input "key" returns |
|---|---|---|
text |
a text field, multi-line with multiline |
the entered text (max length defaults to 32) |
toggle |
an on/off switch | true or false |
slider |
a slider over the given range | a number |
dropdown |
a list of choices | the chosen option's id |
A slider without a default starts at the low end of its range. with format shapes the slider's
label, with {label} and {value} marking the substitutions, e.g. with format "{value} blocks".
A toggle's with values sets what a $(key) command placeholder becomes for each state, e.g.
with values "64" and "1" instead of true and false.
A dropdown can also list its choices as a section, so each choice shows a label different from the id you read back:
add (dropdown|choice) input %string% [labeled %string%]:
option %string% [labeled %string%] [[as] [the] default]
Buttons
add [a] button [%string%] [labeled %string%] [with tooltip %string%] [with width %number%] [that (runs|opens|copies|suggests|shows) %string%]
add [an] exit button [%string%] [labeled %string%] [with tooltip %string%] [with width %number%]
The label defaults to the id. What a button does depends on its action clause:
| Clause | On click |
|---|---|
| none | Fires on dialog click; the id is required so you can match it there. |
that runs %string% |
Runs the command as the player. A $(key) placeholder is filled with that input's value at click time. |
that opens %string% |
Asks to open the url. |
that copies %string% |
Copies the text to the clipboard. |
that suggests %string% |
Pre-fills the chat box with the text. |
that shows %string% |
Opens the dialog with that id. |
The exit button is the single back/cancel button a multi-action or list dialog shows below the others; a dialog can have at most one.
that runs runs the command as the player, with the player's permissions, and the client asks the
player to confirm a plain command first. Work that needs more permission than the player has
belongs in on dialog click instead.
How the dialog is laid out follows from its buttons. No buttons is a plain notice; one button is a
notice with that button; one button plus an exit button is a yes/no confirmation; anything more is
a multi-action dialog in the configured columns. Setting columns turns a confirmation back into
a multi-action.
Dialog lists
add dialog %string% to [the] list
add [the] server links to [the] list
Adds another dialog, by id, as an entry in this dialog's menu. A dialog with any list entries is
shown as a list: each entry is a button that opens that dialog. server links instead presents
the link list the server advertises.
Server links
add [a] server link labeled %string% to [url] %string%
add [a|the] (bug report|community guidelines|support|status|feedback|community|website|forums|news|announcements) server link to [url] %string%
(clear|delete) [all] [the] server links
Manages the server's link list, shown under "Server Links" in the pause menu and in a
server links dialog. Links are server-wide, so on load is the natural place to set them. A
typed link is labelled by each client in its own language; a labeled link shows your text, and a
<translate:...> tag makes that per-language too. Clearing first lets a reloading script rebuild
the list without stacking duplicates.
on load:
clear the server links
add server link labeled "<translate:item.minecraft.filled_map>" to "https://map.example.com"
add website server link to "https://example.com"
Show and close
(show|open) dialog %string% (to|for) %players%
close [the] [current] dialog (for|of|to) %players%
show dialog displays a created dialog; showing to all players works too. close dialog closes
whatever dialog each player has open, from any plugin.
The click event
on dialog (click|submit|button click):
on dialog (click|submit) [(of|for)] %string%:
Fires when a player presses an event button (one with no action clause) on a dialog this addon created. The optional id restricts the event to one dialog.
Inside the event:
event-player # the player who submitted the dialog
[the] clicked [dialog] button # the pressed button's id
[the] [clicked] dialog id # the dialog's id
[the] [dialog] input [value] [(of|for)] %string% # one input's value, by key
[the] [dialog] value of [input] %string% # the same, worded differently
An input's value is a text, a boolean, or a number, matching the inputs table above. Reading a key the dialog does not have gives nothing.
Build
Requires a JDK 25, the version Paper 26.2 needs (the wrapper fetches Gradle itself).
./gradlew build
The jar lands in build/libs/. The addon compiles against the exact Paper build pinned in
gradle.properties; to follow a new Paper build, bump that property and fix whatever no longer
compiles.
CI builds every push and pull request, and a weekly paper-api job compiles against the latest
Paper build, so a breaking change to the experimental dialog API shows up as a failed run instead
of a surprise on a server. Pushing a vX.Y.Z tag attaches the jar to a GitHub release and
publishes it to Modrinth.
Contributing
Bug reports, feature requests, and pull requests are welcome. See CONTRIBUTING.md for how to set up a dev environment and what a good pull request looks like.
License
- Ships as skdialogs-1.1.0.jar — drop this file into the mods folder
- Download size: 56 KB
- Download link checked 9 Aug 2026 — working
These come from our own check of the pack file, not from the source page.