SandyWelcome Documentation
A simple, clean and lightweight plugin for Paper servers that handles join & quit messages, title screens and join sounds — all configurable from a single YAML file, with zero dependencies.
Free resource by Dirtheen Studio — built and maintained by iSandyia_. If you enjoy it, check out SandyShops for a full GUI shop system.
What it does
SandyWelcome handles events when a player joins or leaves your server — with special handling for first-time players and a private MOTD message:
Requirements
| Requirement | Version | Notes |
|---|---|---|
| Paper or Purpur | 1.21 – 1.21.1 | Spigot is not supported. |
| Java | 21+ | Required by Paper 1.21. |
| Dependencies | None | Zero external plugins required. Just drop the JAR. |
Zero dependencies — no Vault, no PlaceholderAPI, no Citizens. SandyWelcome works completely standalone on any fresh Paper or Purpur server.
Installation
Download SandyWelcome-1.1.0.jar
Get the latest version from BuiltByBit — it's free, no purchase required.
Drop it in your plugins folder
Place SandyWelcome-1.1.0.jar inside server/plugins/.
Restart the server
On first launch, SandyWelcome generates plugins/SandyWelcome/config.yml and both readme_en.md and readme_es.md for quick reference.
Edit the config and reload
Customize config.yml to your liking, then run /sandywelcome reload — changes apply instantly, no restart needed.
config.yml
The single configuration file for the entire plugin. Located at plugins/SandyWelcome/config.yml. Everything is configurable here — messages, titles, sounds, feature toggles, first-join events and the private MOTD.
# ─────────────────────────────────────────────
# SandyWelcome — config.yml
# Color formats: & codes, RRGGBB hex, MiniMessage
# Placeholders: %player%, %online%, %max_players%
# ─────────────────────────────────────────────
join:
enabled: true
message: "&a+ &f%player% &7joined the server!"
title:
enabled: true
main: "<gradient:#f9a825:#ff6f00>Welcome!</gradient>"
subtitle: "&fEnjoy your stay, &e%player%&f!"
fade-in: 10 # ticks (20 ticks = 1 second)
stay: 60
fade-out: 20
sound:
enabled: true
name: "ENTITY_PLAYER_LEVELUP"
volume: 1.0
pitch: 1.0
motd:
enabled: true
lines:
- "<gradient:#f9a825:#ff6f00>&lWelcome to the server!</gradient>"
- "&7There are &e%online% &7of &e%max_players% &7players online."
- "&7Type &f/help &7to see available commands."
first-join:
enabled: true
message: "&6★ &e%player% &6joined for the first time! &6★"
title:
enabled: true
main: "<gradient:#f953c6:#b91d73>&lWelcome!</gradient>"
subtitle: "&fThis is your first time here, &d%player%&f!"
fade-in: 10
stay: 80
fade-out: 20
sound:
enabled: true
name: "UI_TOAST_CHALLENGE_COMPLETE"
volume: 1.0
pitch: 1.0
motd:
enabled: true
lines:
- "<gradient:#f953c6:#b91d73>&lWelcome for the first time!</gradient>"
- "&7We're glad to have you here, &d%player%&7!"
- "&7Don't forget to read the rules!"
quit:
enabled: true
message: "&c- &f%player% &7left the server."
messages:
reload-success: "&aSandyWelcome configuration reloaded successfully!"
reload-no-permission: "&cYou don't have permission to do that."
usage: "&eSandyWelcome &7v%version% &8| &7/sandywelcome reload"
Hot reload: After saving any change to config.yml, run /sandywelcome reload to apply it instantly without restarting the server.
Join Events
When a player connects to the server, SandyWelcome can trigger up to three independent events. Each one can be enabled or disabled individually.
Join Message
A message broadcast to all players on the server when someone joins. Supports the %player% placeholder and all color formats.
join:
enabled: true
message: "&a+ &f%player% &7joined the server!"
Title & Subtitle
A title screen shown only to the joining player. The timing values are in ticks (20 ticks = 1 second).
| Key | Type | Description |
|---|---|---|
enabled | boolean | Toggle the title on or off without touching other settings. |
main | string | The large title text. Supports all color formats and %player%. |
subtitle | string | The smaller text below the title. Same format support. |
fade-in | int (ticks) | How long the title takes to appear. Default: 10. |
stay | int (ticks) | How long the title stays fully visible. Default: 60. |
fade-out | int (ticks) | How long the title takes to disappear. Default: 20. |
Join Sound
A sound played only to the joining player. Must be a valid Bukkit Sound enum value. If an invalid name is entered, the server logs a warning and the plugin continues working normally — it will not crash.
sound:
enabled: true
name: "ENTITY_PLAYER_LEVELUP"
volume: 1.0 # 0.0 – 1.0+
pitch: 1.0 # 0.5 (low) – 2.0 (high)
Tip: Sound names must match the Bukkit Sound enum exactly — all uppercase with underscores. See the Sound Names section for a reference list and the Javadocs link.
Join MOTD
A list of private lines sent only to the joining player — not broadcast to the server. Supports all color formats and the placeholders %player%, %online%, and %max_players%.
motd:
enabled: true
lines:
- "<gradient:#f9a825:#ff6f00>&lWelcome to the server!</gradient>"
- "&7There are &e%online% &7of &e%max_players% &7players online."
- "&7Type &f/help &7to see available commands."
Private: MOTD lines are sent only to the joining player via player.sendMessage(). Other players on the server will not see them.
First Join
When a player connects to the server for the very first time, SandyWelcome uses the first-join section instead of the regular join section. This lets you give new players a special welcome experience — a unique broadcast, different title, a more festive sound, and a dedicated onboarding MOTD.
Detection: Uses Bukkit's player.hasPlayedBefore(). Returns false only on the very first connection. All subsequent joins use the regular join section.
First Join Message
A broadcast message sent to all players announcing the new player's first visit.
first-join:
enabled: true
message: "&6★ &e%player% &6joined for the first time! &6★"
First Join Title & Subtitle
A title screen shown only to the new player. Same key structure as the regular join title.
title:
enabled: true
main: "<gradient:#f953c6:#b91d73>&lWelcome!</gradient>"
subtitle: "&fThis is your first time here, &d%player%&f!"
fade-in: 10
stay: 80
fade-out: 20
First Join Sound
A sound played only to the new player. Defaults to UI_TOAST_CHALLENGE_COMPLETE for a more celebratory feel.
sound:
enabled: true
name: "UI_TOAST_CHALLENGE_COMPLETE"
volume: 1.0
pitch: 1.0
First Join MOTD
Private lines sent only to the new player — ideal for rules, Discord links, or onboarding instructions.
motd:
enabled: true
lines:
- "<gradient:#f953c6:#b91d73>&lWelcome for the first time!</gradient>"
- "&7We're glad to have you here, &d%player%&7!"
- "&7Don't forget to read the rules!"
MOTD (Private Message)
Both the join and first-join sections support a motd block — a list of private lines sent only to the joining player, not visible to anyone else on the server.
| Key | Type | Description |
|---|---|---|
enabled | boolean | Toggle the MOTD independently from other join events. |
lines | list of strings | Each entry is a separate chat message sent to the player. Supports all color formats. |
Available Placeholders in MOTD
| Placeholder | Replaced with |
|---|---|
%player% | The joining player's name. |
%online% | Current number of online players. |
%max_players% | Server's maximum player capacity. |
Note: %online% and %max_players% are available in all message fields (join, first-join, quit, title, subtitle), not just the MOTD.
Quit Events
When a player disconnects, SandyWelcome broadcasts a quit message to all remaining players on the server.
quit:
enabled: true
message: "&c- &f%player% &7left the server."
| Key | Description |
|---|---|
enabled | Set to false to completely disable quit messages. |
message | The message broadcast to all players. Supports all color formats and %player%. |
Note: There is no title, subtitle, or sound for quit events — those only apply on join. The quit section only controls the broadcast message.
Colors & Formats
SandyWelcome supports three color systems in any message field. The parser detects the format automatically — you can mix all three in the same string.
Legacy &-codes
The classic Minecraft color format. Works in all message fields.
| Code | Result |
|---|---|
| &0 | Black |
| &1 | Dark Blue |
| &2 | Dark Green |
| &3 | Dark Aqua |
| &4 | Dark Red |
| &5 | Dark Purple |
| &6 | Gold |
| &7 | Gray |
| &8 | Dark Gray |
| &9 | Blue |
| &a | Green |
| &b | Aqua |
| &c | Red |
| &d | Light Purple |
| &e | Yellow |
| &f | White |
| &l | Bold |
| &o | Italic |
| &n | Underline |
| &k | Obfuscated (scrambled text) |
| &r | Reset all formatting |
Hex Colors
Use any 24-bit RGB color with the RRGGBB format. For example: F953C6 produces a pink color.
message: "F953C6Hello B91D73%player%!"
MiniMessage
Full MiniMessage support including gradients, rainbow, decorations and other tags. The parser detects MiniMessage automatically when tags are present.
# Gradient
message: "<gradient:#f9a825:#ff6f00>Welcome, %player%!</gradient>"
# Rainbow
message: "<rainbow>%player% joined!</rainbow>"
# Bold + color
message: "<bold><gold>+</gold></bold> %player% joined the server!"
Mixing formats: You can freely combine legacy codes, hex colors and MiniMessage tags in the same string. The parser handles all three simultaneously.
Commands
config.yml without restarting the server. All changes apply immediately.Permissions
/sandywelcome reload. Defaults to OP.
Note: There are no per-player or per-group permissions for receiving join/quit messages — those are always broadcast to all online players. The only permission node controls access to the admin reload command.
Sound Names
Sound names must be valid Bukkit Sound enum values — all uppercase, words separated by underscores. If an invalid name is used, the server logs a warning with the invalid value and a link to the Javadocs. The plugin continues working normally.
Popular sound names
| Sound Name | Description |
|---|---|
ENTITY_PLAYER_LEVELUP | Default join. Level-up "ding" sound. |
UI_TOAST_CHALLENGE_COMPLETE | Default first-join. Advancement fanfare — festive and distinct. |
ENTITY_EXPERIENCE_ORB_PICKUP | XP pickup chime — subtle and clean. |
BLOCK_NOTE_BLOCK_PLING | Note block pling — short and sharp. |
UI_TOAST_IN | Achievement toast sound. |
ENTITY_FIREWORK_ROCKET_LARGE_BLAST | Firework blast — loud and festive. |
BLOCK_BEACON_ACTIVATE | Beacon activation sound. |
ENTITY_VILLAGER_YES | Villager "yes" trade sound. |
Full list: See all available sounds in the PaperMC Javadocs — Sound enum.
Disabling the sound
To turn off the join sound without removing the config entry, set sound.enabled to false:
sound:
enabled: false
File Structure
SandyWelcome generates the following files on first server launch:
└── SandyWelcome/
├── config.yml ← main configuration
├── readme_en.md ← quick reference (English)
└── readme_es.md ← quick reference (Español)
The readme_en.md and readme_es.md files are generated automatically and contain a quick summary of commands, permissions and color formats for server admins who don't want to visit the docs page.
FAQ
Do I need Vault, PlaceholderAPI or any other plugin?
No. SandyWelcome has zero external dependencies. Drop the JAR in your plugins folder and restart — that's it.
How does the first-join detection work?
SandyWelcome uses Bukkit's built-in player.hasPlayedBefore() method. The first time a player ever connects to the server, this returns false — SandyWelcome uses the first-join section for that event. All subsequent joins use the regular join section.
Can I disable the MOTD without disabling the rest of the join events?
Yes. Each feature has its own enabled toggle. Set join.motd.enabled: false (or first-join.motd.enabled: false) to turn off the private message without affecting the broadcast, title, or sound.
Does it work on Purpur?
Yes. SandyWelcome uses the Paper API, which Purpur is fully compatible with. Any Paper 1.21-compatible fork should work.
Can I use MiniMessage gradients in messages?
Yes. The parser detects MiniMessage tags automatically. You can also mix them with legacy &-codes and hex colors in the same string.
What happens if I put a wrong sound name?
The server logs a warning including the invalid name and a link to the PaperMC Javadocs. No crash, no exception — the rest of the plugin continues working normally.
Can I disable just the title without disabling the join message?
Yes. Each feature has its own enabled toggle. You can have a join message with no title, a sound but no message, a title with no sound — any combination works independently.
What are readme_en.md and readme_es.md?
On first server start, SandyWelcome generates two small readme files inside plugins/SandyWelcome/ — one in English and one in Spanish — with a quick reference for commands, permissions and color formats. They're there for convenience and can be ignored.
How do I completely hide the default Minecraft join/quit messages?
SandyWelcome replaces the vanilla join and quit messages automatically when enabled: true. If you set enabled: false on both, the vanilla messages will show instead.
Contact & Support
SandyWelcome is a free resource maintained by iSandyia_ at Dirtheen Studio. For bug reports, questions, or feedback:
| Channel | Details |
|---|---|
| Discord | discord.gg/aQg5TeEF6h — fastest support, bug reports & suggestions |
| BuiltByBit page | builtbybit.com — SandyWelcome — use the discussion tab for support |
| Studio email | dirtheen.studio@gmail.com |
| Author email | contact.isandyia@gmail.com |
Want a full economy? Check out SandyShops — a GUI shop system with buy & sell, VIP discounts, Sell All, Bedrock support, PlaceholderAPI and a developer API. Paper 1.21+.