Raw protocol access
View and send Minecraft packets through the SoulFire SDK.
The protocol module exposes SoulFire's active Minecraft packet codec. Use it for missing high-level operations, custom packet extensions, or protocol debugging.
Use the typed world, inventory, chat, action, and task APIs for normal automation. Raw packet code depends on the Minecraft version and can break a bot connection.
Check the active protocols
info reports both protocol versions involved in a connection:
minecraftProtocolVersionis SoulFire's native client protocol. Packet schemas and encoded bytes in this API always use this version.remoteProtocolVersionis the Minecraft server protocol negotiated by ViaVersion.protocolStateidentifies the active native state, such asplayorconfiguration.- The limits describe the maximum encoded packet size and send rate.
const info = yield* bot.protocol.info();
yield* Effect.logInfo("Active protocol", {
native: info.minecraftVersionName,
remote: info.remoteVersionName,
state: info.protocolState,
});Discover packet IDs
List the packet names and numeric IDs for the bot's current native protocol state:
import { PacketDirection } from "@soulfiremc/sdk";
const packets = yield* bot.protocol.schemas(
PacketDirection.SERVERBOUND,
);
for (const packet of packets) {
yield* Effect.logInfo(`${packet.networkId}: ${packet.name}`);
}Packet discovery reports the active packet registry, not a stable cross-version contract. Re-read it after a protocol state transition or a bot reconnect.
Observe packets
Packet observation is available to callers with READ_BOT_INFO. Filter at the
server by direction and canonical packet name so high-volume connections do
not send irrelevant events to the SDK.
import { PacketDirection } from "@soulfiremc/sdk";
yield* bot.protocol.packets({
directions: [PacketDirection.CLIENTBOUND],
names: ["minecraft:game_event"],
includeEncodedPacket: true,
maximumEncodedBytes: 4096,
}).pipe(
Stream.runForEach((packet) =>
Effect.logInfo("Packet received", {
name: packet.name,
bytes: packet.encodedPacket.byteLength,
droppedBefore: packet.droppedBefore,
})
),
);The Promise facade returns an AsyncIterable, and the Python clients return
an async iterator or iterator:
from soulfire import PACKET_DIRECTION_CLIENTBOUND
async for packet in bot.protocol.packets(
directions=[PACKET_DIRECTION_CLIENTBOUND],
names=["minecraft:game_event"],
include_encoded_packet=True,
maximum_encoded_bytes=4096,
):
print(packet.name, len(packet.encoded_packet), packet.dropped_before)The stream respects transport backpressure. If the consumer cannot keep up,
SoulFire drops observations instead of blocking the bot's network thread. The
next delivered event reports the number in droppedBefore or
dropped_before.
Send a native packet
send accepts one complete unframed native packet. The byte array must contain
the native protocol packet ID followed by its payload. SoulFire decodes the
bytes through the active serverbound codec, rejects trailing data, and then
sends the decoded packet through the normal connection pipeline. ViaVersion
translates it to the remote server version afterward.
const result = yield* bot.protocol.send(encodedPacket, {
expectedName: "minecraft:custom_payload",
});
yield* Effect.logInfo("Packet sent", result);result = await bot.protocol.send(
encoded_packet,
expected_name="minecraft:custom_payload",
)
print(result.name, result.encoded_bytes)Set expectedName or expected_name whenever the packet type is known. This
guard prevents bytes built for one packet schema from being sent as another
packet after a version or state change.
Raw packet sending requires the RAW_PROTOCOL instance permission.
By default, SoulFire grants this permission only to administrators.
It limits packets to 1 MiB and 20 sends per second for each user and bot.
It writes each send to the server log.
Raw observation and injection do not bypass plugin RPCs, task ownership, or the normal typed SDK. A SoulFire plugin can expose a typed RPC when an operation is reusable. Reserve raw packets for genuinely version-specific work and short-lived diagnostics.
How is this page?
Last updated on
