RU

runtime-eval

Execute and inspect C# code live within a running game environment via WebSocket.

Install

mkdir -p .claude/skills/runtime-eval && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/19282" && unzip -o skill.zip -d .claude/skills/runtime-eval && rm skill.zip

Installs to .claude/skills/runtime-eval

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Runtime C# evaluation via HotRepl WebSocket. Use when inspecting live game state, debugging mod behavior, or prototyping fixes without a build cycle.
149 chars✓ has a “when” trigger
Advanced

Key capabilities

  • Execute C# code in a running game process
  • Inspect live scene objects and variables
  • Stream game state data via watch commands
  • Trigger hot-reloads of plugins
  • Access Unity API methods at runtime

How it works

It connects to a running game via a WebSocket-based REPL, allowing for real-time code execution and inspection within the game's memory space.

Inputs & outputs

You give it
C# expression string
You get back
Evaluated result or object state

When to use runtime-eval

  • Inspect live game state variables
  • Prototype bug fixes without rebuilding
  • Test rendering changes dynamically

About this skill

Runtime Eval (HotRepl)

Execute C# code inside the running game over WebSocket. Inspect scene state, test rendering changes, and prototype fixes without a build/deploy cycle.

Start a HotRepl session

HotRepl is a BepInEx development dependency for Erenshor. It is not a Lunaris plugin, and mod launch does not install it. With the game closed, activate BepInEx, then launch the selected variant through Steam:

uv run erenshor mod activate --loader bepinex
uv run erenshor mod launch
uv run erenshor eval ping

The default variant is main. Pass -V playtest or -V demo before mod and eval only when that variant is intentional. mod deploy --loader bepinex also activates BepInEx when deploying a companion mod. Never swap or copy winhttp.dll by hand.

HotRepl remains installed between sessions. Normal use only requires selecting BepInEx and launching the game. Wait for Steam and the game process to finish starting before treating a failed ping as a loader failure.

Install or update the HotRepl host

HotRepl is maintained in ~/Projects/HotRepl/. The current BepInEx host is a multi-assembly deployment. Build the host from that checkout:

dotnet build ~/Projects/HotRepl/src/HotRepl.BepInEx --nologo -v q

The deploy source is src/HotRepl.BepInEx/bin/Debug/netstandard2.1/. Deploy every top-level DLL from that output into a dedicated BepInEx/plugins/HotRepl/ directory. Replace the existing HotRepl directory as one unit so every assembly comes from the same build. The set includes HotRepl.BepInEx.dll, HotRepl.Core.dll, HotRepl.Protocol.dll, evaluator and Unity-command assemblies, Fleck, Newtonsoft.Json, and mcs.dll. Ensure no HotRepl DLLs remain at the BepInEx/plugins/ root because duplicate or partial deployments produce assembly resolution failures.

Host deployment is an install/update operation, not part of every launch. It must happen while the game is closed and currently has no erenshor mod command. Use the complete build output rather than inventing an allowlist. After starting the game, BepInEx/LogOutput.log should contain HotRepl v… loaded — REPL on 127.0.0.1:18590.

Eval commands

uv run erenshor eval ping                                     # Check connection
uv run erenshor eval run 'SceneManager.GetActiveScene().name' # Evaluate expression
uv run erenshor eval run --json 'GameData.PlayerControl.transform.position'
uv run erenshor eval reset                                    # Clear REPL state
uv run erenshor eval watch 'GameData.PlayerControl.transform.position'  # Stream
uv run erenshor eval complete 'Camera.main.'                  # Autocomplete

Combat evaluation

For controlled experiments that validate damage, healing, resistance, proc, resource, or cooldown behavior, use the combat-evaluation skill. Keep this skill focused on HotRepl commands, evaluator constraints, and runtime access.

C# 7 Limitations

The Mono compiler supports C# 7.x only. These do not work:

  • async/await, nullable annotations, switch expressions, records, ranges
  • Anonymous types (new { foo = 1 }) — compiles to internal classes the REPL's dynamic assembly can't emit. Use tuples or string concatenation instead.
# WRONG — anonymous type fails to compile
uv run erenshor eval run 'objects.Select(o => new { o.name, o.tag }).ToArray()'

# RIGHT — use string formatting
uv run erenshor eval run 'objects.Select(o => o.name + " tag=" + o.tag).ToArray()'

ScriptEngine Cross-Assembly Gotchas

Hot-reloaded mods (deployed via --scripts, reloaded with F6) get timestamp- suffixed assembly names like AdventureGuide-639098010137845420.

HotRepl auto-resets on hot reload: When a ScriptEngine-style assembly loads, HotRepl detects it and rebuilds the evaluator session, filtering out superseded assemblies. Types resolve to the newest version automatically. REPL variable state is lost on reset (expected — F6 is a code change, not a data continuation).

When auto-reset doesn't help: If you encounter cross-assembly errors despite auto-reset (e.g., after multiple rapid F6 reloads), use eval reset manually. The reflection pattern below also works as a fallback for any cross-assembly access:

# Pattern: find object by string name, reflect through its own type
uv run erenshor eval run '
var ag = Resources.FindObjectsOfTypeAll(typeof(MonoBehaviour))
    .First(o => o.GetType().FullName == "AdventureGuide.Plugin");
var bf = System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance;
var state = ag.GetType().GetField("_state", bf).GetValue(ag);
state.GetType().GetProperty("CurrentZone").GetValue(state)
'

Triggering ScriptEngine hot reload

After uv run erenshor mod deploy --mod <id> --loader bepinex --scripts, trigger ScriptEngine directly through HotRepl. The deployment activates BepInEx, so restart the game first if Lunaris was active:

