Skip to main content

AstroJoinLeave Documentation

Complete configuration guide for AstroJoinLeave v1.0.0. Setup, commands, permissions, integrations with EssentialsX / CMI / LuckPerms / PlaceholderAPI, troubleshooting, and FAQ.

Overview

AstroJoinLeave replaces the default vanilla join and leave messages with custom, configurable ones. It supports per-LuckPerms-group messages, hex colors, MiniMessage gradients, sound effects, and a one-time welcome title for first-time joiners. Optional integrations with Discord (via webhook) and PlaceholderAPI for richer placeholders.

Why pick this. EssentialsX has join/leave messages but they are global — every player gets the same one. CMI has per-group support but bundles 50 other features you do not need. AstroJoinLeave is focused: just join/leave messaging done well, configurable per group, no bloat.

Server types

  • Survival SMP
  • Network hubs
  • RPG / lore
  • Skyblock
  • Faction servers
  • VIP-rank servers

Problems it solves

  • Vanilla 'Player joined the game' is bland and indistinguishable from notable members
  • VIP / donor players want recognition on join
  • First-time players get no welcome and may not know what to do next
  • Default messages do not match the brand voice (RPG / lore servers need immersion)
  • Servers can not differentiate staff joins from regular player joins

Installation

  1. 1

    Download the plugin

    Get AstroJoinLeave-1.0.0.jar from the download page.

  2. 2

    Upload to your server

    Place AstroJoinLeave-1.0.0.jar in your server's plugins/ folder.

  3. 3

    Restart the server

    Run /stop to shut down, then start the server again. Do not use /reload.

  4. 4

    Verify installation

    Check the console for "[AstroJoinLeave] Enabled" or run /plugins.

  5. 5

    Configure

    Edit plugins/AstroJoinLeave/config.yml. Use the reload command to apply changes.

Requirements: Paper, Purpur, or Folia server running Minecraft 1.20+. Java 21+.

Configuration

The default config.yml is generated on first run. Edit and reload to apply changes. Below are 4 example configs for different server types.

Simple SMP (default-friendly)

Single message for everyone with a small flourish for first joins.

default:
  join: "&a+ &f%player% joined the server"
  leave: "&c- &f%player% left the server"
  first-join: "&6Welcome &f%player%! &7Type /help for commands"
  first-join-title:
    title: "&6Welcome"
    subtitle: "&7Enjoy your stay"
    fade-in: 10
    stay: 50
    fade-out: 10

groups: {}  # No per-group customization

Network with VIP rank recognition

Different messages per LuckPerms group. VIPs get a flashier welcome.

default:
  join: "&7+ %player%"
  leave: "&7- %player%"
  first-join: "&aWelcome &6%player% &ato the server!"

groups:
  vip:
    join: "&6✦ &eVIP %player% &fhas arrived"
    leave: "&7✦ &eVIP %player% &fleft"
  mvp:
    join: "&b★ &fMVP %player% &fhas arrived &7(welcome back)"
    leave: "&7★ &fMVP %player% &fleft"
  staff:
    join: "&c⚔ &fSTAFF %player% &7is now online"
    leave: "&7⚔ &fSTAFF %player% &7logged off"

RPG / lore server (immersive)

Long-form, in-character join/leave with MiniMessage gradient.

default:
  join: "<gradient:#67F0D3:#22D3EE>%player% steps into the realm</gradient>"
  leave: "<gradient:#22D3EE:#67F0D3>%player% fades from the world</gradient>"
  first-join: "<gradient:#FFD700:#F5A500>A new adventurer arrives. Welcome, %player%!</gradient>"
  first-join-title:
    title: "<gold>You wake up...</gold>"
    subtitle: "<gray>What is your story?</gray>"
    fade-in: 20
    stay: 80
    fade-out: 20

Silent mode for staff testing

Disable broadcasts entirely (useful when staff are testing builds).

default:
  join: ""  # Empty disables the broadcast
  leave: ""
  first-join: ""

groups:
  staff:
    join: ""  # Staff testing — stay silent
    leave: ""

Config location

plugins/AstroJoinLeave/config.yml

Use Cases

Real scenarios with step-by-step setup. Pick the closest match to your server and adapt.

Hide vanish'd staff joins from regular players

