Architecture And Protocols
Understand how SoulFire boots, loads plugins, manages instances and bots, and translates GUI or CLI actions into low-level bot behavior.
If you want to build serious plugins, you should understand how SoulFire is layered. That is the difference between a plugin that happens to work today and a plugin you can keep alive across updates.
Runtime layers
At a high level, SoulFire looks like this:
- 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 instance: config, accounts, proxies, metrics, and session lifecycle.
- 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.
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
That is why the built-in plugin directory is such a strong reference. The internal plugins use the same event, settings, metadata, and control primitives that your external plugin uses.
The core objects
| Class | Responsibility |
|---|---|
SoulFireServer | global server process, RPC server, auth, server settings, instance registry |
InstanceManager | one instance, its settings, bot list, session lifecycle, instance metrics |
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
That matters for plugin authors because your settings page becomes a first-class part of the UI and CLI once you register it correctly.
Bot action protocol
SoulFire's internal action protocol for live bot control is described in bot.proto.
That service includes:
- 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
This is the same model you should think in when writing a plugin.
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 your use case can stay in scripting, it should. 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.
If you want to trace behavior end to end, start in the proto file, then read the matching gRPC service implementation, then inspect the built-in plugin or mixin that uses the same primitive.
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
Mixins And Access Wideners
Use Fabric Mixins and access wideners to inject into Minecraft or SoulFire internals when the public event surface is not enough.
Developer Resources
Jump directly to the current Javadocs, source trees, artifact coordinates, built-in plugin references, and other official SoulFire development entry points.