

Outward Mods Communicator enables seamless communication between mods through shared events and configuration syncing. It also lets users override any changes made by other mods, giving them full control over their settings. You can find library published on NuGet as Outward.ModsCommunicator.
Benefits of using this library:
This library allows mod pack creators to synchronize configuration files without directly editing them.
Users don’t need to download configuration files from third-party sources.
Configurations can be edited through XML, and the control flow follows this order: User -> Mod -> Cfg Documents
.cfg configuration files inside the BepInEx/config directory.
Mods Communicator solves this by using two XML files. One XML file is placed in the
mod’s plugin directory (recommended), and Mods Communicator uses it to override
configuration settings right after the ResourcesPrefabManager class
finishes its Load method.
Afterwards, it reads the player’s PlayerModsOverrides.xml file, located
inside this mod’s folder, to apply personal overrides based on the player’s preferences.
PlayerModsOverrides.example.xml file —
players must rename it to PlayerModsOverrides.xml.
This makes their configuration safe from updates and re-downloads.
ResourcesPrefabManager.Load method?ResourcesPrefabManager.Load completes, all
.cfg files are loaded, and it becomes safe to apply overrides.
Outward Game Settings mod uses this dependency
solely for the EventBus feature to publish additional events.
PlayerModsOverrides.example.xml file. You will need
to change it's name to PlayerModsOverrides.xml when you can open it to add
or modify XML values.
OutwardModsCommunicator.OMC.xmlFilePath = "FullPathTo/MyModsOverrides.xml";
<ConfigOverrides>
<Mod GUID="gymmed.outward_game_settings">
<Section Name="Enchanting Modifications">
<Entry Key="EnchantingSuccessChance" Value="5" />
<Entry Key="RequireRecipeToAllowEnchant" Value="false" />
<Entry Key="UseRecipeOnEnchanting" Value="false" />
</Section>
</Mod>
<Mod GUID="gymmed.outward_mods_communicator">
<Section Name="Event Profiler">
<Entry Key="EnableEventsProfiler" Value="true" />
<Entry Key="InstantLogEventsProfileData" Value="true" />
</Section>
</Mod>
</ConfigOverrides>
## Settings file was created by plugin Outward Game Settings v0.0.1
## Plugin GUID: gymmed.outward_game_settings
[Enchanting Modifications]
## Allow enchanting only if enchantment is on character?
# Setting type: Boolean
# Default value: true
RequireRecipeToAllowEnchant = false## Remove recipe after using it on enchanting?
# Setting type: Boolean
# Default value: true
UseRecipeOnEnchanting = false## What is success chance(%) of enchanting?
# Setting type: Int32
# Default value: 50
# Acceptable value range: From 0 to 100
EnchantingSuccessChance = 5
## Play additional audio on enchanting failed/success?
# Setting type: Boolean
# Default value: true
PlayAudioOnEnchantingDone = true
Communication is handled through an Event Bus — a system that allows mods to fire (publish) and listen (subscribe) to shared events.
using OutwardModsCommunicator.EventBus;
...
void Awake()
{
...
// GUID is your plugin ID provided as a string
// "EnchantmentMenu@TryEnchant" is the event name
// ("menu", typeof(EnchantmentMenu)) defines your variable name and its type
EventBus.RegisterEvent(GUID, "EnchantmentMenu@TryEnchant", ("menu", typeof(EnchantmentMenu)));
// you can add multiple variables and
// add as many as you need like this:
//EventBus.RegisterEvent("MyPluginId", "MyClass@MyMethod", ("name", typeof(string)), ("health", typeof(int)));
...
}
using OutwardModsCommunicator.EventBus;
...
void YourMethod()
{
...
// Add variable types and names
var payload = new EventPayload
{
["EnchantmentMenu"] = menu,
};
// Send event for subscribers to receive data
EventBus.Publish(OutwardGameSettings.GUID, "EnchantmentMenu@TryEnchant", payload);
}
using OutwardModsCommunicator.EventBus;
...
void Awake()
{
...
// Provide other mod GUID
// Provide event name
// Provide method you want to execute
EventBus.Subscribe("gymmed.outward_game_settings", "EnchantmentMenu@TryEnchant", OnTryEnchant);
}
private static void OnTryEnchant(EventPayload payload)
{
if (payload == null) return;
// try to retrieve passed event data
EnchantmentMenu menu = payload.Get<EnchantmentMenu>("menu", null);
// if event data is null log and stop execution
if (menu == null)
{
Log.LogMessage("Mod gymmed.outward_game_settings event EnchantmentMenu@TryEnchant returned null for EnchantmentMenu");
return;
}
// Lets log success
Log.LogMessage($"{GUID} successfully communicated with gymmed.outward_game_settings mod and passed menu!");
}
using OutwardModsCommunicator.EventBus;
...
// We use harmony patch to execute code after each plugin is loaded
// and have already registered their events
[HarmonyPatch(typeof(ResourcesPrefabManager), nameof(ResourcesPrefabManager.Load))]
public class ResourcesPrefabManager_Load
{
static void Postfix(ResourcesPrefabManager __instance)
{
// Log all registered events
EventBusDataPresenter.LogRegisteredEvents();
}
}
The project also includes extra tools like EventProfiler and EventBusDataPresenter — feel free to explore them to learn more.
You can view mod creation template here.
You can view outward game settings mod here.
To manually set up, do the following
Outward\BepInEx\plugins\OutwardModsCommunicator\.BepInEx\plugins\OutwardModsCommunicator\ directory you created.Outward\BepInEx\plugins\OutwardModsCommunicator\OutwardModsCommunicator.dll
Launch the game.