Scenario: Staff use /vanish to enter the server invisibly to monitor. You do not want the join broadcast to give away that they are online.

  1. Install SuperVanish or PremiumVanish.
  2. AstroJoinLeave automatically suppresses the join broadcast for vanish'd players (it listens to PlayerJoinEvent and checks isVanished via the vanish API).
  3. Verify: log in vanish'd, no broadcast. Log in normally, broadcast fires.

Welcome first-time players with a Discord ping

Scenario: You want your community manager to see when a brand-new player joins so they can welcome them in Discord chat.

  1. Set discord.webhook-url in config.yml to your Discord webhook URL.
  2. Set discord.first-join-mention to '@CommunityManager' or a role ping.
  3. On first join, the plugin POSTs the first-join message to Discord with the mention.
  4. Test by creating a fresh Mojang account and connecting — the Discord channel should see the ping.

Differentiate rank tiers visually

Scenario: You run an economy server with 5 ranks. Donors want their rank to be visible when they join.

  1. Map each LuckPerms group to a join/leave message in 'groups' section.
  2. Use group-specific colors that match your rank colors elsewhere (gold for VIP, aqua for MVP).
  3. Add a sound effect per rank (default: pling; VIP: ui.toast.in; etc) via 'groups.<group>.sound'.
  4. Test by switching your group with /lp user <self> parent set <group>.

Suppress broadcasts during raid

Scenario: During a PvP event you want to silence join/leave messages so they do not flood chat.

  1. Run /astrojoin silence on (placeholder — actual command is /jl silence on).
  2. Plugin stops broadcasting until you run /jl silence off.
  3. Note: this is a runtime override and does not persist across restarts.

Show online players a count update on every join

Scenario: Small SMP, you want players to know 'X players online' after every join.

  1. Set join message to include %online%/%max% via PlaceholderAPI.
  2. Example: '&a+ &f%player% &7(%online%/%max% online)'.
  3. Install PlaceholderAPI if not already.

Commands

CommandDescriptionPermission
/astrojoinleave reloadReload configastrojoinleave.admin

Permissions

NodeDescriptionDefault
astrojoinleave.adminUse reloadop
astrojoinleave.group.<rank>Use specific rank message templateop

Recommended LuckPerms group setups

default

Anyone — gets the generic join/leave message

# No explicit nodes needed for the default group

vip

VIP donors — gets the gold-flavored message

/lp group vip permission set group.vip true

staff

Staff — gets a distinct staff-flavored message; can /jl silence

/lp group staff permission set group.staff true
/lp group staff permission set astrojoinleave.silence true
/lp group staff permission set astrojoinleave.reload true

Tip: Use LuckPerms to manage permissions per player or group.

Integrations with other plugins

How AstroJoinLeave works alongside common Spigot/Paper plugins.

LuckPerms

Used to detect which group the joining player belongs to. Without LuckPerms, all players fall through to the 'default' group.

/lp user <player> parent set vip
# Now their join message uses the 'vip' group config

PlaceholderAPI

Enables placeholders beyond %player%. Examples: %online%, %max_players%, %vault_eco_balance%, %luckperms_prefix%. AstroJoinLeave passes the message through PAPI before sending.

SuperVanish / PremiumVanish

Detects vanish'd players via API and suppresses their join/leave broadcasts. No extra config needed — auto-detected at startup.

DiscordSRV

DiscordSRV automatically picks up Minecraft chat and forwards it to Discord. If you want join/leave broadcasts in Discord, just keep DiscordSRV's chat-to-discord enabled. If you want a dedicated channel with custom formatting, use the AstroJoinLeave discord.webhook-url config instead.

discord:
  webhook-url: "https://discord.com/api/webhooks/..."
  first-join-mention: "<@&123456789012345678>"

EssentialsX

EssentialsX has join/leave messages too. To use AstroJoinLeave instead, disable Essentials' messages: in EssentialsX/config.yml set 'announce-format: ""'.

Troubleshooting

Join messages duplicated (one from EssentialsX + one from AstroJoinLeave)

Cause: Both plugins are broadcasting.

Fix:

  • Disable EssentialsX's messages by setting 'announce-format' to empty in EssentialsX/config.yml.
  • Or disable AstroJoinLeave's broadcasts (set 'default.join' to empty string) and use Essentials' formatting.

