Architecture And Protocols
Learn how SoulFire starts, loads plugins, manages bots, and processes actions from the GUI or CLI.
Read this page after you load your first plugin. It explains how a UI or RPC request becomes bot behavior.
If you only need to build a normal plugin, stay in Build Your First Plugin, Event System, and Settings And Metadata. Read this page when you need to follow an internal code path end to end.
Runtime layers
SoulFire has these runtime layers:
- Bootstrap and launcher prepare startup, properties, and mixin loading.
- Fabric loads SoulFire itself as a mod and also loads your external plugin jar as another Fabric mod.
- SoulFireServer manages the global server process, settings, auth, RPC server, and instances.
- InstanceManager manages one separate group of settings, accounts, proxies, metrics, and automation.
- BotStateManager persists each bot's desired state and reconciles connection attempts.
- BotConnection owns one bot's headless Minecraft client copy plus settings, metadata, scheduler, and control state.
- Plugins listen to events, register settings pages, and optionally use Mixins for deeper integration.
For plugin authors, the important points are:
- Fabric loads both SoulFire and your plugin jar
- SoulFire exposes higher-level hooks through events, settings, metadata, and control APIs
- the GUI and CLI are thin clients over structured gRPC and proto definitions
- when you need to go lower, you are following the same path SoulFire itself follows
Internal plugins versus external plugins
SoulFire has two plugin loading models:
- internal plugins are scanned from
com.soulfiremc.server.pluginsusing@InternalPluginClass - external plugins are ordinary Fabric mods that call
SoulFireAPI.registerServerExtension(...)from aModInitializer
The built-in plugin directory contains useful examples. Internal and external plugins use the same event, settings, metadata, and control APIs.
The core objects
| Class | Responsibility |
|---|---|
SoulFireServer | global server process, RPC server, auth, server settings, instance registry |
InstanceManager | one separate group of permissions, settings, accounts, proxies, automation, and metrics |
BotStateManager | durable per-bot intent, connection queueing, reconnect policy, and runtime status |
BotConnection | one bot, including the cloned headless Minecraft client |
SoulFireAPI | global event bus and plugin registry |
Settings and UI protocol
The GUI and CLI do not hardcode plugin pages. Instead, SoulFire exports structured definitions over gRPC:
server.protoexposes server config, setting definitions, pages, and pluginsinstance.protoexposes instance config, setting definitions, pages, and pluginscommon.protodefinesSettingsDefinition,SettingsPage,SettingsNamespace, andServerPlugin
After registration, your settings page appears in the GUI and CLI.
Bot action protocol
SoulFire's internal action protocol for live bot control is described in bot.proto.
That service includes:
- per-bot desired state, restart, and status streaming
- movement state updates
- rotation updates
- hotbar selection
- inventory clicks and container button clicks
- world mouse clicks
- container text input
- POV rendering
- dialog retrieval and interaction
The important implementation detail is what happens after the RPC call arrives:
- the request is resolved to an online
BotConnection - permissions are checked
- SoulFire schedules a low-level operation through
BotControlAPIor direct player and gameMode access - control state or staged tasks drive the actual Minecraft-side behavior
Plugins follow the same process.
How low-level actions reach Minecraft
The typical path is:
GUI or CLI action -> gRPC/proto request -> service implementation -> BotConnection -> ControlState or ControllingTask -> Minecraft classes or mixin hook
Examples from the current implementation:
- movement RPCs write to
ControlState - rotation, hotbar, inventory, mouse, and dialog actions typically use
ControllingTask.singleTick(...) - multi-step automation uses staged controlling tasks
- input booleans become real player movement through SoulFire's keyboard input mixin
Script protocol
The visual scripting system is a separate higher-level automation layer.
Its wire model lives in script.proto and describes:
- edge types
- port types
- type descriptors
- node definitions
- script graphs and execution metadata
If scripting supports your use case, use scripting. Plugin development is what you use when you need lower-level access than the script graph model exposes.
Why Mixins appear in the architecture
SoulFire is built on Fabric and real Minecraft client code. That means some of its own public hooks are created by Mixins:
- packet pre-send and pre-receive events
- chat receive event
- bot pre-tick and post-tick events
- client brand and client settings overrides
- control-state-driven input
So when you write a plugin Mixin, you are not leaving the architecture. You are using the same extension mechanism SoulFire itself uses for its lowest-level integrations.
To trace behavior, start in the proto file. Then read the matching gRPC service and the plugin or Mixin that uses the same API.
Best places to trace behavior
- SoulFire source root
- gRPC service implementations
- Proto definitions
- Built-in plugins
- Javadocs package index
Next steps
How is this page?
Last updated on
