---
title: MasterMemory v3 最速確認会
tags: 
author: [ゆっち〜 (Yuichiro MUKAI)](https://www.docswell.com/user/yucchiy)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/G75R188DE4.jpg?width=480
description: MasterMemory v3 最速確認会 by ゆっち〜 (Yuichiro MUKAI)
published: December 28, 24
canonical: https://www.docswell.com/s/yucchiy/ZN173W-2024-12-28-163212
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/G75R188DE4.jpg)

MasterMemory v3 最速確認会
【年末だよ】Unity お・と・なのLT大会 2024
2024/12/28 @yucchiy_


# Page. 2

![Page Image](https://bcdn.docswell.com/page/9J2D1KVMJR.jpg)

このLTで話したいこと
• MasterMemoryについてのおさらい
• MasterMemoryについて
• MessagePackとの関係やコード生成について
• MasterMemory v3の変更点の紹介
• Source Generator対応について
• MasterMemory v3の利用方法の紹介
• 導入方法から簡単な使い方について


# Page. 3

![Page Image](https://bcdn.docswell.com/page/DEY2ZN3PEM.jpg)

自己紹介
向井 祐一郎
• 株式会社 サイバーエージェント / 株式会社アプリ ット
• Lead Developer Experience
• システム系の基盤開発・プロジェクトの開発支援
SNS・個人活動など
• @yucchiy_（X）
• Unity Weekly
• https://blog.yucchiy.com/tags/unity-weekly/
ボ
• UniTips（社内有志で技術書典に執筆）


# Page. 4

![Page Image](https://bcdn.docswell.com/page/VJN83XVM78.jpg)

MasterMemory のおさらい


# Page. 5

![Page Image](https://bcdn.docswell.com/page/YE9K986WE3.jpg)

• マスター ータの管理に主眼を置いたインメモリ ータベース
• 省メモリ・高速なデータベースロード・高速な検索の3点に重点を置く
• 弊社導入事例: Unity/C#
ーム開発における、クライアントでのマスターデータの扱い方
• https://blog.applibot.co.jp/2024/01/19/unity-master-data/
•
ータベースのフォーマットは MessagePack
• データを読み込んで、メモリ上にデータベースを構築する
• 書き出されたデータの読み込みでMessagePackのデータの解析に、
MessagePackのシリアライ が必要になる
デ
ザ
ゲ
https://github.com/Cysharp/MasterMemory
デ
デ
MasterMemory とは


# Page. 6

![Page Image](https://bcdn.docswell.com/page/GE8R98ZRJD.jpg)

デ
ータの定義
[MemoryTable(&quot;person&quot;), MessagePackObject(true)]
public record Person
{
[PrimaryKey]
public int PersonId { get; set; }
[SecondaryKey(0), NonUnique]
[SecondaryKey(1, keyOrder: 1), NonUnique]
public int Age { get; set; }
[SecondaryKey(2), NonUnique]
[SecondaryKey(1, keyOrder: 0), NonUnique]
public Gender Gender { get; set; }
public string Name { get; set; }
}
属性を用いて各カラムの “扱い” を定義


# Page. 7

![Page Image](https://bcdn.docswell.com/page/LELKWRD2JR.jpg)

デ
ータベースの検索
データベースの読み込み
（byte[] を引数に初期化）
var db = new MemoryDatabase(
File.ReadAllBytes(
Path.Combine(Application.dataPath, &quot;StreamingAssets&quot;, &quot;database.bytes&quot;)
)
);
Person person = db.PersonTable.FindByPersonId(3);
RangeView&lt;Person&gt; persons =
db.PersonTable.FindByGender(Gender.Male);
PrimaryKeyで検索
SecondaryKeyで範囲検索


# Page. 8

![Page Image](https://bcdn.docswell.com/page/4JM29RP9JW.jpg)

MessagePackのフォーマッタ
独自型のシリアライ
のために、内部でフォーマッタが必要になる
[MemoryTable(“person”), MessagePackObject(true)]
public record Person
{
[PrimaryKey]
public int PersonId { get; init; }
internal sealed class PersonFormatter :
MessagePack.Formatters.IMessagePackFormatter&lt;Samples.Person&gt;
{
public void Serialize(
ref MessagePack.MessagePackWriter writer,
Samples.Person value,
MessagePack.MessagePackSerializerOptions options)
{
[SecondaryKey(0), NonUnique]
[SecondaryKey(1, keyOrder: 1), NonUnique]
public int Age { get; init; }
var formatterResolver = options.Resolver;
writer.WriteMapHeader(4);
writer.WriteRaw(GetSpan_PersonId());
// …
[SecondaryKey(2), NonUnique]
[SecondaryKey(1, keyOrder: 0), NonUnique]
public Gender Gender { get; init; }
}
public Samples.Person Deserialize(
ref MessagePack.MessagePackReader reader,
MessagePack.MessagePackSerializerOptions options)
{
// …
}
public string Name { get; init; }
}
ズ
}


# Page. 9

![Page Image](https://bcdn.docswell.com/page/PJRMGR19E9.jpg)

MessagePackCompiler（mpc）
• IL2CPP下のUnityではフォーマッタの事前生成が必要（AOT Code Generation）
• mpcを用いて実行前にコード生成しておく
dotnet tool install --global MessagePack.Generator
// Simple Sample:
dotnet mpc -i &quot;..\src\Sandbox.Shared.csproj&quot; -o &quot;MessagePackGenerated.cs&quot;
// Use force map simulate DynamicContractlessObjectResolver
dotnet mpc -i &quot;..\src\Sandbox.Shared.csproj&quot; -o &quot;MessagePackGenerated.cs&quot;
-m


# Page. 10

![Page Image](https://bcdn.docswell.com/page/PEXVXRY37X.jpg)

MasterMemory.Generator
定義された
ータを操作するためのロジックを生成するツール
Person person = db.PersonTable.FindByPersonId(3);
RangeView&lt;Person&gt; persons =
db.PersonTable.FindByGender(Gender.Male);
MasterMemory.Generator.exe
-i “C:\UnitySample”
-o “C:\UnitySample\Generated&quot;
-n &quot;UnitySample&quot;
[MemoryTable(&quot;person&quot;), MessagePackObject(true)]
public record Person
{
[PrimaryKey]
public int PersonId { get; set; }
[SecondaryKey(0), NonUnique]
[SecondaryKey(1, keyOrder: 1), NonUnique]
public int Age { get; set; }
[SecondaryKey(2), NonUnique]
[SecondaryKey(1, keyOrder: 0), NonUnique]
public Gender Gender { get; set; }
public string Name { get; set; }
デ
}


# Page. 11

![Page Image](https://bcdn.docswell.com/page/3EKQWR3NED.jpg)

MasterMemory v3の変更点


# Page. 12

![Page Image](https://bcdn.docswell.com/page/L73P18GZE5.jpg)

前提: MessagePack v3の ップ ートについて
• v3（v3.0.3）にて、フォーマッタの事前生成がSource Generator化された
• プロジェクトコードのコンパイル時にフォーマッタが自動生成される
• 上記の対応に伴い、mpcが不要になった
デ
ア
https://github.com/MessagePack-CSharp/MessagePack-CSharp/releases/tag/v3.0.3


# Page. 13

![Page Image](https://bcdn.docswell.com/page/87DLXM14EG.jpg)

MasterMemory v3の ップ ート
• MessagePack v3が取り込まれた
• これによりMessagePackのSource Generator対応が取り込まれた
• あわせて、MasterMemory.GeneratorがSource Generator化された
• MasterMemoryのコード生成に関する実装が、すべてSource Generator化された
デ
ア
https://neue.cc/2024/12/20_mastermemory_v3.html


# Page. 14

![Page Image](https://bcdn.docswell.com/page/VJP2PRQVJ8.jpg)

MasterMemory v3の導入方法


# Page. 15

![Page Image](https://bcdn.docswell.com/page/2EVD2R5REQ.jpg)

インストール
だ
NuGet For Unityで「MasterMemory」をインストールする（
け！）


# Page. 16

![Page Image](https://bcdn.docswell.com/page/57GYRM667L.jpg)

asmdef を切る場合の設定
“Override References” をONにし、”Assembly References”にDLLを設定


# Page. 17

![Page Image](https://bcdn.docswell.com/page/4EQMVR42JP.jpg)

各アセン
リごとに「MasterMemoryGeneratorOptions」を設定する
using MasterMemory;
v2以前ではコマンドラインのオプションで指定していた箇所
[assembly: MasterMemoryGeneratorOptions(
Namespace = &quot;Samples&quot;,
IsReturnNullIfKeyNotFound = false,
PrefixClassName = &quot;Hoge&quot;
)]
namespace System.Runtime.CompilerServices
{
internal sealed class IsExternalInit { }
}
Initプロパティを利用したい場合は定義
ブ
デ
ータベースの設定


# Page. 18

![Page Image](https://bcdn.docswell.com/page/KJ4VM8QPE1.jpg)

MasterMemory v3の使い方


# Page. 19

![Page Image](https://bcdn.docswell.com/page/LE1382PXJG.jpg)

デ
ータの定義
v2以前と比べ、利用方法に変更はない
[MemoryTable(&quot;person&quot;), MessagePackObject(true)]
public record Person
{
[PrimaryKey]
public int PersonId { get; init; }
[SecondaryKey(0), NonUnique]
[SecondaryKey(1, keyOrder: 1), NonUnique]
public int Age { get; init; }
[SecondaryKey(2), NonUnique]
[SecondaryKey(1, keyOrder: 0), NonUnique]
public Gender Gender { get; init; }
public string Name { get; init; }
}


# Page. 20

![Page Image](https://bcdn.docswell.com/page/GEWPZR2KJ2.jpg)

ゲ
デ
ータベースの書き出し
v2以前と比べ、利用方法に変更はない
var builder = new DatabaseBuilder();
ームごとに管理されている
マスターデータを読み込んで
builder.Append(new Person[]
{
new() { PersonId = 1, Age = 20, Gender = Gender.Male, Name = &quot;John&quot; },
new() { PersonId = 2, Age = 22, Gender = Gender.Female, Name = &quot;Jane&quot; },
new() { PersonId = 3, Age = 24, Gender = Gender.Male, Name = &quot;Jack&quot; },
});
File.WriteAllBytes(
Path.Combine(Application.dataPath, &quot;StreamingAssets&quot;, &quot;database.bytes&quot;),
builder.Build()
);
データベースファイルとして書き出す


# Page. 21

![Page Image](https://bcdn.docswell.com/page/47ZK1RDN73.jpg)

デ
ータベースの検索
v2以前と比べ、利用方法に変更はない
var db = new MemoryDatabase(
File.ReadAllBytes(
Path.Combine(Application.dataPath, &quot;StreamingAssets&quot;, &quot;database.bytes&quot;)
)
);
Person person = db.PersonTable.FindByPersonId(3);
RangeView&lt;Person&gt; persons =
db.PersonTable.FindByGender(Gender.Male);


# Page. 22

![Page Image](https://bcdn.docswell.com/page/YJ6QLR19JV.jpg)

余談: コンパイル時のエラー
Unity 6で再現する、Unity側のバ とのこと
グ
https://x.com/neuecc/status/1870994368020296171


# Page. 23

![Page Image](https://bcdn.docswell.com/page/GJ5R184D74.jpg)

まとめ
• MasterMemory v3の、Source Generator対応に焦点を当てて紹介しました
• Source Generator対応により、導入からコード生成の手間が大幅に省けた
• これによって開発体験が大きく向上した
• MasterMemory v2からv3について利用方法の大きな変更はない
• 下回り（Source Generator対応）がメインになる
• 移行コストは低そう（Unityバージョンの要求は高いので、運用タイトルからの移行はチョット高い）
→ MasterMemory v3、積極的に使っていきたい


