Skip to main content

Utilities

Besides the framework itself, VersatiaAPI ships a set of independent helpers over the Paper API. Server-wide calls start at one class, VersatiaEngine; everything else is an extension on the object you already hold, grouped under dev.versatia.util by the domain it touches.

Start with VersatiaEngine.​

Work that needs no object at hand, such as finding a player, broadcasting or looking up a service, is a static call on VersatiaEngine: one class to remember. Type VersatiaEngine. and pick from completion; IntelliJ adds the import (import dev.versatia.broadcast).

VersatiaEngine.broadcast(text("The shop is open"))
VersatiaEngine.playerOrNull("Notch")?.sendMessage(text("Welcome back"))
val economy = VersatiaEngine.loadService<Economy>()
VersatiaEngine.reload("shop")
MemberDoesInstead of
registrythe running Versatia plugins by friendly name, a PluginRegistryVersatiaEngine.instance.registry
reload(name)reloads the plugin registered as name, as /versatia reload <name> does; an unknown name fails and lists the running onesa registry lookup and instance.reload(plugin)
onlinePlayersthe online playersBukkit.getOnlinePlayers()
playerOrNull(name)the online player with exactly this name, ignoring case; never the prefix match of Bukkit.getPlayer(String)Bukkit.getPlayerExact(name)
playerOrNull(id)the online player with this UUIDBukkit.getPlayer(id)
offlinePlayer(id)the player behind a UUID, online or not; never null, never a web lookupBukkit.getOfflinePlayer(id)
worldOrNull(name)the world with this nameBukkit.getWorld(name)
broadcast(message), broadcast(message, permission)sends a Component to every player and the console, or to everyone holding permission; returns the number of recipientsBukkit.broadcast(...)
dispatchConsoleCommand(line)runs a command, without the slash, as the console; off the main thread it throws IllegalStateExceptionBukkit.dispatchCommand(Bukkit.getConsoleSender(), line)
loadService<T>(), loadServiceOrNull<T>()the provider registered for T in the ServicesManager; ServiceNotRegisteredException names the service when there is noneBukkit.getServicesManager().load(...)
isPrimaryThread(), checkPrimaryThread(action), checkNotPrimaryThread(action)where the code runs; the checks throw IllegalStateException on the wrong thread, naming the optional action and the scheduler call that fixes itBukkit.isPrimaryThread()

Work on something you already hold is a call on that object, not on VersatiaEngine:

TaskWhere
run work over timea BackgroundTask or scope.launch { }, see Tasks and coroutines
schedule a plain Bukkit taskplugin.runTaskLater(20) { }, see Scheduler
loglogger or componentLogger in the plugin, plugin.log elsewhere
reload your own pluginversatiaReload(), see Reloading plugins
message one playerplayer.sendMessage(...)
run a command as a playerplayer.performCommand(...)
fire an eventevent.callEvent()
read configuration@Value and the strict getters
provide a serviceserver.servicesManager.register(...) in the providing plugin
check for an optional plugin@ConditionalOnPlugin
inventories, boss bars, block datathe Bukkit factories

Members that call Bukkit work in any plugin; registry and reload need VersatiaCore enabled. In a bean, take the plugin or the PluginRegistry as a constructor parameter instead of reaching for VersatiaEngine.registry: it keeps the bean testable. The shortcuts are Kotlin extensions on the companion of VersatiaEngine; from Java, use VersatiaEngine.getInstance() and Bukkit.

Helpers by package​

PackageContentsPage
configstrict typed getters for ConfigurationSection, Duration and Secret included, YAML file traversalConfiguration
collectionaddOrThrow/putAllOrThrow-style helpers, DeepMergeMap, List.cycleCollections
pluginPlugin.log, logWarning, logSevereScheduler, logging and more
schedulerPlugin.runTask* wrappers over BukkitScheduler, for plain Bukkit tasks; tasks come firstScheduler, logging and more
validationvalidateAtLeast-style guards that return the receiverScheduler, logging and more
reflectaccess to private members through kotlin-reflectScheduler, logging and more
inventoryItemStack and Inventory helpers, raw player-inventory slot indicesScheduler, logging and more
worldLocation helpers, isWithin among themScheduler, logging and more
langenum lookups ignoring caseScheduler, logging and more
textsubscript and superscript digitsScheduler, logging and more
typesmall value types Percent and SecretScheduler, logging and more

None of the helpers needs VersatiaCore's runtime; they are plain Kotlin extension functions and small types. Everything in VersatiaAPI without a visibility modifier is part of the contract; return types are written out only where the compiler could not infer a precise one, such as helpers over Bukkit getters.