OpenEngine hosts the .NET CoreCLR to enable C# scripting for game logic. The scripting system supports hot-reloading, asset interaction, and bidirectional C++/C# interop.
How It Works
C# Script (Assets/Scripts/*.cs)
โ
CoreCLR Host (in engine)
โ
C++ โ C# P/Invoke Interop
โ
Engine Systems (rendering, physics, assets)The engine initializes CoreCLR at startup, loads compiled assemblies from build/bin/<Config>/ScriptAssemblies/, and invokes C# entry points each frame.
Script Assembly Pipeline
- Place
.csfiles inAssets/ - Build the C++ project โ CMake generates
OpenEngine.Scripts.csprojand builds it - Output:
build/bin/<Config>/ScriptAssemblies/OpenEngine.Scripts.dll - Engine loads the assembly at runtime
No manual dotnet build needed โ the ScriptAssemblies pipeline is part of the CMake build.
C++ to C# Interop
The engine registers native functions that C# can call via P/Invoke:
// NativeInterop.cs โ provided by the engine
public static class NativeInterop
{
[DllImport("Engine")]
public static extern void LogMessage(string message);
[DllImport("Engine")]
public static extern int GetAssetCount();
[DllImport("Engine")]
public static extern int AddNumbers(int a, int b);
}Hot-Reloading
The engine monitors Assets/ for file changes using platform-native file watchers:
- Windows:
ReadDirectoryChangesWAPI - Linux/macOS:
inotify/FSEvents
When a .cs file changes, the engine recompiles the assembly and reloads it โ no restart required.
Hot-reload detection is sub-millisecond. Changes appear in the next frame after compilation completes.
Lifecycle
OnInitialize()โ called once at startupOnUpdate(float deltaTime)โ called every frameOnShutdown()โ called during engine shutdown[InitializeOnLoad]โ attribute for editor-time initialization
Next Steps
- Build the Editor to use the visual tooling
- Follow the Development Workflow for scripting sessions