Skip to content

Public API

Compile-time dependency

xml
<repositories><repository><id>jiuwu-releases</id><url>https://repo.crypticlib.com/repository/maven-public/</url></repository></repositories>
<dependency><groupId>emaki.jiuwu.craft</groupId><artifactId>emaki-item-api</artifactId><version>2.7.16</version><scope>provided</scope></dependency>
kotlin
repositories { maven("https://repo.crypticlib.com/repository/maven-public/") }
dependencies { compileOnly("emaki.jiuwu.craft:emaki-item-api:2.7.16") }

Compile only — never install, shade, or relocate this jar

EmakiItem embeds the same un-relocated classes. Duplicating them breaks Bukkit event delivery and bridge identity.

Use EmakiItemApi.status().usable(). Non-null layers are catalog(), operations(), repair(), experimental migration(), extensions(), and state(). install, uninstall, and Bridge are internal.

operations().create(id, amount) must run on the global-region owner thread and fires the synchronous cancellable EmakiItemCreateEvent before returning; a veto becomes FailureKind.CANCELLED. Refresh methods obey their update policies; player and set refresh use the player owner thread. openRepairGui returns EmakiResult<Unit>.

repair() owns disabled flags, economy repair quotes, and economy repair(player, item). Quotes can be successful but unaffordable; repair performs the event, charge, compensation, durability commit, and post actions. Material repair remains a GUI/inventory transaction rather than a fabricated convenience API.

Experimental migration() provides worker-thread filesystem preview/apply, player-owner migrateInventory, and current-thread-owned migrateAllOnline; partial results preserve changed work when a batch cannot fully complete. extensions() registers owner-scoped item-layer preview providers.

state() is the typed read/write layer for custom persistent item state, addressed by ItemStateKey<T> (namespace + partition + field name + ItemStateType). snapshot(item) returns an immutable ItemStateSnapshot supporting get(key), contains(key), and repaired(), with item() handing back a clone; repair(item) repairs metadata and reads the snapshot back. get(item, key) returns Optional<T> and is empty on a type mismatch. set(item, key, value), add(item, key, amount), and remove(item, key) return ItemStateMutation<T> carrying oldValue, newValue, delta, plus committed, changed, clamped, rejected, and reason, so clamping and rejection are readable from the result instead of thrown.

Use Success, Partial, Failure, and optionalValue(). Failure kinds are UNAVAILABLE, NOT_FOUND, INVALID_INPUT, REJECTED, CANCELLED, TARGET_OFFLINE, WRONG_THREAD, INTERNAL_ERROR.

Readiness and reload

status().ready() means "definitions are loaded", not "components were constructed". The components are non-null as soon as the plugin enables, but the definition table is rebuilt during a reload, so:

  • Inside a reload window status() reports loading and every EmakiResult-returning method on catalog(), operations(), repair(), and migration() returns unavailable() rather than NOT_FOUND. Treat unavailable() as "retry shortly", not "no such item".
  • definitionIds(), exists(id), and typeIds() cannot express unavailability and may return stale or empty results during a reload. When you must act only on loaded definitions, use EmakiCoreLibApi.whenReady(plugin, "EmakiItem", callback) instead of inferring absence from an empty result.
  • A plugin that caches EmakiItem definitions should refresh them after every reload via EmakiCoreLibApi.addModuleListener(plugin, "EmakiItem", phase -> ...): invalidate on LOADING, rebuild on READY. whenReady fires only once and is not suited to this.

A plugin that depends on EmakiItem definitions at startup should hook whenReady rather than querying the table directly in its own onEnable: module load order does not guarantee EmakiItem's first load happens before your onEnable. The callback fires once, and the thread it runs on is not guaranteed to be an owner thread, so schedule explicitly before touching players or inventories.