How it started
At the time, I was learning XAML and joined a project called NautaExternal as a co-developer.
The application was built with C# and WPF, with me handling the frontend while the backend was developed collaboratively. Eventually, I migrated the application to Microsoft’s newer WinUI framework, giving it a more modern foundation.
The original goal was to bring support for Call of Duty: Black Ops III, with plans to expand to more games over time. What started as a relatively focused project gradually grew into something much more ambitious.
Bringing it to life
Once the core features were in place, we started exploring how much more we could build into the application.

Beyond the modding functionality itself, I worked on features such as interface customization, user accounts, global chat, and community translations. The goal was to make NautaExternal feel like a complete platform rather than just another modding utility.
One example was the global chat system, which connected users through the application and updated the interface with chat data and online users.
private Task GetChatData()
{
if (pullingChatData)
return Task.CompletedTask;
pullingChatData = true;
onlineUsers = SessionHandler.NautaAuthApp.FetchOnline();
if (onlineUsers is null)
{
pullingChatData = false;
return Task.CompletedTask;
}
getUserDBInfo = NautaGetAllUsersAPI();
var chat = SessionHandler.NautaAuthApp.GetChat("General");
if (chat is null)
{
pullingChatData = false;
return Task.CompletedTask;
}
var onlineUsersNames = string.Join("\n", onlineUsers.Select(x => x.credential));
App.MainWindow.DispatcherQueue.TryEnqueue(() =>
{
UpdateUI(chat, onlineUsersNames);
});
pullingChatData = false;
return Task.CompletedTask;
} NautaInternal
We also explored a more ambitious approach: building a C++ DLL that the main application could load and communicate with, acting as a bridge between the two.
I started working on an ImGui menu foundation that could be used to experiment with this approach and test functionality. It opened up new possibilities for the project and gave us another way to build and interact with features beyond the main application’s interface.

On the C# side, logic was added for checking whether the game was ready, handling the connection process, and updating the application when the RPC connection was established.
private async void Play_Click()
{
if (Memory.BlackOpsIII.IsGameReady())
{
if (Memory.BlackOpsIII.GetDvarString("NautaRPCEnabled") == "1" || Memory.BlackOpsIII.RPCTestConnection())
{
NotificationsHelper.InfoBar("RPC is currently active, please restart the game if you need to connect again.", InfoBarSeverity.Error);
return;
}
var response = await Task.Run(() => RPCInjectionThread());
if (response && Memory.BlackOpsIII.RPCSendBeep())
{
Memory.BlackOpsIII.Dvar_SetFromStringByName("NautaRPCEnabled", "1");
App.MainWindow.DispatcherQueue.TryEnqueue(() =>
{
UpdateRPCInfo(true);
NotificationsHelper.InfoBar("RPC attached.", InfoBarSeverity.Informational, true);
});
_ = Task.Run(() => RPCEnabledThread());
return;
}
}
} The DLL loading operation was separated into its own method, keeping that part of the process distinct from the UI event handler.
internal static bool InjectDLL_M_Map(byte[] dllData)
{
if (Game.GetValue<long>(Game[OFF_GAME_READY]) is 0)
throw new Exception("Call of Duty Black Ops III process is not ready.");
try
{
lpMyDll = Game.MapModule(dllData, new ModuleLoadOptions() { ClearHeader = false, ExecMain = true, MainThreadType = XCTT_QUAPC });
myDll = ProcessModuleEx.FromMappedModule(lpMyDll, dllData);
return true;
}
catch (Exception e)
{
App.MainWindow.DispatcherQueue.TryEnqueue(() =>
{
NotificationsHelper.InfoBar(e.Message, InfoBarSeverity.Error);
});
return false;
}
} Moving on
After spending more than two years working on the project, I started to lose the enjoyment that had brought me into it in the first place.
What was once an exciting opportunity to learn, build, and experiment had gradually started to feel like a chore. I was burned out, and continuing to work on it no longer felt right.
Eventually, I decided to step away and return to solo hobby projects. The main developer was also considering discontinuing the project, so it felt like a natural point for me to move on.
NautaExternal was a significant chapter in my development journey. It gave me experience working on a much larger application, and taking software from development through to public release.
Even though I eventually moved on, it remains one of the biggest projects I’ve ever been involved in.
