A modular .NET 9 game scripting framework that communicates with a game server via Windows named pipes using MessagePack-encoded JSON-RPC. Scripts are dynamically discovered at runtime from DLL assemblies and execute on background threads.
C# port of the Java JBotWithUsV2 framework.
- .NET 9 SDK
- Windows (named pipe transport)
# Build
dotnet build
# Run
dotnet run
# Run release build
dotnet run --configuration ReleaseThe application launches an ImGui-based graphical terminal for connecting to the game server, managing scripts, live game streaming, and monitoring performance.
Single .NET project with three logical layers:
Api/ (interfaces) — Public interfaces, models, query builders
↑ used by
Core/ (implementation) — RPC client, pipe transport, script runtime
↑ used by
Cli/ (terminal) — Interactive CLI, command system
Pure interface layer. Contains IBotScript (the script SPI), IGameApi (100+ methods for game interaction), fluent entity query builders (Npcs, Players, SceneObjects, GroundItems), inventory wrappers (Backpack, Bank, Equipment), an event bus, and inter-script communication via IMessageBus.
Key namespaces:
Constants— Game constant registries (InterfaceIds,InventoryIds,AnimationIds)Log— Structured logging API (IBotLogger,LoggerFactory,LogLevel)Script— Task-based scripting framework (ITask,TaskScript)Isc— Inter-script communication (IMessageBuswith request/response,ISharedState)Util— Timing helpers (Timing.GaussianRandom,Conditions.WaitForAnimation,Humanizefor human-like delays)
Runtime and communication layer. Handles Windows named pipe I/O (PipeClient), synchronous JSON-RPC with MessagePack serialization (RpcClient), script discovery from DLL files (ScriptLoader), and script lifecycle management (ScriptRuntime, ScriptRunner).
Key features:
- RPC timeouts — Configurable per-call timeouts with
RpcTimeoutException - Retry & reconnect —
RetryPolicywith exponential backoff,ReconnectablePipeClientfor auto-reconnect - Metrics —
RpcMetricstracks call count, latency, and error rate per method - Profiling —
ScriptProfilertracks loop timing (avg/min/max/last) - Error isolation — Per-phase error handling in
ScriptRunner(OnStart/OnLoop/OnStop) - Structured logging —
ConsoleLoggerimplementation ofIBotLogger - Stream pipe reader —
StreamPipeReaderfor receiving JPEG frames from game server stream pipes
ImGui-based graphical terminal (Silk.NET + OpenGL) with a command system. Features ANSI color parsing, inline image display, live game streaming, and command history with tab completion. Supports multiple simultaneous pipe connections and connection groups.
| Command | Description |
|---|---|
connect [pipe] |
Connect to a named pipe (default: BotWithUs) |
ping |
Test connectivity and measure latency |
scripts |
List loaded/available scripts |
mount <name> |
Start a script by name |
unmount <name> |
Stop a running script |
reload |
Reload scripts from scripts/ directory |
reload --watch |
Toggle auto-reload on DLL changes |
reload --start |
Reload and auto-start all scripts |
reload --group=<name> |
Reload scripts across a connection group |
stream start |
Start live game video streaming inline |
stream stop |
Stop all active streams |
stream start --quality 60 --fps 2 --width 960 --height 540 |
Stream with custom settings |
stream start --group <name> |
Stream from all connections in a group |
screenshot [file] [--open] |
Capture and display a screenshot inline |
metrics |
View RPC call statistics (latency, error rates) |
metrics --top=N |
Show top N methods by call count |
profile |
View per-script loop timing data |
config |
View/modify persistent CLI configuration |
actions |
Inspect the game action queue, history, blocked state |
events |
Monitor event bus subscriptions and publish counts |
group |
Manage connection groups (create/delete/add/remove) |
pipes |
Scan for available named pipes |
logs |
View log buffer with filtering |
help |
Show available commands |
Scripts implement the IBotScript interface and are packaged as .NET class library DLLs.
using JBotWithUsV2.Api;
[ScriptManifest(
Name = "My Script",
Version = "1.0",
Author = "You",
Description = "Does something useful"
)]
public class MyScript : IBotScript
{
private IScriptContext _ctx = null!;
public void OnStart(IScriptContext ctx)
{
_ctx = ctx;
// Initialize state, subscribe to events
}
public int OnLoop()
{
var api = _ctx.GameApi;
// Query entities, interact with the game
var npcs = new Npcs(api);
// ...
return 1000; // delay in ms before next loop, or -1 to stop
}
public void OnStop()
{
// Clean up resources
}
}For scripts with multiple behaviors, use TaskScript:
using JBotWithUsV2.Api.Script;
public class MyTaskScript : TaskScript
{
protected override void SetupTasks()
{
AddTask(new BankTask(Ctx));
AddTask(new CombatTask(Ctx));
AddTask(new IdleTask());
}
}
public class CombatTask : ITask
{
public string Name => "Combat";
public int Priority => 5;
public bool Validate() => /* enemy nearby */;
public int Execute() => /* fight and return delay */;
}Place compiled DLLs in the scripts/ directory. The runtime discovers and loads them automatically.
IBotScript → IGameApi → RpcClient → PipeClient → Game Server (named pipe)
The pipe transport uses 4-byte LE length-prefixed MessagePack frames over \\.\pipe\BotWithUs. The RPC client provides synchronous request/response semantics with async event dispatch.
This project is licensed under the GNU General Public License v3.0 — see the LICENSE file for details.