Skip to content

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 reload

Builder methods

MethodDescription
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

ModeBehavior
.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 (for passWhenMarked).
  • 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();