Public API
Compile-time dependency
<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>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()reportsloadingand everyEmakiResult-returning method oncatalog(),operations(),repair(), andmigration()returnsunavailable()rather thanNOT_FOUND. Treatunavailable()as "retry shortly", not "no such item". definitionIds(),exists(id), andtypeIds()cannot express unavailability and may return stale or empty results during a reload. When you must act only on loaded definitions, useEmakiCoreLibApi.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 onLOADING, rebuild onREADY.whenReadyfires 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.