Anvil
Building blocksEnvironmentsActions

Interacting through agents

Use process capabilities backed by native server or proxy agents without creating a player.

Use an agent-backed process capability when a test needs to read or change state through the server or proxy's native API. Retrieve the capability directly from the running process. The process owns the behavior; its platform agent supplies the native implementation. This does not require a simulated player or a game session.

Retrieve a process capability

Look up a capability on the process handle, for example anvil.processes().server("lobby").capability(Dispatch.class) with the built-in Dispatch capability, which runs a command as the console through the platform agent. Capability retrieval fails with CapabilityUnavailableException when the installed providers do not supply the requested type. Use process.hasCapability(type) only when absence is an intentional supported case; it reports whether the capability is installed, not whether its next request will succeed.

Choose the owner and interaction

TaskEntry point
Run a command as the console and know whether the platform accepted itThe process's Dispatch capability
Send console input or inspect captured process outputThe process's console
Read or change plugin state with a typed resultAn installed process capability calling a native operation
Know who is on a server or proxy, the profile it sees, or a player's backendThe process's Players capability
Restart one processRestarting processes

A capability's owner follows who can normally do or know the thing, not how it is implemented. Dispatch and Players belong to the process because running a console command and knowing who is on it are what a server or proxy does; both happen to use its agent. A custom process capability can use another implementation without exposing an agent in its public API.

Call an external capability

The Echo example supplies a process capability that calls an installed handler. Add its host adapter to anvilImplementation, and install its handler JAR in lobby. Inside a test with the running ScenarioContext anvil, use:

import com.example.echo.Echo;

import static org.junit.jupiter.api.Assertions.assertEquals;

var lobby = anvil.processes().server("lobby");
assertEquals("echo:hello", lobby.capability(Echo.class).send("hello"));

Success establishes that the handler in lobby returned echo:hello. Replace Echo with an operation that returns the application state your test needs to assert. The result contains serializable values, not the platform's live objects.

Process capability instances remain stable across a JVM restart. Retrieve the current process handle for state and console observations; the replacement handle exposes the same capability instances. Agent-backed requests can fail while the replacement connection is unavailable; retry only after the process has started successfully.

Closing the scenario closes process capabilities after players and before their agent connections. Subsequent capability lookup fails and hasCapability(...) returns false. Do not use retained capability instances after that cleanup.

Add native behavior

A host capability provider calls a typed operation through its borrowed RequestChannel. Anvil connects that channel to the process's agent client. The matching AgentOperationProvider installs the handler inside the managed JVM. These are separate extension points: adding the host dependency does not install the native handler.

Follow Agent providers for host wiring and Contracts and handlers for native implementation. Install handlers as workspace assets under plugins/anvil-agent-extensions.

Handlers access native services through PlatformAgent.requireService(...). The bundled Bukkit agent exposes org.bukkit.Server; Velocity and BungeeCord agents expose their proxy APIs. Use platform.call(...) and follow the native API's threading rules.

If a request fails, check agent readiness, handler installation and service descriptors, matching operation contracts, and the target process's anvil-console.log.

On this page