Skip to content

v5 NmsAPI

Jake Moore edited this page Aug 31, 2026 · 6 revisions

NmsAPI

⚠️ Usage ⚠️

Available in spigot-utils and its inheritors (spigot-jar).

NmsAPI is the entry point for everything version-specific. It is a static facade: there is no instance to obtain and no initialisation to perform. Behind it, KamiCommonNMS ships an implementation for every supported Minecraft version and picks one by name at runtime, so your code never contains a version check.

ItemStack held = NmsAPI.getItemInMainHand(player);
NmsAPI.getTeleporter().teleportWithoutEvent(player, location);

What it exposes

Text. See Text and Components.

VersionedComponentSerializer getVersionedComponentSerializer();   // new in v5
ComponentLoggerAdapter       getComponentLoggerAdapter();         // new in v5

Items

AbstractItemEditor getItemEditor();       // display name, lore, unbreakable, damage, durability
NmsItemMethods     getNmsItemMethods();
AbstractItemTextPre_1_17 getItemText();

ItemStack getItemInMainHand(Player);
void      setItemInMainHand(Player, ItemStack);
ItemStack getItemInOffHand(Player);       // null below 1.9
void      setItemInOffHand(Player, ItemStack);   // throws UnsupportedOperationException below 1.9

World and blocks

AbstractBlockUtil getBlockUtil();         // fast block setting, XBlockData
NMSWorld          getNMSWorld(World);
AbstractTeleporter getTeleporter();

Entities, packets, commands, misc

AbstractEntityMethods  getEntityMethods();
NMSPacketHandler       getPacketHandler();
CommandMapModifier     getCommandMapModifier();
AbstractMessageManager getMessageManager();
Color                  getJavaColor(ChatColor);
String                 getNamespaced(Enchantment);

Version information

NmsVersion.getMCVersion();             // e.g. "1.20.4"
NmsVersion.getFormattedNmsInteger();   // a comparable integer, see below
NmsVersion.isWineSpigot();

getFormattedNmsInteger() encodes the version so it can be compared with < and >:

  • 1.x versions keep their v4 encoding exactly: 1.8 → 1080, 1.8.8 → 1088, 1.20.4 → 1204, 1.21.10 → 12110. Every threshold you already wrote still works.
  • Calendar versions, meaning major 2 and above, use major*10000 + minor*100 + patch: 26.2 → 260200, 26.1.2 → 260102.

⚠️ The second rule is new in v5. The old formula gave 26.2 → 2620, which sorted below 1.21.11 → 12111. If you stored a v4-computed number for a calendar version, recompute it.

Trailing non-numeric components are tolerated, because Paper 26.x reports its version as 26.2.build.115-stable.

Diagnostics

  • /kc nmsversion reports the detected version and its formatted integer
  • /kc nmsproviders reports which implementation resolved for each capability
  • /kc nmstest runs the checks that need a player
  • /kc texttest asserts on what VersionedComponent emits on this server

/kc texttest covers the whole VersionedComponent surface: the factories, the serializers, hovers, clicks, decorations, append, the ItemMeta round trip, createInventory and hex colours. Each case builds a component, takes the form this server's tier actually sends, and asserts on the structural shape the receiving end reads rather than on payload text appearing somewhere.

From the console it writes one [texttest] PASS <case> or [texttest] FAIL <case>: <reason> line per case, and closes with a [texttest] RESULT: line carrying the counts, the server version and the tier that handled it. Failures are logged at SEVERE, so a script can drive the command across a version matrix and read the outcome back. Expectations are keyed on the implementation class the server dispatched to, and a tier with no declared expectations is reported as a failure rather than skipped.

Run by a player, it also sends the same components to that player, for the one question a wire assertion cannot answer, which is whether the client draws them. Cases that cannot apply on the running version, such as COPY_TO_CLIPBOARD below 1.16, are named as unavailable instead of sent.

What is public API

Roughly 60 types are marked @ApiStatus.Internal, including ShimLoader, TextBundles, NmsBundles, the version providers, and every concrete VersionedComponent_*. They are dispatch targets resolved by string. They are public because the loader needs them to be, not because you should call them. They can be renamed, split or moved between modules without a major version bump.

Two interfaces are deliberately not marked internal, because they are the extension points for writing your own version module:

  • NmsBundle is the entry point into one version implementation. Every capability is a default method that throws, so a module implements only what it ships.
  • TextBundle is the text boundary interface.

Do not relocate com.kamikazejam.kamicommon.nms.bundle.* or com.kamikazejam.kamicommon.nms.text.TextBundleImpl_* when shading. The lookup is by string name.

Removed since v4

removed replacement
NmsAPI.getEventManager(), getEventManagerProvider(), and the EventManager interface none. See the Migration Guide
nms.util.data.MaterialData XMaterialData, but it is not a rename
nms.abstraction.entity.EntityMethodsPre_1_13 still shipped, but no longer part of the documented API. getSpawnerType and setSpawnerType are on AbstractEntityMethods

Clone this wiki locally