Behavior composition
Combine SoulFire tasks into scoped TypeScript and Python Effect workflows.
Behavior combinators build application workflows. They choose the next action while durable tasks manage movement, combat, inventory, and survival timing.
Build a workflow
This workflow gathers logs, retries a bounded build, and guarantees cleanup:
import {
cleanup,
collectBlocks,
retry,
sequence,
} from "@soulfiremc/sdk";
const prepareShelter = cleanup(
sequence(
collectBlocks({
blockIds: [],
tags: ["minecraft:logs"],
count: 16,
}),
retry(buildShelter, {
attempts: 3,
delayMs: 500,
backoff: 2,
}),
),
releaseTemporaryClaims,
);
const results = yield* prepareShelter.run(bot);sequence preserves result order and stops at the first failure. Prefer a
durable server task inside each behavior instead of a client-side loop of
atomic movement calls.
Choose a combinator
| Combinator | Use it when |
|---|---|
sequence | Every step must run in order |
parallel | Run independent work at the same time |
race | Return the first successful strategy |
repeat | Run a step a fixed number of times |
retry | Retry a temporary error |
timeout | Work needs a hard application deadline |
until | Repeat until a result satisfies a predicate |
conditional | Choose a branch from current state |
fallback | Try alternatives in order until one succeeds |
cleanup | A finalizer must run after success, failure, or cancellation |
scopedLease / scoped_lease | A workflow needs exclusive bot control |
Both SDKs run parallel behaviors in scoped fibers with bounded concurrency. A failure interrupts sibling work and waits for cleanup.
race means first successful result. A failed contender does not end the race
while another contender can still succeed. The runtime interrupts losing fibers and waits for their cleanup.
Bound retries
Always give retries a finite attempt count. Delay and backoff are optional:
const resilient = retry(operation, {
attempts: 5,
delayMs: 250,
backoff: 2,
maximumDelayMs: 4_000,
});Interruption stops retries and cancels the active operation.
Retry and fallback handle typed failures. Defects and interruption pass through.
Use while in TypeScript or while_ in Python to restrict retries.
Hold exclusive control
Use a scoped lease when a workflow must exclude other SDK controllers:
const exclusive = scopedLease(prepareShelter, 30);
const result = yield* exclusive.run(bot);Use bot.acquireControlScoped() in TypeScript or bot.acquire_control() in Python for a direct scoped lease.
The scope releases the lease after success, failure, or interruption.
Behavior callbacks and finalizers return effects.
Behavior composition is an orchestration layer. A workflow does not move time-sensitive game logic back into the client process. Native and plugin tasks still own their server-side lifecycle, resource arbitration, reconnect policy, progress, and typed result.
How is this page?
Last updated on