uv run erenshor eval run '
var asm = AppDomain.CurrentDomain.GetAssemblies()
    .First(a => a.GetName().Name == "ScriptEngine");
var type = asm.GetType("ScriptEngine.ScriptEngine");
var inst = UnityEngine.Object.FindObjectsOfTypeAll(type).First();
type.GetMethod(
    "ReloadPlugins",
    System.Reflection.BindingFlags.Instance
        | System.Reflection.BindingFlags.Public
        | System.Reflection.BindingFlags.NonPublic)
    .Invoke(inst, null);
"reloaded"
'

Why this shape matters:

  • FindObjectOfType(type) can return null for the ScriptEngine singleton
  • FindObjectsOfTypeAll(type).First() finds the BepInEx_Manager instance
  • ReloadPlugins is an instance method, not static

After the reload, check BepInEx/LogOutput.log for:

  • Script Engine] Reloaded all plugins!
  • your mod's startup log block
  • any reload-time exceptions

HotRepl auto-resets its evaluator session after ScriptEngine reload, so the connection dropping and reconnecting once is expected.

AdventureGuide DebugAPI

For AdventureGuide inspection, prefer DebugAPI over raw reflection. DebugAPI methods are static and resolve correctly after F6 hot reload thanks to HotRepl's auto-reset.

# Mod state overview
uv run erenshor eval run 'AdventureGuide.Diagnostics.DebugAPI.DumpState()'

# Quest details
uv run erenshor eval run 'AdventureGuide.Diagnostics.DebugAPI.DumpQuest("TheQuestDBName")'

# Navigation state (target, waypoint, ground path)
uv run erenshor eval run 'AdventureGuide.Diagnostics.DebugAPI.DumpNav()'


# All quests in current zone
uv run erenshor eval run 'AdventureGuide.Diagnostics.DebugAPI.DumpZoneQuests()'

Performance Profiling

For live runtime timing, use the in-game-performance-profiling skill.

Keep this skill focused on HotRepl usage, evaluation quirks, and inspection. Move detailed benchmarking patterns, Stopwatch helpers, and profiling workflow guidance into the profiling skill so runtime-eval stays concise.

Unity API Access

Static Unity methods need the full UnityEngine.Object. prefix:

# WRONG
uv run erenshor eval run 'FindObjectsOfType<Camera>().Length'

# RIGHT
uv run erenshor eval run 'UnityEngine.Object.FindObjectsOfType<Camera>().Length'

Pre-imported namespaces: UnityEngine, UnityEngine.SceneManagement, System.Linq.

REPL State

Variables persist across calls. Use eval reset to clear.

uv run erenshor eval run 'var npcs = NPCTable.LiveNPCs;'
uv run erenshor eval run 'npcs.Count'
uv run erenshor eval run 'npcs.Select(n => n.NPCName).Distinct().OrderBy(x => x).ToArray()'

Timeout

Default: 10 seconds. Override per-call:

uv run erenshor eval run --timeout 3000 'while(true){}'  # ms, killed after ~3s

Key Files

FilePurpose
~/Projects/HotRepl/Standalone HotRepl project
src/erenshor/application/eval/client.pyPython WebSocket client
src/erenshor/cli/commands/eval.pyCLI commands
src/mods/AdventureGuide/src/Diagnostics/DebugAPI.csAdventureGuide inspection API

When not to use it

  • Using async/await or anonymous types in evaluated code
  • Performing heavy benchmarking or profiling
  • Modifying game state without testing in a controlled environment

Prerequisites

BepInExHotRepldotnet SDK

Limitations

  • Supports C# 7.x only
  • Anonymous types fail to compile
  • REPL state is lost on hot reload

How it compares

It enables live debugging and prototyping without requiring a full build and deployment cycle for every minor code change.

Compared to similar skills

runtime-eval side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
runtime-eval (this skill)010dReviewAdvanced
unity-developer1423moNo flagsAdvanced
csharp-developer432moNo flagsAdvanced
csharp-pro93moNo flagsIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

You might also like

unity-developer

sickn33

Build Unity games with optimized C# scripts, efficient rendering, and proper asset management. Masters Unity 6 LTS, URP/HDRP pipelines, and cross-platform deployment. Handles gameplay systems, UI implementation, and platform optimization. Use PROACTIVELY for Unity performance issues, game mechanics, or cross-platform builds.

142357

csharp-developer

zenobi-us

Expert C# developer specializing in modern .NET development, ASP.NET Core, and cloud-native applications. Masters C# 12 features, Blazor, and cross-platform development with emphasis on performance and clean architecture.

43151

csharp-pro

sickn33

Write modern C# code with advanced features like records, pattern matching, and async/await. Optimizes .NET applications, implements enterprise patterns, and ensures comprehensive testing. Use PROACTIVELY for C# refactoring, performance optimization, or complex .NET solutions.

953

performance-benchmark

dotnet

Generate and run ad hoc performance benchmarks to validate code changes. Use this when asked to benchmark, profile, or validate the performance impact of a code change in dotnet/runtime.

328

bug-fix

mono

Fix bugs in SkiaSharp C# bindings. Structured workflow for investigating, fixing, and testing bug reports. Triggers: Crash, exception, AccessViolationException, incorrect output, wrong behavior, memory leak, disposal issues, "fails", "broken", "doesn't work", "investigate issue", "fix issue", "look at #NNNN", any GitHub issue number referencing a bug. For adding new APIs, use `add-api` skill instead.

426

dotnet-backend-patterns

wshobson

Master C#/.NET backend development patterns for building robust APIs, MCP servers, and enterprise applications. Covers async/await, dependency injection, Entity Framework Core, Dapper, configuration, caching, and testing with xUnit. Use when developing .NET backends, reviewing C# code, or designing API architectures.

722

Search skills

Search the agent skills registry