什么是MRubyD?

MRubyD是一个基于纯C#实现的mruby虚拟机,其名称寓意”mruby for dotnet“,同时向著名的mruby/c实现致敬。该项目专为C#游戏引擎深度优化,在保持Ruby语法兼容性的同时,充分利用现代C#特性实现卓越性能。

[!NOTE]
当前版本为预览版,欢迎开发者尝鲜体验

核心优势解析

原生C#实现的深度整合

MRubyD完全采用C#编写,这意味着:

  • 与Unity等C#游戏引擎无缝协作
  • 直接调用.NET丰富的类库资源
  • 利用C#强大的类型系统增强稳定性

现代C#带来的性能飞跃

通过以下技术实现高性能:

  • 托管指针(managed pointers)优化内存访问
  • Span<T>实现高效内存切片操作
  • .NET运行时GC与JIT编译器的性能加持
  • 值类型优化减少堆分配

高度兼容的Ruby API层

项目当前已实现:

  • 完整支持mruby所有操作码(opcodes)
  • 通过官方syntax.rb测试套件验证
  • 持续完善内置类型和方法支持

前所未有的扩展能力

相比原生C实现:

  • 直接嵌入C#对象无需复杂绑定
  • 调用.NET生态数百万高质量库
  • 简化游戏引擎脚本系统集成

当前版本能力边界

作为预览版本,请注意以下限制:

  • 内置类型和方法持续完善中(查看当前支持列表
  • 暂未实现private/protected可见性控制(mruby 3.4+特性)
  • 需配合原生mruby编译器使用(提供编译工具链简化方案)

技术路线图

  • [ ] 完善内置Ruby标准库
  • [ ] 实现Fiber协程支持
  • [ ] Ruby代码全量迁移到C#(性能优化)
  • [ ] Unity引擎深度集成
  • [ ] VitalRouter.MRuby新版适配

快速入门指南

安装部署

dotnet add package MRubyD

执行字节码示例

  1. 准备Ruby脚本:
def fibonacci(n)
  return n if n <= 1 
  fibonacci(n - 1) + fibonacci(n - 2)
end
fibonacci 10 #=> 55
  1. 编译为.mrb字节码:
mrbc -o fibonacci.mrbc fibonacci.rb
  1. C#端执行:
using MRubyD;
var bytes = File.ReadAllBytes("fibonacci.mrb");
var state = MRubyState.Create();
var result = state.Exec(bytes);

result.IsInteger    //=> true
result.IntegerValue //=> 55

核心数据类型处理

MRubyValue作为跨语言桥梁,支持丰富操作:

// 类型检测
value.IsNil      // 空值检测
value.IsInteger  // 整型检测
value.IsFloat    // 浮点检测
value.IsSymbol   // 符号检测
value.IsObject   // 对象检测

// 值提取
value.IntegerValue  // 获取Int64
value.FloatValue    // 获取float
value.As<RString>() // 对象转换

// 模式匹配
switch (value) {
    case { IsInteger: true }:
        break;
    case { Object: RString str }:
        break;
}

// 值构造
var intValue = MRubyValue.From(100);
var floatValue = MRubyValue.From(1.234f);

动态扩展Ruby类

var state = MRubyState.Create();

// 类定义
var classA = state.DefineClass(Intern("A"u8), c => {
    // 带参数方法
    c.DefineMethod(Intern("plus100"u8), (state, self) => {
        var arg0 = state.GetArgAsIntegeger(0);
        return MRubyValue.From(arg0 + 100);
    });
    
    // 块参数处理
    c.DefineMethod(Intern("method2"), (state, self) => {
        var blockArg = state.GetBlockArg();
        if (!blockArg.IsNil) {
            state.Send(blockArg, state.Intern("call"u8), arg0);
        }
    });
});

// 类方法扩展
classA.DefineClassMethod(Intern("classmethod1"), (state, self) => {
    return MRubyValue.From(state.NewString("hoge fuga"));
});

对应Ruby调用:

A.new.plus100(23#=> 123
A.classmethod1    #=> "hoge fuga"

字符串与符号处理

采用UTF-8编码体系:

// 字符串创建
var str1 = state.NewString("文本"u8); 
var str2 = state.NewString($"插值{x}");

// 符号处理
var sym1 = state.Intern("method1"u8);
var sym2 = state.ToSymbol(str1);

编译工具链集成

原生编译器方案

git clone git@github.com:mruby/mruby.git
cd mruby
rake
./build/host/bin/mrbc

MRubyD.Compiler简化方案

dotnet add package MRubyD.Compiler
var compiler = MRubyCompiler.Create(state);
var irep = compiler.Compile("def a; 1; end; a"u8);
state.Exec(irep); //=> 1

应用场景展望

  1. 游戏脚本系统
    Unity等引擎中替代Lua实现更优雅的游戏逻辑

  2. 配置脚本化
    动态配置加载与热更新

  3. 自动化测试
    利用Ruby DSL编写测试用例

  4. 快速原型开发
    Ruby语法快速验证游戏机制

开源与社区


通过MRubyD,.NET开发者现在可以同时享受Ruby的表达力和C#的性能优势,特别是在游戏开发领域将开辟全新的可能性。预览版已发布,期待您的体验反馈!