- player-load: load-on-join (PlayerReadyEvent → IO → modify). - async-moderation: IAsyncEvent → coroutine bridge for chat moderation. - periodic-leaderboard: pluginScope loop with parallel reads. - bounty-board: kitchen-sink demo exercising every v0.1 primitive.
2.0 KiB
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-SNAPSHOT") 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.