First-join title appears for returning players too

Cause: Player data file got wiped or your world directory was reset.

Fix:

  • AstroJoinLeave tracks first-join via the player's UUID stored in plugins/AstroJoinLeave/seen-players.yml.
  • If you restored from a backup that did not include seen-players.yml, all players are 'new' again.
  • Restore seen-players.yml from your backup, or use the OfflinePlayer.hasPlayedBefore() Bukkit API (set 'use-bukkit-first-join: true' in config).

Group-specific message not applied — falls back to default

Cause: LuckPerms not installed, group name typo, or player's primary group differs from what you expect.

Fix:

  • Run /lp user <player> info to see primary group.
  • Make sure the group key in config.yml matches case-exactly.
  • If using multiple parent groups, the primary group is used (highest priority).

Discord webhook not firing on join

Cause: Invalid webhook URL, network blocked, or webhook deleted on Discord side.

Fix:

  • Test the webhook with: curl -X POST -H 'Content-Type: application/json' -d '{"content":"test"}' <your-webhook-url>.
  • Check the plugin log for HTTP errors (403 = deleted webhook, 401 = invalid token).
  • Confirm 'discord.enabled: true' in config.yml.

MiniMessage gradients show as raw <gradient:...> tags

Cause: Paper version below 1.18 or MiniMessage parsing disabled.

Fix:

  • Upgrade to Paper 1.18+.
  • Set 'minimessage-enabled: true' in config.yml (default is true on Paper 1.18+).
  • On older versions use legacy &color codes only.

FAQ

How do I disable join messages entirely?

Set the join, leave, and first-join messages to empty string '' in the default section. The plugin will short-circuit and not broadcast anything.

Will it preserve EssentialsX vanish behavior?

Yes. The plugin checks the vanish state via the Bukkit metadata 'vanished' (set by Essentials, SuperVanish, PremiumVanish). If true, no broadcast fires.

Can I have a different welcome title per LuckPerms group?

Yes. Inside each 'groups.<groupname>' block, add a 'first-join-title' subsection with title/subtitle/fade-in/stay/fade-out, exact same structure as the default.

Does the plugin persist seen-players across restarts?

Yes. plugins/AstroJoinLeave/seen-players.yml stores UUIDs of players who have triggered first-join. The file is loaded at startup and saved every 10 minutes plus on shutdown.

Can I trigger the first-join title manually for an existing player?

Yes — delete their UUID from seen-players.yml and run /astrojoin reload. Next join will trigger first-join. Useful for re-onboarding returning players.

How do sound effects work?

Each group config can have a 'sound' field set to a Bukkit Sound enum (BLOCK_NOTE_BLOCK_PLING, UI_TOAST_IN, ENTITY_PLAYER_LEVELUP). The sound plays for everyone online when the join message fires.

Does it work with offline-mode servers?

Yes. Player UUID detection uses Bukkit's getUniqueId() which works in offline mode (uses a deterministic hash of the username). First-join detection still works.

What is the cost of running this on a server with 200 players?

Tiny. Join/leave events fire only when a player actually joins/leaves, not on a tick. Message construction is a few string operations. Discord webhook POSTs are async (off the main thread).

Can I A/B test which first-join message converts better to retained players?

Not built-in, but you can: rotate two first-join messages weekly and compare /seen counts of new players who joined that week. We will add proper conversion tracking once we integrate with analytics.

What happens if Discord webhook URL is wrong or unreachable?

The plugin logs a warning but does not block the join. Join broadcast in Minecraft chat still happens normally.

Does it integrate with Geyser / Floodgate (Bedrock) players?

Yes. Floodgate players show up as normal Bukkit players with their .username field. The plugin uses standard Bukkit Player.getName() so Bedrock players get the same message treatment.

Can I disable the join message but keep the title?

Yes. Set the broadcast message to empty string but keep the first-join-title block populated. The title still fires.

Changelog

v1.0.02026-05-13

  • Initial public release
  • Per-LuckPerms-group join/leave messages
  • First-join title overlay
  • Optional Discord webhook for first-join pings
  • Vanish detection (auto-suppresses broadcasts)
  • MiniMessage gradient support on Paper 1.18+
  • Per-group sound effects
  • /jl reload and /jl silence commands