PlayerWarpSlots¶
Sets how many PlayerWarps each player may own on main, by adding their donor rank's free slots to
any extra slots they bought. Ranks can change or lapse without anyone losing a purchased slot.
What it does¶
PlayerWarps 5.0.0 only understands absolute limit nodes like playerwarps.limit.5, and it uses the
highest one a player has. Two nodes never add up. This plugin makes rank slots and bought slots
add together:
- Rank floor. A rank group holds one
playerwarps.floor.<n>node. Floors are held, not owned: if a player has several, the highest counts, and it goes away when the rank does. - Purchased bonus. Each buyer holds one
playerwarps.bonus.<n>user node in LuckPerms. It is saved for good and survives any rank change. - The plugin works out
total = min(max-total-slots, highest floor + bonus)and gives the online playerplayerwarps.limit.<total>. PlayerWarps reads that node. - It re-checks a player when they join and whenever LuckPerms recalculates their permissions (a rank bought, changed, or expired). If the total has not changed, it changes nothing.
Live floors on main: rank1 gets 1, rank2 gets 3, rank3 gets 5. Rank 4 and 5 inherit
rank3's 5. Unranked players get 0 from PlayerWarps' default-limit-size: 0.
Example: a rank2 player (floor 3) who bought 2 slots can own 5 warps.
How players use it¶
- Get warp slots by buying a donor rank, by buying extra warp slots in the store, or both.
- Make a warp with PlayerWarps as usual (
/pwarp). Creating and managing warps is free. Past the limit, PlayerWarps refuses the new warp.
Bought slots add on top of the rank. If a rank lapses, the rank slots go away but bought slots stay. A store purchase shows up within a moment if the player is online, or on their next join.
Staff guide¶
All commands need playerwarpslots.admin (ops by default). Console works, and the store uses it.
The player must have joined the server at least once.
| Task | Command |
|---|---|
| See a player's rank floor, bought slots and total | /pwarpslots info Steve |
| Add bought slots (store fulfilment) | /pwarpslots add Steve 1 |
| Take bought slots away (refunds, chargebacks) | /pwarpslots remove Steve 1 |
| Set bought slots to an exact number | /pwarpslots set Steve 3 |
| Clear all bought slots | /pwarpslots set Steve 0 |
- Store command. The store runs
pwarpslots add <player> 1per slot sold. It adds to what the player already has, so repeat purchases stack. addandremoveneed an amount of 1 or more.removenever goes below 0.setaccepts 0.- A bonus above
max-total-slots(100) is refused withRefusing bonus .... - Every change is saved to LuckPerms and logged with the action, amount, and who ran it, for
example
Steve now has 2 purchased PlayerWarp slot(s), total 5. Action=add, requested=1, executor=CONSOLE.inforesults are logged too. - Run from RCON? RCON can drop the reply because it arrives a moment later. Check the server log for the result line instead.
Give a rank warp slots. Give the rank group one floor node. Set it to the total slots that rank should have alone, not an increase:
/lp group rank1 permission set playerwarps.floor.1 true
/lp group rank2 permission set playerwarps.floor.3 true
/lp group rank3 permission set playerwarps.floor.5 true
A rank3 player who also inherits rank1 and rank2 gets 5, not 9.
Never grant playerwarps.limit.N to a group or user. PlayerWarps takes the highest limit node,
so a hand-granted limit does not add to the plugin's total. It just replaces it whenever it is
higher, with no error. Use a floor node (ranks) or /pwarpslots (purchases).
Do not hand-edit playerwarps.bonus.N nodes. Use /pwarpslots so the change is logged and the
player's limit updates right away.
Testing. Test as a non-op. PlayerWarps gives ops unlimited warps, so the limit can never be hit as an op.
Configuration¶
plugins/PlayerWarpSlots/config.yml. There is no reload command, and the file is read only at
startup, so a change goes live on the next server restart. scripts/reload_or_restart.sh has
no row for this plugin, so its default (restart) applies.
| Key | Default | What it is for |
|---|---|---|
floor-prefix |
playerwarps.floor. |
The rank floor node ladder |
bonus-prefix |
playerwarps.bonus. |
The purchased bonus node |
effective-limit-prefix |
playerwarps.limit. |
What PlayerWarps reads. Change only if PlayerWarps changes |
max-total-slots |
100 |
Cap on the total, and the largest bonus a command may set. Guards against a bad store command |
Rules the plugin enforces at startup: each prefix must be non-empty and end in ., the three
prefixes must be different, and max-total-slots must be at least 1. If not, it logs
Invalid config: ... and turns itself off.
The rank floors and PlayerWarps' own settings (default-limit-size: 0, free creation) live in
LuckPerms and in PlayerWarps' config, not here.
Data and storage¶
This plugin has no files or tables of its own besides config.yml.
- Bought slots are one LuckPerms user node per player,
playerwarps.bonus.<n>. This is the only record of a purchase. Do not delete it unless you mean to remove the slots. - Floors are LuckPerms group nodes
playerwarps.floor.<n>that staff set. - The limit node
playerwarps.limit.<total>is a temporary in-memory Bukkit permission, not a LuckPerms node. It will not show in the LuckPerms editor. It is rebuilt on every join, so it is safe to lose. Use/pwarpslots infoto see it. - The warps themselves belong to PlayerWarps.
Troubleshooting¶
| Symptom | Cause | Fix |
|---|---|---|
| A ranked player gets 0 or too few warps | The rank has no floor node, or LuckPerms has not picked up a database change | /pwarpslots info <player>. If the floor is 0, add the floor node. If it was just written to the database, run /lp sync |
| A ranked buyer has fewer warps than floor plus bonus | Someone granted playerwarps.limit.N directly |
Remove that node and use a floor or bonus instead |
| Store sale went through but the warp count did not move | The command failed, the name was wrong, or the player never joined | Check the server log for now has ... purchased or Unknown player. Re-run /pwarpslots add <player> 1 |
| An op tester can make endless warps | PlayerWarps gives ops unlimited warps | Test as a non-op |
| Total stuck at 100 | The max-total-slots cap |
Expected. Raise the cap and restart if that is really wanted |
| Plugin is disabled at boot | LuckPerms is missing, or the config is invalid | Read the error line below and fix it |
Boot log line when it is working:
[PlayerWarpSlots] PlayerWarp slot arithmetic active: floor + purchased bonus -> playerwarps.limit.N (ceiling 100)
Error lines:
LuckPerms is unavailable; slot purchases cannot be resolved.LuckPerms did not load. The plugin turns itself off.Invalid config: ...A config rule above was broken. The plugin turns itself off.
Maintainer notes¶
- The 1.0.0 crash. Giving a player the limit node changes their permissions. That makes
LuckPerms fire
UserDataRecalculateEvent, which is what asks for a re-check. In 1.0.0 this was an endless loop that spun the server thread until the watchdog killed the server on player join. The 1.0.0 jar onmainis renamed.disabled-20260828-034301. Do not restore it. - The three brakes (1.0.1,
ReconcileGate). At most one queued check per player. A check that would grant the node the player already has changes nothing, so no new event fires and the chain ends. A check that is already running cannot start again.ReconcileGateTestcovers this. - Reads LuckPerms' cached permission map, not
Player#getEffectivePermissions(), which builds a wrapper object for every inherited node on each call. It falls back to the Bukkit view only if the LuckPerms user is not loaded. - The bonus is one node, replaced, not stacked.
addreads the current bonus from the user's own nodes, removes everyplayerwarps.bonus.*node, and writes one new global node. So the count is never split across many rows. - Ceiling check covers the bonus only. Commands refuse a bonus above
max-total-slots, but do not count the floor. Floor plus bonus is then silently capped at the ceiling. With today's floors (max 5) and cap (100), that gap does not matter. - Group bonus nodes. A
playerwarps.bonus.Non a group would count toward the live total, butinfowould report "purchased 0", andaddwould ignore it. Keep bonus nodes on users only. - Number suffixes are parsed strictly: anything that is not plain digits, or is over 1,000,000, counts as 0.
- The floor plus extras rule is the same one VaultTickets uses for vault pages and
pixelmonbridgeuses for PC boxes. It is a deliberate copy, not a shared library. - Ops docs:
documentation/operations/donor-ranks-1-2-3.md(item B5) and the PlayerWarps sections ofdocumentation/operations/workflow-playbooks.mdin the ops repo.
Building¶
./gradlew clean test jar
Java 21, built against Paper API 1.21.1 and LuckPerms API 5.4. Output:
build/libs/PlayerWarpSlots-1.0.1.jar. Runs 18 unit tests on the slot math and the loop brakes.
Jars are built with fixed timestamps and file order, so they are byte-reproducible.
Full command, permission and config tables: Reference.