English
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/uninstalland theBridgeinterface 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:
| Method | Returns | Description |
|---|---|---|
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
| Method | Returns | Description |
|---|---|---|
getMultiblockId() | String | The triggered multiblock definition id |
getPlayer() / getPlayerId() | Player / UUID | The triggering player (never null) |
getWorldName() | String | World name holding the structure anchor |
getX() / getY() / getZ() | int | Anchor block coordinates |
getFacing() | String | Facing 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 whilecatalog()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