Package-level declarations

Types

Link copied to clipboard
class Capture

Accumulate, materialize once, seal. Backs the per-eval out and the run_command target=client chat window.

Link copied to clipboard
class EvalHandle(val task: EvalTask)

A receipt for one eval submitted to a Lane: the block-until-done result future, plus the ability to cancel the eval (the client-initiated counterpart to the lane's own reaping; see cancel). Handed out by Lane.submit; the MCP layer holds it against the in-flight request id so a notifications/cancelled can find and stop it.

Link copied to clipboard
internal class EvalTask(val code: String, val onCompiled: (EvalTask) -> Unit, val epoch: Long, val guardLane: GuardLane?)

One eval scheduled on a lane. Compilation runs OFF the tick (pure computation) on a short-lived thread; once compiled the task enters the lane and is EXECUTED ON THE TICK THREAD by the pump — so the snippet runs with the real server/client/render thread identity (ensureOnSameThread passes), not a surrogate thread.

Link copied to clipboard
interface ExecLane

The minimal lane contract McpServer depends on to run an eval: is it runnable right now, and submit code to it. Implemented by Lane and ParallelLane, which share the eval machinery and differ only in what drives each eval's steps — a heartbeat, or a worker loop.

Link copied to clipboard
enum GuardLane(val killIdField: String) : Enum<GuardLane>

Which per-thread kill-id field an instrumented script reads. The server lane runs on the Server thread; the client and render lanes BOTH run on the Render thread and share one field (they never run concurrently). Each case names the static field the inlined GETSTATIC reads. A future lane needing its own thread costs one case here, one field, and one branch in TimeoutGuard.setKillId — the rest of the guard state is per-ordinal.

Link copied to clipboard
class IterEval(val iterator: Iterator<*>, val errorFlag: AtomicBoolean)

What ReplHost.execute hands back for a cross-tick snippet: the iterator to drive one step per tick. Both output channels — println, and the => type = value each yield renders — land in the per-eval out sink EvalTask owns and passed down, so the two arrive interleaved in the order they happened.

Link copied to clipboard
class Lane(val name: String, val liveProbe: LiveProbe) : ExecLane

One execution lane: a tick source (a game method a Mixin injects at RETURN — the "heartbeat") whose every fire steps the lane's active evals once, on that source's own thread, so a step has exclusive access to that side's game state. Three lanes exist (Lanes): server (server tick), client (client tick), render (render frame) — identical machinery, different heartbeat.

Link copied to clipboard
class Lanes
The execution lanes and how they observe the running game: three heartbeat-pumped tick lanes (server / client / render) plus the off-tick PARALLEL lane.
Link copied to clipboard
internal fun interface LiveProbe

Whether a lane's tick source is up, asked of that source on demand rather than tracked in a field — nothing to keep in sync, and one left over from a source that has since stopped answers false on its own. The client and render lanes answer from the physical side alone; the server lane asks the MinecraftServer, whose own liveness flag covers the integrated server coming and going on a client.

Link copied to clipboard
class Outcome(val isError: Boolean, textFn: Supplier<String>)

The result of one eval: its text plus whether it ended in error, which the MCP layer maps to tools/call isError.

Link copied to clipboard
class ParallelLane(val name: String) : ExecLane

Off-tick execution lane. Unlike the heartbeat-pumped tick lanes (Lane), which serialize every eval through one pump on one game thread under the 1s TimeoutGuard, this runs each eval CONCURRENTLY on its own worker thread — no tick affinity, no cross-tick yield, no scriptguard. For work that must NOT touch live game state under a tick thread's identity: pure computation, blocking I/O, anything that would freeze a tick or trip the watchdog. Always isReady (there is no heartbeat to observe).

Link copied to clipboard
class ScriptTimeoutError(budgetMs: Long) : Error

Thrown by the timeout guard ScriptWeave.instrument inlines into a script's own bytecode when a tick's shared script-time budget is exhausted. An Error rather than an Exception so a script's catch (e: Exception) cannot swallow it.

Link copied to clipboard

Inlined per-tick time guard. ScriptWeave.instrument inlines if (killId == myEvalId) throw timeout (GETSTATIC + LDC + IF_ICMPNE + GETSTATIC timeout + ATHROW) at every method entry, loop back-edge and (non-self-ref) catch handler entry of a script's own bytecode. Being inlined it pushes NO new frame, so it runs even at the stack-full edge — inside the catch handler's existing frame — where an INVOKESTATIC guard would itself StackOverflowError. One mechanism handles BOTH dead loops (back-edges) and dead recursion (the checks fire as SOE unwinds through catch handlers).