Skip to content

API & Integration ​

Third-party plugins reach EmakiStructure through emaki-structure-api (current version 1.0.1). The API jar is a compile-time dependency only; the matching runtime artifact is EmakiStructure-1.0.5.jar

Maven coordinates ​

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-structure-api</artifactId>
  <version>1.0.1</version>
  <scope>provided</scope>
</dependency>
kotlin
repositories { maven("https://repo.crypticlib.com/repository/maven-public/") }
dependencies { compileOnly("emaki.jiuwu.craft:emaki-structure-api:1.0.1") }

Compile-only dependency

Each runtime jar already embeds the API classes unrelocated. Never install, bundle, shade, or relocate the API jar; a duplicate ClassLoader identity breaks events and bridges

The EmakiStructureApi facade ​

The static facade exposes exactly two query entry points, and the accessors never return null:

java
// Availability and identity metadata; notInstalled while EmakiStructure is absent
var status = EmakiStructureApi.status();

// Structure template catalog; an empty-answer implementation when absent
// (an empty answer does not mean the plugin is absent — combine with status ())
var catalog = EmakiStructureApi.catalog();
  • install / uninstall and the Bridge interface are marked internal / non-extendable — do not call or implement them
  • Resolve accessors at the point of use rather than caching them in a field: a reload replaces the backing bridge
  • status().usable() is the standard way to check whether the bridge is usable

StructureCatalog queries ​

Read-only snapshots, safe from any thread, all returning unmodifiable copies:

MethodReturnsDescription
registeredIds()Set<String>Every currently loaded template id
template(String)Optional<StructureTemplateView>The view for that id, empty when not loaded

StructureTemplateView is an immutable record with fields id, sizeX, sizeY, sizeZ, blockCount. Coordinates are template-local ((0,0,0) is the minimum corner of the bounding box) and carry no world or BlockData references, so instances are safe to hold across threads

Events ​

MultiblockTriggerEvent ​

emaki.jiuwu.craft.structure.api.event.MultiblockTriggerEvent — fired when a multiblock structure passes its condition and cooldown checks, right before the configured actions run

MethodReturnsDescription
getMultiblockId()StringThe triggered multiblock definition id
getPlayer() / getPlayerId()Player / UUIDThe triggering player (never null)
getWorldName()StringWorld name holding the structure anchor
getX() / getY() / getZ()intAnchor block coordinates
getFacing()StringFacing in config form: north/east/south/west plus _mirror variants
  • Informational and non-cancellable: cancelling it has no effect on action execution
  • Fired on the thread that handled the interaction; on Folia, the region thread owning the clicked block
java
@EventHandler
public void onMultiblockTrigger(MultiblockTriggerEvent event) {
    if ("teleporter".equals(event.getMultiblockId())) {
        log(event.getPlayerId() + " triggered the portal at "
            + event.getWorldName() + " " + event.getX() + "," + event.getY() + "," + event.getZ());
    }
}

Threading and lifecycle ​

  • Facade queries are safe from any thread; the event callback runs on the thread that handled the trigger, so schedule players/world/inventory access onto the right owner thread yourself
  • During a module reload status() reports loading while catalog() still answers with snapshots; never interpret "empty catalog" as "template does not exist"
  • With EmakiStructure absent, first touching the API classes carries a linkage-failure risk — isolate the call and catch LinkageError | RuntimeException