为什么写 LuminPack
游戏存档、实时网络消息和跨进程数据交换都会频繁触发序列化。通用反射方案虽然灵活,却常常带来额外查找、装箱与分配;Unity 的 IL2CPP 和 AOT 环境还会进一步限制运行时动态能力。
LuminPack 因此选择了另一条路线:通过 Roslyn 增量源代码生成器,在编译期为具体类型生成专用解析代码。运行时无需反射,同时支持二进制与 JSON 两套格式。
核心能力
- 支持
ReadOnlySpan<byte>与ReadOnlySequence<byte>等现代 I/O API。 - 支持 .NET Standard 2.1、.NET 8/9/10,并针对 Unity Mono 与 IL2CPP 适配。
- 支持多态、循环引用、反序列化缓存池与非托管 WriterBuffer。
- 提供快速的有限版本容忍,以及
GenerateType.VersionTolerant完整版本容忍模式。 - 无反射,生成代码可直接检查,方便定位协议问题。
五分钟上手
先安装运行库和生成器:
dotnet add package LuminPack
dotnet add package LuminPackGenerator
给数据类型添加 LuminPackable:
using LuminPack;
[LuminPackable]
public class Person
{
public int Age { get; set; }
public string Name { get; set; } = string.Empty;
}
之后即可调用统一入口:
var item = new Person { Age = 18, Name = "Light" };
var binary = LuminPackSerializer.Serialize(item);
var json = LuminPackSerializer.SerializeJson(item);
var fromBinary = LuminPackSerializer.Deserialize<Person>(binary);
var fromJson = LuminPackSerializer.DeserializeJson<Person>(json);
性能之外:协议演进
默认对象格式追求速度,适合结构稳定、客户端与服务端同步更新的场景。需要跨版本长期保存数据时,可以使用完整版本容忍模式,并通过 LuminPackOrder 固定成员编号。
[LuminPackable(GenerateType.VersionTolerant)]
public class SaveData
{
[LuminPackOrder(0)]
public int Level { get; set; }
[LuminPackOrder(1)]
public string PlayerName { get; set; } = string.Empty;
}
这类模式会牺牲一部分性能来换取更自由的字段增删,因此应该根据数据生命周期选择,而不是全局套用。
Unity 使用建议
Unity 项目需要启用 .NET Standard 2.1 API 兼容级别。运行库可以通过 NuGetForUnity 或手动方式导入;生成器放入 Assets/RoslynAnalyzers 后,需要确认它被标记为 Roslyn Analyzer。
发布前建议真正跑一次目标平台的 IL2CPP Player。只看编辑器内编译成功,不能覆盖裁剪、AOT 注册和平台 ABI 等实际问题。
接下来
计划继续推进 Unity 编辑器可视化、内置压缩与加密能力。LuminPack 的目标不仅是跑得快,还要让生成结果、格式规则与错误诊断足够透明。
