Skip to content

RankForge API Best Practices – Threads, Folia & Compatibility

Operation Thread Safety
get* (reading points, tiers, stats) Safe from any thread
setPoints, addPoints, removePoints Server thread only (main thread on Paper, region thread on Folia) because it dispatches synchronous events
saveAsync() Safe from any thread (returns CompletableFuture)
  • When calling mutation methods from async contexts, schedule onto the server thread using Bukkit.getGlobalRegionScheduler().execute(...) (compatible with both modern Paper and Folia).
  • getPlayerData() returns an active data instance that can be updated concurrently. Read needed values into local variables rather than storing long-lived object references.

getTier, getTierByPoints, and getNextTier return null for unranked players or players at the top tier.

Tier tier = api.getTier(player);
String name = tier != null ? tier.display : "Unranked";
  • Use softdepend: [RankForge] in plugin.yml.
  • Isolate RankForge-dependent code into dedicated bridge classes to prevent NoClassDefFoundError when RankForge is absent.
  • Check RankForgeAPI.isAvailable() before calling RankForgeAPI.get().

4. Rely Exclusively on Public API Packages

Section titled “4. Rely Exclusively on Public API Packages”

Only classes inside xyz.noxlydev.rankforge.api.* and xyz.noxlydev.rankforge.model.* are public and guaranteed stable. Internal packages are obfuscated with ProGuard and may change without notice.

Never invoke addPoints or setPoints within a PlayerPointsChangeEvent handler. Use event.setNewPoints(...) instead to alter values.