Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
MasterMemory v3 最速確認会
Search
Yuichiro MUKAI
December 28, 2024
Technology
0
1.4k
MasterMemory v3 最速確認会
「【年末だよ】Unity お・と・なのLT大会 2024 」で発表した資料になります。
Yuichiro MUKAI
December 28, 2024
Tweet
Share
More Decks by Yuichiro MUKAI
See All by Yuichiro MUKAI
Timeline エディター拡張入門
yucchiy
0
1.4k
Other Decks in Technology
See All in Technology
エンジニアに定年なし! AI時代にキャリアをReboot — 学び続けて未来を創る
junjikoide
0
180
Datadog On-Call と Cloud SIEM で作る SOC 基盤
kuriyosh
0
180
仕様駆動 x Codex で 超効率開発
ismk
2
1.4k
エンジニアにとってコードと並んで重要な「データ」のお話 - データが動くとコードが見える:関数型=データフロー入門
ismk
0
510
LINE公式アカウントの技術スタックと開発の裏側
lycorptech_jp
PRO
0
370
自己的售票系統自己做!
eddie
0
440
『HOWはWHY WHATで判断せよ』 〜『ドメイン駆動設計をはじめよう』の読了報告と、本質への探求〜
panda728
PRO
5
1.7k
Proxmox × HCP Terraformで始めるお家プライベートクラウド
lamaglama39
1
200
エンタープライズ企業における開発効率化のためのコンテキスト設計とその活用
sergicalsix
1
390
「O(n log(n))のパフォーマンス」の意味がわかるようになろう
dhirabayashi
0
140
機密情報の漏洩を防げ! Webフロントエンド開発で意識すべき漏洩パターンとその対策
mizdra
PRO
9
3.2k
JJUG CCC 2025 Fall バッチ性能!!劇的ビフォーアフター
hayashiyuu1
1
260
Featured
See All Featured
Raft: Consensus for Rubyists
vanstee
140
7.2k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
31
2.7k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
5.7k
Agile that works and the tools we love
rasmusluckow
331
21k
jQuery: Nuts, Bolts and Bling
dougneiner
65
8k
Docker and Python
trallard
46
3.6k
The Cost Of JavaScript in 2023
addyosmani
55
9.2k
What's in a price? How to price your products and services
michaelherold
246
12k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.3k
The Cult of Friendly URLs
andyhume
79
6.7k
The Power of CSS Pseudo Elements
geoffreycrofte
80
6.1k
Large-scale JavaScript Application Architecture
addyosmani
514
110k
Transcript
ʲͩΑʳUnity ͓ɾͱɾͳͷLTେձ 2024 2024/12/28 @yucchiy_ MasterMemory v3 最速確認会
• MasterMemoryについてのおさらい • MasterMemoryについて • MessagePackとの関係やコード生成について • MasterMemory v3の変更点の紹介 •
Source Generator対応について • MasterMemory v3の利用方法の紹介 • 導入方法から簡単な使い方について このLTで話したいこと
自己紹介 向井 祐一郎 • 株式会社 サイバーエージェント / 株式会社アプリ ボ ット
• Lead Developer Experience • システム系の基盤開発・プロジェクトの開発支援 SNS・個人活動など • @yucchiy_(X) • Unity Weekly • https://blog.yucchiy.com/tags/unity-weekly/ • UniTips(社内有志で技術書典に執筆)
MasterMemory のおさらい
• マスター デ ータの管理に主眼を置いたインメモリ デ ータベース • 省メモリ・高速なデータベースロード・高速な検索の3点に重点を置く • 弊社導入事例:
Unity/C# ゲ ーム開発における、クライアントでのマスターデータの扱い方 • https://blog.applibot.co.jp/2024/01/19/unity-master-data/ • デ ータベースのフォーマットは MessagePack • データを読み込んで、メモリ上にデータベースを構築する • 書き出されたデータの読み込みでMessagePackのデータの解析に、 MessagePackのシリアライ ザ が必要になる MasterMemory とは https://github.com/Cysharp/MasterMemory
[MemoryTable("person"), 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; } } デ ータの定義 属性を用いて各カラムの “扱い” を定義
var db = new MemoryDatabase( File.ReadAllBytes( Path.Combine(Application.dataPath, "StreamingAssets", "database.bytes") )
); Person person = db.PersonTable.FindByPersonId(3); RangeView<Person> persons = db.PersonTable.FindByGender(Gender.Male); デ ータベースの検索 データベースの読み込み (byte[] を引数に初期化) PrimaryKeyで検索 SecondaryKeyで範囲検索
internal sealed class PersonFormatter : MessagePack.Formatters.IMessagePackFormatter<Samples.Person> { public void Serialize(
ref MessagePack.MessagePackWriter writer, Samples.Person value, MessagePack.MessagePackSerializerOptions options) { var formatterResolver = options.Resolver; writer.WriteMapHeader(4); writer.WriteRaw(GetSpan_PersonId()); // … } public Samples.Person Deserialize( ref MessagePack.MessagePackReader reader, MessagePack.MessagePackSerializerOptions options) { // … } } 独自型のシリアライ ズ のために、内部でフォーマッタが必要になる MessagePackのフォーマッタ [MemoryTable(“person”), 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; } }
MessagePackCompiler(mpc) • IL2CPP下のUnityではフォーマッタの事前生成が必要(AOT Code Generation) • mpcを用いて実行前にコード生成しておく // Simple Sample:
dotnet mpc -i "..\src\Sandbox.Shared.csproj" -o "MessagePackGenerated.cs" // Use force map simulate DynamicContractlessObjectResolver dotnet mpc -i "..\src\Sandbox.Shared.csproj" -o "MessagePackGenerated.cs" -m dotnet tool install --global MessagePack.Generator
定義された デ ータを操作するためのロジックを生成するツール MasterMemory.Generator [MemoryTable("person"), 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; } } Person person = db.PersonTable.FindByPersonId(3); RangeView<Person> persons = db.PersonTable.FindByGender(Gender.Male); MasterMemory.Generator.exe -i “C:\UnitySample” -o “C:\UnitySample\Generated" -n "UnitySample"
MasterMemory v3の変更点
前提: MessagePack v3の ア ップ デ ートについて • v3(v3.0.3)にて、フォーマッタの事前生成がSource Generator化された
• プロジェクトコードのコンパイル時にフォーマッタが自動生成される • 上記の対応に伴い、mpcが不要になった https://github.com/MessagePack-CSharp/MessagePack-CSharp/releases/tag/v3.0.3
• MessagePack v3が取り込まれた • これによりMessagePackのSource Generator対応が取り込まれた • あわせて、MasterMemory.GeneratorがSource Generator化された •
MasterMemoryのコード生成に関する実装が、すべてSource Generator化された MasterMemory v3の ア ップ デ ート https://neue.cc/2024/12/20_mastermemory_v3.html
MasterMemory v3の導入方法
NuGet For Unityで「MasterMemory」をインストールする( だ け!) インストール
“Override References” をONにし、”Assembly References”にDLLを設定 asmdef を切る場合の設定
各アセン ブ リごとに「MasterMemoryGeneratorOptions」を設定する デ ータベースの設定 using MasterMemory; [assembly: MasterMemoryGeneratorOptions( Namespace
= "Samples", IsReturnNullIfKeyNotFound = false, PrefixClassName = "Hoge" )] namespace System.Runtime.CompilerServices { internal sealed class IsExternalInit { } } v2以前ではコマンドラインのオプションで指定していた箇所 Initプロパティを利用したい場合は定義
MasterMemory v3の使い方
[MemoryTable("person"), 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; } } v2以前と比べ、利用方法に変更はない デ ータの定義
var builder = new DatabaseBuilder(); builder.Append(new Person[] { new() {
PersonId = 1, Age = 20, Gender = Gender.Male, Name = "John" }, new() { PersonId = 2, Age = 22, Gender = Gender.Female, Name = "Jane" }, new() { PersonId = 3, Age = 24, Gender = Gender.Male, Name = "Jack" }, }); File.WriteAllBytes( Path.Combine(Application.dataPath, "StreamingAssets", "database.bytes"), builder.Build() ); v2以前と比べ、利用方法に変更はない デ ータベースの書き出し ゲ ームごとに管理されている マスターデータを読み込んで データベースファイルとして書き出す
var db = new MemoryDatabase( File.ReadAllBytes( Path.Combine(Application.dataPath, "StreamingAssets", "database.bytes") )
); Person person = db.PersonTable.FindByPersonId(3); RangeView<Person> persons = db.PersonTable.FindByGender(Gender.Male); v2以前と比べ、利用方法に変更はない デ ータベースの検索
Unity 6で再現する、Unity側のバ グ とのこと 余談: コンパイル時のエラー https://x.com/neuecc/status/1870994368020296171
• MasterMemory v3の、Source Generator対応に焦点を当てて紹介しました • Source Generator対応により、導入からコード生成の手間が大幅に省けた • これによって開発体験が大きく向上した •
MasterMemory v2からv3について利用方法の大きな変更はない • 下回り(Source Generator対応)がメインになる • 移行コストは低そう(Unityバージョンの要求は高いので、運用タイトルからの移行はチョット高い) まとめ → MasterMemory v3、積極的に使っていきたい