Custom Tasks
A task is one round challenge: an instruction shown to players and a condition
that decides who passes. Build them with the fluent TaskBuilder and register them
from your addon.
Quick start
import dev.blancocl.simonSays.api.TaskBuilder;
TaskBuilder.create("my-task") .instruction("<yellow>Do something!</yellow>") // MiniMessage .weight(5) // selection weight .onStart((game, gp, ctx) -> { // when the round starts ctx.put("target", randomLocation); ctx.addCleanup(() -> removeProp()); // undone when the round ends }) .check((game, gp, ctx) -> { // evaluated every tick Location target = ctx.get("target"); return gp.bukkit().getLocation().distance(target) < 3; }) .register(); // survives /ss reloadBuilder methods
| Method | Description |
|---|---|
create(String id) | Start a builder with a unique task id. |
.instruction(String) | The MiniMessage instruction shown to players. |
.weight(int) | Selection weight — higher is picked more often (default 5). |
.onStart(Setup) | Runs when the round starts: spawn props, pick targets, store state with ctx.put(...), register undo with ctx.addCleanup(...). |
.check(Check) | Per-player pass condition, sampled every tick. |
.evaluateAtEnd() | Evaluate only when the window closes (e.g. “don’t move”). |
.passWhenMarked() | Pass when your listener calls ctx.complete(uuid). |
.disabled() | Register the task disabled. |
.build() | Build the Task without registering it. |
.register() | Build and register with SimonSays. |
Evaluation modes
| Mode | Behavior |
|---|---|
.check(...) (default) | Latch — passes if the condition held at any tick during the window. |
.evaluateAtEnd() | Evaluated only when the window closes — for “hold it until the end” tasks like don’t move or keep sneaking. |
.passWhenMarked() | Passes when your own listener calls game.currentContext().complete(uuid). |
Round context (ctx)
The context object passed to onStart and check carries per-round state:
ctx.put(key, value)/ctx.get(key)— store and read round state.ctx.addCleanup(Runnable)— register an undo action run when the round ends.ctx.complete(uuid)— mark a player as having passed (forpassWhenMarked).ctx.completed(uuid)— whether a player has been marked.
Examples
A self-contained task using built-in player state:
TaskBuilder.create("fly-high") .instruction("<aqua>Get above Y <yellow>120</yellow>!") .check((game, gp, ctx) -> gp.bukkit() != null && gp.bukkit().getY() > 120) .register();An event-driven task that your own listener completes:
TaskBuilder.create("double-punch") .instruction("<yellow>Punch the air twice!</yellow>") .weight(6) .passWhenMarked() .register();