Files
purpur-quest-board/README.md
T
dmg 7496564b94
CI / build (pull_request) Successful in 49s
CI / build (push) Successful in 1m7s
feat(platform): support Purpur 26.3
2026-10-16 23:49:39 -04:00

6.7 KiB

Purpur Quest Board

A Purpur 26.3 plugin for shared physical quest boards. Players can escrow rewards for item deliveries or player bounties, fulfill them, and collect exact rewards through shared boards.

The approved behavior is specified in the SoMC OKF wiki.

Status

Administrators can register persistent shared quest boards by targeting a block within five blocks and running /questadmin createboard. They can instead run /questadmin createboard physical to generate a five-wide oak board above the targeted ground anchor, with glowing centered title and browsing-instruction signs above three decorative signs; its visible panel blocks and all five signs are registered. Right-clicking any registered board opens a compact native dashboard with dedicated browsing, creation, and claim screens. A player can request any inventory item material and quantity while escrowing the exact reward stack held in their main hand. Every board and /quests list show the same active quests with requested items, rewards, issuers, and time remaining; custom reward names are shown together with their material type. Players can complete quests at any board or with /quests complete <quest> by delivering the required items. After durable completion, exact escrowed rewards are delivered to the hunter (or retained for collection if delivery cannot proceed), and delivered items are held for the issuer. Issuers can cancel their own active quests at any board or with /quests cancel <quest>. Completed deliveries and rewards from cancelled or seven-day-expired quests are held durably and can be collected at any board or with /quests claim; inventory overflow drops at the claimant's feet.

Player bounties

At any registered board, choose Create bounty, enter a player name or UUID and a positive kill count, and hold the exact reward stack until target resolution finishes. Online, cached and asynchronously resolved offline targets are supported. Boards work even with player commands disabled; posting bounties uses the board, not a new command.

  • Each hunter has separate UUID-based progress. The first to reach the full count earns the whole reward; the issuer cannot win.
  • Only actual, non-cancelled deaths attributed by the server to a player count, including credited projectiles. Bounties never enable PvP or bypass protections.
  • Browse shows target identity, your progress, exact named reward and remaining time. Earned bounty rewards appear separately in Pending claims.
  • Issuers may cancel unfinished bounties, even after partial progress. Cancellation or seven-day expiry returns unpaid escrow; no partial payouts.
  • There is no added kill cooldown, anti-collusion rule or target-consent gate. Existing server conduct rules remain authoritative.

Persistence and recovery

Quest/bounty/claim persistence runs on a serialized worker; Bukkit inventory and dialog operations run on the server thread. Existing delivery quests and claims are preserved. Native-callback, death-attribution, restart, failure and lifecycle paths are automated-tested; this does not claim live-server verification.

Inventory and YAML are not crash-atomic. A durable transfers journal reserves payouts before inventory delivery and acknowledges known outcomes afterward. Interrupted RESERVED transfers are quarantined, never automatically paid again. Players see recovery guidance; administrators must reconcile the exact owner/items against inventory and server records before any repair. Preserve quests.yml, player data and recovery logs; stop the server before a separately reviewed repair. Do not indiscriminately delete reservations or replay them: delivery may already have occurred.

Controlled input-save failures return the exact items without overwriting unrelated inventory changes. Offline/failed returns are retained for collection; unresolved disk failures emit recovery records and an explicit INCOMPLETE shutdown result. Keep those logs private: they contain player UUIDs and exact item data needed for recovery. Permanently unavailable storage, forced termination and the input-removal-before-save crash window cannot be made loss-proof by this file-based plugin.

A canonical-path ownership lock prevents a replacement runtime from loading a stale snapshot while accepted work drains. Do not delete quests.yml.owner.lock while a runtime is active. Unresolved hot reload is rejected rather than discarding recovery. Orderly shutdown closes main-thread callbacks, drains worker recovery and has a bounded 30-second JVM shutdown wait; it does not protect against SIGKILL, forced halt or indefinitely hung storage.

Back up before upgrade. Do not run an older plugin against new bounty/transfer state. Old binaries neither preserve these records nor honor the new lock; rollback requires a reviewed state-reconciliation/restore plan, not merely swapping the JAR.

Distribution migration

The repository, checkout and new JARs use purpur-quest-board. Runtime SpigotQuestBoard, Java entrypoint/packages, data folder/namespace, commands, permissions and existing board/quest/escrow/claim data remain unchanged. Replace the old JAR instead of installing both distributions. Historical tags and spigot-quest-board-* assets are retained; the previous v1.12.0 download was verified byte-for-byte after renaming.

Requirements

  • Purpur 26.3 build 2651
  • Java 25

Build

./gradlew clean check jar

The plugin JAR is written to build/libs/. The verification task downloads the fixed Purpur 26.3 build 2651 runtime, verifies SHA-256 0677c1febecfbc2e5b0a7f76abd647b70a1f38d3cbdf3dd6a82e401b4262a598, and starts an isolated server to prove plugin load, enable, and orderly disable. Mock/API tests remain separate coverage for dialogs, boards, escrow, claims, persistence, and ownership locking.

Player commands

Player commands are disabled by default and can be enabled persistently by an administrator. When disabled, players within five blocks of a registered board can still use /quests create <item> <quantity> with material and quantity autocomplete; other player command forms remain disabled.

/quests
/quests list
/quests create ...
/quests complete <quest>
/quests cancel <quest>
/quests claim

Administration

The spigotquestboard.admin permission is granted to server operators by default.

/questadmin createboard
/questadmin createboard physical
/questadmin commands <enable|disable>

Releases

Gitea Actions checks pushes and pull requests and stores a development JAR. Pull requests validate conventional commits. Main-branch conventional commits drive semantic releases when the repository defines a RELEASE_TOKEN with contents-write permission.