Examples
Four runnable plugin sketches built as Gradle composite builds — they
consume the in-development library directly via includeBuild("../.."),
so editing the lib and rebuilding an example picks up the change without
publishing.
| Example | Pattern |
|---|---|
player-load/ |
Load player JSON on PlayerReadyEvent, mutate a component on the world thread. |
async-moderation/ |
IAsyncEvent (PlayerChatEvent) bridged to coroutines, off-thread check, conditional modify + event cancel. |
periodic-leaderboard/ |
Plugin-scoped periodic loop with parallel read over players. |
bounty-board/ |
The kitchen sink — exercises every public Async primitive. |
Build any of them
cd examples/<name>
./gradlew shadowJar
# → build/libs/<name>.jar
Drop the JAR in your dev server's mods/.
How the composite wiring works
Each example's settings.gradle.kts does:
includeBuild("../..") {
dependencySubstitution {
substitute(module("com.mythlane:async"))
.using(project(":dist"))
}
}
So implementation("com.mythlane:async:0.1.0") resolves to the
local :dist project — no Maven publication required during dev.
What's stubbed
Each example contains TODO() markers in two places:
-
Custom
Component<EntityStore>registration. DeclaringWallet,PlayerStats, etc. onEntityStore.REGISTRYis plugin-specific and not part of what Async does. Async only consumes the resultingComponentTypeviaComponentRegistry.register<T>(...). -
Online-player accessors like
onlinePlayerRefs()andbroadcastToAllWorlds(...). These iterateUniverse.get()/world.playersin whatever shape your plugin needs.
Wire those to your dev server and the examples become fully runnable. The
Async-side calls (installAsync(), playerScope, modify<T>,
PlayerRef.toEntityHandle(), etc.) are accurate as-shipped.