<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Posts on Wuyukwi's Notebook</title><link>https://wuyukwi.duckdns.org/posts/</link><description>Recent content in Posts on Wuyukwi's Notebook</description><generator>Hugo</generator><language>ja</language><lastBuildDate>Tue, 08 Sep 2026 17:05:00 +0900</lastBuildDate><atom:link href="https://wuyukwi.duckdns.org/posts/index.xml" rel="self" type="application/rss+xml"/><item><title>FastAPI による軽量マイクロサービスと Webhook 自動化</title><link>https://wuyukwi.duckdns.org/posts/second-post/</link><pubDate>Tue, 08 Sep 2026 17:05:00 +0900</pubDate><guid>https://wuyukwi.duckdns.org/posts/second-post/</guid><description>個人用サーバーでタスク自動化や Webhook 連携を行うためのミニマムな設計手法について。</description></item><item><title>1GB の VPS に極小ブログと API サーバーを構築した記録</title><link>https://wuyukwi.duckdns.org/posts/first-post/</link><pubDate>Tue, 08 Sep 2026 17:00:00 +0900</pubDate><guid>https://wuyukwi.duckdns.org/posts/first-post/</guid><description>Oracle Cloud の 1GB メモリ VPS 上で、NapCatQQ を稼働させながら、常駐メモリほぼゼロの Hugo + PaperMod と FastAPI を共存させたミニマム構成の紹介。</description></item><item><title>☝️ 「汎用化したい」という衝動と、開発の現実</title><link>https://wuyukwi.duckdns.org/posts/zenn-010f3a8e5af665/</link><pubDate>Mon, 18 May 2026 17:34:45 +0900</pubDate><guid>https://wuyukwi.duckdns.org/posts/zenn-010f3a8e5af665/</guid><description>&lt;blockquote&gt;
&lt;p&gt;📌 &lt;em&gt;この記事は &lt;a href="https://zenn.dev/wuyukwi/articles/010f3a8e5af665"&gt;Zenn&lt;/a&gt; に投稿した内容のアーカイブです。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;プログラマーを数年やっていると、おそらく全員が一度は同じことを考える。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;「これ、他のプロジェクトでも使える形にしたい」&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;最初はただ動けばよかったコードが、だんだん気持ち悪く見えてくる。&lt;br&gt;
コピペも増える。責務も混ざる。依存も汚くなる。&lt;/p&gt;
&lt;p&gt;すると自然に、&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;共通化したい&lt;/li&gt;
&lt;li&gt;抽象化したい&lt;/li&gt;
&lt;li&gt;再利用可能にしたい&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;という欲求が出てくる。&lt;/p&gt;
&lt;p&gt;これは悪いことではない。むしろ健全だと思う。&lt;br&gt;
“設計”を意識し始めた証拠だから。&lt;/p&gt;
&lt;p&gt;ただ、この感覚はかなり危ない。&lt;/p&gt;
&lt;p&gt;一歩間違えると、&lt;br&gt;
簡単に「過剰設計」に転がり始める。&lt;/p&gt;
&lt;p&gt;「将来使うかもしれない」&lt;/p&gt;
&lt;p&gt;この一言が、&lt;br&gt;
過剰設計の始まりになることはかなり多い。&lt;/p&gt;
&lt;p&gt;今回は、自分がゲーム開発をやる中で感じた、&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;なぜ人は汎用化したくなるのか&lt;/li&gt;
&lt;li&gt;なぜそれが失敗しやすいのか&lt;/li&gt;
&lt;li&gt;実際どう考えるとちょうどいいのか&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;について書いてみる。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="汎用化したくなるのは実はかなり自然なこと"&gt;汎用化したくなるのは、実はかなり自然なこと&lt;/h2&gt;
&lt;p&gt;例えば、最初の頃のコードってかなり局所的になる。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if (isBoss)
{
hpBar.color = Color.red;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;みたいな、「今必要だから書いたコード」が大量にある。&lt;/p&gt;
&lt;p&gt;でも経験を積むと、&lt;br&gt;
こういうコードを見るだけで“変更コスト”を想像するようになる。&lt;/p&gt;
&lt;p&gt;「これ別のボス出たらどうするんだろう」&lt;br&gt;
「色変えるたびに if 増えるの？」&lt;br&gt;
「そもそも UI が敵情報知ってるのおかしくない？」&lt;/p&gt;
&lt;p&gt;みたいなことを考え始める。&lt;/p&gt;
&lt;p&gt;つまり汎用化欲求の正体って、単なる意識高い設計趣味ではなく、&lt;/p&gt;
&lt;p&gt;“変更に弱いコードへの違和感”&lt;/p&gt;
&lt;p&gt;なんだと思う。&lt;/p&gt;
&lt;p&gt;だからある程度コードを書いた人ほど、自然と抽象化に向かう。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="実際汎用化にはかなり強いメリットがある"&gt;実際、汎用化にはかなり強いメリットがある&lt;/h2&gt;
&lt;p&gt;これは間違いない。&lt;/p&gt;
&lt;h3 id="1-依存に敏感になる"&gt;1. 「依存」に敏感になる&lt;/h3&gt;
&lt;p&gt;再利用を意識すると、まずベタ結合が気になり始める。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;直接参照&lt;/li&gt;
&lt;li&gt;Singleton ベタ依存&lt;/li&gt;
&lt;li&gt;MonoBehaviour 神クラス&lt;/li&gt;
&lt;li&gt;Inspector 配線地獄&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;みたいなものを避けたくなる。&lt;/p&gt;
&lt;p&gt;結果として、&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;責務分離&lt;/li&gt;
&lt;li&gt;Interface 化&lt;/li&gt;
&lt;li&gt;データ駆動&lt;/li&gt;
&lt;li&gt;疎結合&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;みたいな方向へ進む。&lt;/p&gt;</description></item><item><title>🧊 【Unity】10万オブジェクトを回転させたらどこがボトルネックになるのか（後編：ISystemで一桁msへ）</title><link>https://wuyukwi.duckdns.org/posts/zenn-8577fbf1074840/</link><pubDate>Wed, 01 Apr 2026 12:47:15 +0900</pubDate><guid>https://wuyukwi.duckdns.org/posts/zenn-8577fbf1074840/</guid><description>&lt;blockquote&gt;
&lt;p&gt;📌 &lt;em&gt;この記事は &lt;a href="https://zenn.dev/wuyukwi/articles/8577fbf1074840"&gt;Zenn&lt;/a&gt; に投稿した内容のアーカイブです。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="はじめに"&gt;はじめに&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://zenn.dev/wuyukwi/articles/88800f31f667f3"&gt;前回&lt;/a&gt;は、Job System + Burst を使って&lt;br&gt;
&lt;strong&gt;10万オブジェクトの回転処理（46ms → 3.5ms）&lt;/strong&gt; まで最適化しました。&lt;/p&gt;
&lt;p&gt;ただしその時点でも、フレーム全体としてはまだ重く、&lt;br&gt;
ボトルネックはレンダリング側に残っていました。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="なぜjob-systemだけでは不十分だったのか"&gt;なぜJob Systemだけでは不十分だったのか&lt;/h2&gt;
&lt;p&gt;前回の時点で回転処理自体はかなり軽くなっていましたが、&lt;br&gt;
それでもフレーム全体としては大きな負荷が残っていました。&lt;/p&gt;
&lt;p&gt;原因は、描画周りの処理です。&lt;/p&gt;
&lt;p&gt;たとえロジック（Job）が高速でも、メインスレッド側では依然として&lt;br&gt;
10万個の &lt;code&gt;MeshRenderer&lt;/code&gt; を個別に処理する必要があります。&lt;/p&gt;
&lt;p&gt;具体的には以下のような処理です：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Culling（可視判定）&lt;/li&gt;
&lt;li&gt;Bounding Volume（バウンディング更新）&lt;/li&gt;
&lt;li&gt;RenderQueue（描画順の整理）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これらがすべて「オブジェクト単位」で実行されるため、&lt;br&gt;
結果として大きなCPU負荷になっていました。&lt;/p&gt;
&lt;p&gt;この問題に対するアプローチが、Entities Graphicsです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;目標：&lt;br&gt;
→ GameObjectベースのオブジェクトをEntityに変換する&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;仕組み：&lt;br&gt;
→ 変換後は、これらの処理を &lt;code&gt;Entities Graphics&lt;/code&gt; が内部的に管理し、&lt;br&gt;
&lt;code&gt;BatchRendererGroup&lt;/code&gt; を利用して描画処理をまとめて実行します。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;その結果：&lt;/p&gt;
&lt;p&gt;数万〜数十万単位のオブジェクトでも、&lt;br&gt;
ごく少数のバッチとして扱えるようになります。&lt;/p&gt;
&lt;h2 id="-結果"&gt;■ 結果&lt;/h2&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://static.zenn.studio/user-upload/8eac221c088d-20260401.gif"&gt;&lt;br&gt;
今回は DOTS（Entities + Entities Graphics）に移行した結果：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;フレーム時間：約120ms → 約9ms&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;110FPS前後で安定&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ほぼ別物レベルまで改善しています。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-比較"&gt;■ 比較&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;指標&lt;/th&gt;
&lt;th&gt;改造前（GameObject）&lt;/th&gt;
&lt;th&gt;改造後（Pure DOTS）&lt;/th&gt;
&lt;th&gt;改善&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Batches&lt;/td&gt;
&lt;td&gt;~120,000&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;74&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;約1486倍削減&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SetPass Calls&lt;/td&gt;
&lt;td&gt;56&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;26&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;約2.1倍改善&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tris / Verts&lt;/td&gt;
&lt;td&gt;不安定&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;安定&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;描画の一貫性向上&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Frame Time&lt;/td&gt;
&lt;td&gt;120ms（8FPS）&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;9ms（110FPS）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;約13倍高速化&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="-profilerを見ると何が起きているか"&gt;■ Profilerを見ると何が起きているか&lt;/h2&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://static.zenn.studio/user-upload/561808254336-20260401.png"&gt;&lt;br&gt;
&lt;img loading="lazy" src="https://static.zenn.studio/user-upload/d2021f89924c-20260401.png"&gt;&lt;br&gt;
Profilerを確認すると：&lt;/p&gt;</description></item><item><title>🧊 【Unity】10万オブジェクトを回転させたらどこがボトルネックになるのか（前編：LateUpdateとJob System）</title><link>https://wuyukwi.duckdns.org/posts/zenn-88800f31f667f3/</link><pubDate>Tue, 31 Mar 2026 17:31:45 +0900</pubDate><guid>https://wuyukwi.duckdns.org/posts/zenn-88800f31f667f3/</guid><description>&lt;blockquote&gt;
&lt;p&gt;📌 &lt;em&gt;この記事は &lt;a href="https://zenn.dev/wuyukwi/articles/88800f31f667f3"&gt;Zenn&lt;/a&gt; に投稿した内容のアーカイブです。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;最近、DOTS（Data-Oriented Tech Stack）が実際どのくらい効果があるのか気になっていたので、&lt;br&gt;
簡単な検証を兼ねて触ってみることにしました。&lt;/p&gt;
&lt;p&gt;せっかくなので「大量のオブジェクトを動かした場合にどこがボトルネックになるのか？」も含めて、&lt;br&gt;
段階的に確認していこうと思います。&lt;/p&gt;
&lt;p&gt;この記事ではまず、LateUpdateでの回転処理のボトルネックと、&lt;br&gt;
Job Systemによる最適化の効果にフォーカスします。&lt;/p&gt;
&lt;p&gt;レンダリング周り（CullingやDrawCall）については、次回以降で触れる予定です。&lt;/p&gt;
&lt;h2 id="-検証環境"&gt;■ 検証環境&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;CPU：i7-12700K&lt;/li&gt;
&lt;li&gt;GPU：RTX 3070&lt;/li&gt;
&lt;li&gt;Unity：URPの新規プロジェクト&lt;/li&gt;
&lt;li&gt;オブジェクト数：10万（Cube）&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-テスト内容"&gt;■ テスト内容&lt;/h2&gt;
&lt;p&gt;シンプルに「10万個のCubeを生成して回転させるだけ」です。&lt;br&gt;
&lt;img loading="lazy" src="https://static.zenn.studio/user-upload/96aecb2d5f9f-20260331.gif"&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;BoxColliderは削除&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ランダム位置に配置&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;各オブジェクトにランダムな回転軸&lt;/p&gt;
&lt;p&gt;void Start()
{
var root = new GameObject(&amp;ldquo;CubeRoot&amp;rdquo;).transform;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;for (int i = 0; i &amp;lt; spawnCount; i++)
{
var go = Instantiate(prefab, Random.insideUnitSphere * 50f, Quaternion.identity, root);
transforms.Add(go.transform);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;void LateUpdate()
{
float dt = Time.deltaTime;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;for (int i = 0; i &amp;lt; transforms.Count; i++)
{
transforms[i].Rotate(rotationAxes[i], 100f * dt);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;</description></item><item><title>🙌 なぜ Unity は C# を選び、Unreal は選ばなかったのかについての個人の考察</title><link>https://wuyukwi.duckdns.org/posts/zenn-97b70df23bd792/</link><pubDate>Wed, 11 Mar 2026 19:31:51 +0900</pubDate><guid>https://wuyukwi.duckdns.org/posts/zenn-97b70df23bd792/</guid><description>&lt;blockquote&gt;
&lt;p&gt;📌 &lt;em&gt;この記事は &lt;a href="https://zenn.dev/wuyukwi/articles/97b70df23bd792"&gt;Zenn&lt;/a&gt; に投稿した内容のアーカイブです。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="はじめに"&gt;はじめに&lt;/h1&gt;
&lt;p&gt;ゲームエンジンの言語の話になると、よくこんな対比が出てきます。&lt;/p&gt;
&lt;p&gt;Unity は C#。&lt;br&gt;
Unreal は C++ と Blueprint。&lt;/p&gt;
&lt;p&gt;この違い、ただの好みではありません。&lt;br&gt;
エンジンの設計思想そのものに関わっています。&lt;/p&gt;
&lt;p&gt;C# が優れているとか、C++ が古いとか、そういう単純な話ではない。&lt;br&gt;
両者はそもそも目指している開発体験が違うのです。&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id="unity-が辿った言語統一の歴史"&gt;Unity が辿った言語統一の歴史&lt;/h1&gt;
&lt;p&gt;今でこそ「Unity といえば C#」という印象がありますが、最初からそうだったわけではありません。&lt;br&gt;
初期の Unity では、開発者のバックグラウンドに合わせて複数の言語を選択できるのが特徴でした。&lt;/p&gt;
&lt;p&gt;具体的には次の3つです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;UnityScript&lt;/strong&gt; （JavaScript 風の独自言語）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Boo&lt;/strong&gt; （Python 風の言語）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当時の Unity は「スクリプト言語の自由度」を売りの一つにしており、Web 開発者は UnityScript、Python 系に慣れている人は Boo、という具合に選べるようになっていました。&lt;/p&gt;
&lt;p&gt;しかし、この方針は長くは続きませんでした。&lt;/p&gt;
&lt;p&gt;Unity 2017 頃から段階的に非推奨となり、&lt;br&gt;
&lt;strong&gt;Unity 2019.1 を最後に UnityScript と Boo は完全に削除&lt;/strong&gt; されます。&lt;/p&gt;
&lt;p&gt;結果として、Unity のスクリプト言語は &lt;strong&gt;C# のみ&lt;/strong&gt; に統一されました。&lt;/p&gt;
&lt;p&gt;参考&lt;br&gt;
&lt;a href="https://discussions.unity.com/t/which-release-removed-support-unityscript-and-boo/1624299"&gt;https://discussions.unity.com/t/which-release-removed-support-unityscript-and-boo/1624299&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;なぜこうなったのか。理由はいくつかあります。&lt;/p&gt;
&lt;p&gt;まず、複数言語の維持コストです。&lt;br&gt;
エンジン側はコンパイラ、ツールチェーン、デバッグ環境などをすべてサポートし続ける必要があります。&lt;/p&gt;
&lt;p&gt;さらに重要なのは、UnityScript と Boo の実態です。&lt;br&gt;
これらは見た目こそ別言語でしたが、内部では Mono 上で動作するスクリプトでした。&lt;/p&gt;</description></item><item><title>🎉 Git を「完全に理解」するためのデータ構造の話</title><link>https://wuyukwi.duckdns.org/posts/zenn-12736c19b679d6/</link><pubDate>Wed, 25 Feb 2026 17:25:36 +0900</pubDate><guid>https://wuyukwi.duckdns.org/posts/zenn-12736c19b679d6/</guid><description>&lt;blockquote&gt;
&lt;p&gt;📌 &lt;em&gt;この記事は &lt;a href="https://zenn.dev/wuyukwi/articles/12736c19b679d6"&gt;Zenn&lt;/a&gt; に投稿した内容のアーカイブです。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="はじめに"&gt;はじめに&lt;/h1&gt;
&lt;p&gt;Git を使っていて、こんな感覚になったことはありませんか？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;コマンドは打てるけど、何が起きているか分からない&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;merge と rebase の違いを、説明しろと言われると詰まる&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;conflict が出ると、なぜ衝突したのか理解できない&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;多くの Git 解説記事は、&lt;br&gt;
&lt;strong&gt;「何を打つか」&lt;/strong&gt; は丁寧に教えてくれますが、&lt;br&gt;
&lt;strong&gt;「なぜそうなるか」&lt;/strong&gt; までは踏み込んでくれません。&lt;/p&gt;
&lt;p&gt;その結果、&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;なんとなく使えているが、仕組みはよく分からない&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;という状態に陥りがちです。&lt;/p&gt;
&lt;p&gt;この記事では、コマンドの説明はほぼ行いません。&lt;br&gt;
代わりに、&lt;strong&gt;Git の内部構造をデータ構造として捉え直す&lt;/strong&gt; ことで、&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;「あ、そういうことだったのか」&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;と腑に落ちる理解を目指します。&lt;/p&gt;
&lt;p&gt;少しだけ &lt;strong&gt;グラフ理論&lt;/strong&gt; と &lt;strong&gt;ポインタの概念（C 言語）&lt;/strong&gt; の素養があると、&lt;br&gt;
かなりスムーズに理解できると思います。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="git-の正体木構造ではなく-dag有向非巡回グラフ"&gt;Git の正体：木構造ではなく DAG（有向非巡回グラフ）&lt;/h2&gt;
&lt;p&gt;多くの人は、Git の履歴を「木構造」としてイメージしています。&lt;/p&gt;
&lt;p&gt;しかし、これは正確ではありません。&lt;/p&gt;
&lt;p&gt;Git の本質は &lt;a href="https://ja.wikipedia.org/wiki/%E6%9C%89%E5%90%91%E9%9D%9E%E5%B7%A1%E5%9B%9E%E3%82%B0%E3%83%A9%E3%83%95"&gt;有向非巡回グラフ&lt;/a&gt;です。&lt;/p&gt;
&lt;h3 id="commit-はノード"&gt;Commit は「ノード」&lt;/h3&gt;
&lt;p&gt;すべての commit は、グラフ上の &lt;strong&gt;ノード&lt;/strong&gt; です。&lt;/p&gt;
&lt;p&gt;各 commit は、&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;ファイルのスナップショット&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;親 commit への参照（1 個または 2 個）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;を持っています。&lt;/p&gt;
&lt;h3 id="親が-2-個になる瞬間--merge"&gt;親が 2 個になる瞬間 = merge&lt;/h3&gt;
&lt;p&gt;通常の commit は親が 1 つですが、&lt;br&gt;
merge commit は &lt;strong&gt;親を 2 つ&lt;/strong&gt; 持ちます。&lt;/p&gt;</description></item><item><title>☝️ デバッグ UI を書かずに Unity のデバッグ環境を成立させる設計と実装</title><link>https://wuyukwi.duckdns.org/posts/zenn-2d31ee3e52b29e/</link><pubDate>Wed, 18 Feb 2026 13:18:23 +0900</pubDate><guid>https://wuyukwi.duckdns.org/posts/zenn-2d31ee3e52b29e/</guid><description>&lt;blockquote&gt;
&lt;p&gt;📌 &lt;em&gt;この記事は &lt;a href="https://zenn.dev/wuyukwi/articles/2d31ee3e52b29e"&gt;Zenn&lt;/a&gt; に投稿した内容のアーカイブです。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="はじめに"&gt;はじめに&lt;/h1&gt;
&lt;p&gt;Unity で開発していると、&lt;br&gt;
&lt;strong&gt;実行中にパラメータを触りながら挙動を確認したい&lt;/strong&gt;&lt;br&gt;
という場面は、ほぼ毎日のように出てきます。&lt;/p&gt;
&lt;p&gt;最初のうちは、Unity 標準の仕組みを使って&lt;br&gt;
簡単な Runtime Debug UI を用意すれば十分でした。&lt;/p&gt;
&lt;p&gt;ただ、プロジェクトが進み、&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;デバッグ項目が増える&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;調整対象が増える&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;複数人で同時に触る&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;という状況になるにつれ、&lt;br&gt;
&lt;strong&gt;「その場しのぎ」で作ったデバッグ UI が、確実に足を引っ張る&lt;/strong&gt;&lt;br&gt;
ようになってきます。&lt;/p&gt;
&lt;p&gt;この段階で欲しくなったのが、&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;壊れにくく、拡張しやすく、&lt;br&gt;
プロジェクトと一緒に「育てていける」デバッグ基盤&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;でした。&lt;/p&gt;
&lt;p&gt;この記事では、&lt;br&gt;
そのために設計した &lt;strong&gt;自作 Runtime Debug システム&lt;/strong&gt; について、&lt;br&gt;
&lt;strong&gt;設計意図と実装の要点&lt;/strong&gt; を中心にまとめます。&lt;/p&gt;
&lt;h1 id="何が問題だったのか"&gt;何が問題だったのか&lt;/h1&gt;
&lt;p&gt;問題の本質は、&lt;strong&gt;「UI をどう実装するか」&lt;/strong&gt; ではありませんでした。&lt;/p&gt;
&lt;p&gt;本当に困っていたのは、&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Debug 項目の追加・削除が面倒&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;どこに何のデバッグ設定があるのか分からない&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;不要になった項目が整理されず、蓄積していく&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;という &lt;strong&gt;運用面の破綻&lt;/strong&gt; です。&lt;/p&gt;
&lt;p&gt;特に後半になると、&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;「デバッグ環境のせいで、デバッグそのものがやりにくい」&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;という、本末転倒な状態になりがちでした。&lt;/p&gt;
&lt;h1 id="目指したゴール"&gt;目指したゴール&lt;/h1&gt;
&lt;p&gt;今回の設計で目指したゴールは、かなり明確です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;UI を書かずに Debug 項目を追加できる&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;構造が自然に整理され続ける&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;無効化・除去が簡単&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;プロジェクト規模が大きくなっても破綻しない&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;つまり、&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;「運用しても壊れない設計」&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;を最優先にしました。&lt;/p&gt;
&lt;h1 id="全体構成"&gt;全体構成&lt;/h1&gt;
&lt;p&gt;全体の流れは、次のようになります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;起動
↓
RuntimeInitializeOnLoadMethod
↓
DebugManager 自動生成
↓
DebugOption 自動登録
↓
Reflection による項目収集
↓
UI 自動生成 &amp;amp; バインディング
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ここで重視したのは、&lt;/p&gt;</description></item><item><title>🧠 AndroidビルドでPlayFabのSecretKeyが丸見えだった話と、ビルド時に自動変換する対策</title><link>https://wuyukwi.duckdns.org/posts/zenn-6817fe00d739b4/</link><pubDate>Thu, 05 Feb 2026 14:15:44 +0900</pubDate><guid>https://wuyukwi.duckdns.org/posts/zenn-6817fe00d739b4/</guid><description>&lt;blockquote&gt;
&lt;p&gt;📌 &lt;em&gt;この記事は &lt;a href="https://zenn.dev/wuyukwi/articles/6817fe00d739b4"&gt;Zenn&lt;/a&gt; に投稿した内容のアーカイブです。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="はじめに"&gt;はじめに&lt;/h3&gt;
&lt;p&gt;PlayFab を使ったプロジェクトで、&lt;br&gt;
&lt;code&gt;TitleId&lt;/code&gt; や &lt;code&gt;DeveloperSecretKey&lt;/code&gt; をどう管理するかは、最初に一度は悩むポイントだと思います。&lt;/p&gt;
&lt;p&gt;自分も最初は深く考えずに、&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const string TitleId = &amp;quot;XXXX&amp;quot;;
const string DeveloperSecretKey = &amp;quot;YYYY&amp;quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;のようにコードに直接書いていました。&lt;/p&gt;
&lt;p&gt;ところが Android ビルド後に apk を確認してみると、&lt;br&gt;
&lt;code&gt;strings&lt;/code&gt; コマンドで &lt;strong&gt;平文のままキーが抜ける&lt;/strong&gt; ことに気づき、&lt;br&gt;
「これはさすがにまずいな……」となったのが今回のきっかけです。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="問題点apk-内に平文で残る"&gt;問題点：apk 内に平文で残る&lt;/h3&gt;
&lt;p&gt;C# のコードに直接書いた文字列は、&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;IL2CPP でも&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;難読化をしていても&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最終的に &lt;strong&gt;文字列リテラルとして apk 内に残ります&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;つまり、&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;strings app.apk
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;を叩くだけで、TitleId や SecretKey が見えてしまう状態でした。&lt;/p&gt;
&lt;p&gt;もちろん「完全に隠す」ことは不可能ですが、&lt;br&gt;
&lt;strong&gt;平文で置いておくのはリスクが高すぎる&lt;/strong&gt; と判断しました。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="方針コードには平文を置かない"&gt;方針：コードには平文を置かない&lt;/h3&gt;
&lt;p&gt;今回の方針はシンプルです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;ソースコード内に &lt;strong&gt;平文のキーを一切書かない&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ビルド時に Editor 側で変換・生成する&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ランタイムでは最小限の復号処理だけ行う&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;いわゆる「秘匿」というより、&lt;br&gt;
&lt;strong&gt;apk を覗かれたときに即バレしない状態を作る&lt;/strong&gt; のが目的です。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="実装概要"&gt;実装概要&lt;/h3&gt;
&lt;p&gt;実装は以下の流れにしました。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Editor フォルダ内&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>🐈 UnityのEditor拡張で「設定の保存先」に毎回悩む話</title><link>https://wuyukwi.duckdns.org/posts/zenn-b2fdefc2c53908/</link><pubDate>Mon, 02 Feb 2026 17:57:13 +0900</pubDate><guid>https://wuyukwi.duckdns.org/posts/zenn-b2fdefc2c53908/</guid><description>&lt;blockquote&gt;
&lt;p&gt;📌 &lt;em&gt;この記事は &lt;a href="https://zenn.dev/wuyukwi/articles/b2fdefc2c53908"&gt;Zenn&lt;/a&gt; に投稿した内容のアーカイブです。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Unity でエディタ拡張を書いていると、&lt;br&gt;
「この設定、どこに保存するのが正解なんだろう？」&lt;br&gt;
と悩む場面がよくあります。&lt;/p&gt;
&lt;p&gt;そのときにまず候補に上がるのが &lt;code&gt;EditorPrefs&lt;/code&gt; です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;bool isOpen = EditorPrefs.GetBool(&amp;quot;MyTool_Foldout&amp;quot;, false);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;とても手軽で便利ですが、使い方を間違えると&lt;br&gt;
&lt;strong&gt;チーム開発では地味に事故りやすい&lt;/strong&gt; API でもあります。&lt;/p&gt;
&lt;p&gt;この記事では、&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;EditorPrefs は何のための仕組みなのか&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;どんな用途に向いているのか&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;逆に使ってはいけないケース&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;を整理してみます。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="editorprefs-とは何か"&gt;EditorPrefs とは何か&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;EditorPrefs&lt;/code&gt; は、&lt;strong&gt;Unity エディタ専用の設定保存機構&lt;/strong&gt; です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;プロジェクト単位ではない&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ユーザー（マシン）単位で保存される&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;バージョン管理の対象外&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;という特徴があります。&lt;/p&gt;
&lt;p&gt;つまり、&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;「この PC で、この Unity を使っている自分だけの設定」&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;を保存するためのものです。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="保存場所はどこ"&gt;保存場所はどこ？&lt;/h2&gt;
&lt;p&gt;EditorPrefs の中身は、OS ごとに以下の場所に保存されます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Windows：レジストリ&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;macOS：&lt;code&gt;~/Library/Preferences&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Linux：&lt;code&gt;~/.config&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;この時点で分かる通り、&lt;br&gt;
&lt;strong&gt;Git にも SVN にも乗りません&lt;/strong&gt; 。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="向いているユースケース"&gt;向いているユースケース&lt;/h2&gt;
&lt;h3 id="1-エディタ-ui-の表示状態"&gt;1. エディタ UI の表示状態&lt;/h3&gt;
&lt;p&gt;例えば、&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;ツールウィンドウの開閉状態&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;折りたたみ（Foldout）の ON / OFF&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;最後に選択していたタブ&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;こういった「見た目の状態」は、EditorPrefs と非常に相性が良いです。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;bool isOpen = EditorPrefs.GetBool(&amp;quot;MyTool_Foldout&amp;quot;, false);&lt;/code&gt;&lt;/p&gt;</description></item><item><title>😎 「リンクリストはもう使われない」のか？</title><link>https://wuyukwi.duckdns.org/posts/zenn-f01b1a0f7f2884/</link><pubDate>Mon, 02 Feb 2026 15:20:02 +0900</pubDate><guid>https://wuyukwi.duckdns.org/posts/zenn-f01b1a0f7f2884/</guid><description>&lt;blockquote&gt;
&lt;p&gt;📌 &lt;em&gt;この記事は &lt;a href="https://zenn.dev/wuyukwi/articles/f01b1a0f7f2884"&gt;Zenn&lt;/a&gt; に投稿した内容のアーカイブです。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="2026年のハードウェア前提で考えるデータ構造の現実"&gt;――2026年のハードウェア前提で考えるデータ構造の現実&lt;/h2&gt;
&lt;p&gt;エンジニア向けの記事や SNS で、&lt;br&gt;
「リンクリストはもう終わった」&lt;br&gt;
という表現を見かけることがあります。&lt;/p&gt;
&lt;p&gt;最初にこの話を聞いたとき、正直かなり極端だなと思いました。&lt;br&gt;
ただ、実務でパフォーマンスを意識した設計や実装を重ねていくと、この言い方が&lt;strong&gt;完全に間違っているとも言い切れない&lt;/strong&gt; 、という感覚になってきます。&lt;/p&gt;
&lt;p&gt;この記事では、「リンクリストがなぜ避けられるようになったのか」「それでも今なお使われ続けている理由」を、&lt;strong&gt;現代の CPU・メモリ構成を前提に&lt;/strong&gt; 整理してみます。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="教科書的な理解と現実のズレ"&gt;教科書的な理解と、現実のズレ&lt;/h2&gt;
&lt;p&gt;学生時代にデータ構造を学んだとき、ほとんどの人が次のように習ったはずです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;配列：途中への挿入・削除は O(N)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;リンクリスト：挿入・削除は O(1)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;理論としては正しいです。&lt;br&gt;
ただし、ここには&lt;strong&gt;重要な前提条件&lt;/strong&gt; があります。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;メモリアクセスのコストはすべて同じである&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;現実のハードウェアでは、これは成立しません。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="キャッシュ階層という無視できない現実"&gt;キャッシュ階層という「無視できない現実」&lt;/h2&gt;
&lt;p&gt;現代の CPU では、メモリは階層構造になっています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;L1 キャッシュ：数サイクル&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;L2 キャッシュ：十数サイクル&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;L3 キャッシュ：数十サイクル&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;メインメモリ（RAM）：数百サイクル&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;この差は無視できるものではありません。&lt;br&gt;
特に問題になるのが、&lt;strong&gt;アクセスパターンが予測できない場合&lt;/strong&gt; です。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="リンクリストが不利になる理由"&gt;リンクリストが不利になる理由&lt;/h2&gt;
&lt;p&gt;典型的なリンクリストは、ノードがメモリ上に散らばって配置されます。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Node A -&amp;gt; Node B -&amp;gt; Node C&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;見た目はシンプルですが、実際のアドレスは次のようになっているかもしれません。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;0x1000 -&amp;gt; 0x8F20 -&amp;gt; 0x3A10&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;リンクリストを走査する場合、&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;現在のノードを読み込む&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;next ポインタを読む&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;次のアドレスが分かってから、次の読み込みを行う&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;という&lt;strong&gt;強い依存関係のある処理&lt;/strong&gt; になります。&lt;/p&gt;
&lt;p&gt;CPU のプリフェッチ機構は、連続したアクセス（配列など）は得意ですが、&lt;br&gt;
リンクリストのようなポインタ追跡はほとんど先読みできません。&lt;/p&gt;
&lt;p&gt;結果として、&lt;strong&gt;キャッシュミスが頻発&lt;/strong&gt; します。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="配列vectorが速い本当の理由"&gt;配列（vector）が速い本当の理由&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;std::vector&lt;/code&gt; や配列を順番に処理しているとき、&lt;br&gt;
実際には CPU はすでに次のデータをキャッシュに読み込んでいます。&lt;/p&gt;</description></item><item><title>📃 UE5 における Gameplay Ability System ＆ Game Features を「いつ使うべきか」という個人的な考察</title><link>https://wuyukwi.duckdns.org/posts/zenn-a3cb27df6b605c/</link><pubDate>Wed, 21 Jan 2026 20:30:30 +0900</pubDate><guid>https://wuyukwi.duckdns.org/posts/zenn-a3cb27df6b605c/</guid><description>&lt;blockquote&gt;
&lt;p&gt;📌 &lt;em&gt;この記事は &lt;a href="https://zenn.dev/wuyukwi/articles/a3cb27df6b605c"&gt;Zenn&lt;/a&gt; に投稿した内容のアーカイブです。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;UE5 には &lt;strong&gt;Gameplay Ability System（GAS）&lt;/strong&gt; や &lt;strong&gt;Game Features（GF）&lt;/strong&gt; といった、拡張性と再利用性を強く意識した公式フレームワークが用意されています。&lt;/p&gt;
&lt;p&gt;最近では Epic Games もこれらの利用を積極的に推奨しており、&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;「公式が用意しているのだから、最初から使うべきでは？」&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;と感じる方も少なくないと思います。&lt;/p&gt;
&lt;p&gt;しかし、&lt;strong&gt;すべてのプロジェクト・すべての開発フェーズで導入すべきか&lt;/strong&gt; というと、&lt;br&gt;
個人的には &lt;strong&gt;明確にそうではない&lt;/strong&gt; と考えています。&lt;/p&gt;
&lt;p&gt;この記事では&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;なぜプロジェクト初期で GAS / Game Features を導入すると負担になりやすいのか&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;どの段階で導入すると真価を発揮するのか&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;について、自身の経験をもとに整理します。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="結論gas--game-features-は優秀だが導入時期が重要"&gt;結論：GAS / Game Features は優秀だが「導入時期」が重要&lt;/h2&gt;
&lt;p&gt;まず前提として&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GAS は長年運用され、&lt;strong&gt;大規模タイトルで実績のあるシステム&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Game Features も &lt;strong&gt;機能分離・モジュール化を重視した現代的な設計&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;であり、品質や思想そのものに問題があるわけではありません。&lt;/p&gt;
&lt;p&gt;問題になるのは &lt;strong&gt;「いつ導入するか」&lt;/strong&gt; です。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="プロジェクト初期プロトタイプ段階で起きやすい問題"&gt;プロジェクト初期・プロトタイプ段階で起きやすい問題&lt;/h2&gt;
&lt;h3 id="-フレームワークが過剰に重い"&gt;① フレームワークが過剰に重い&lt;/h3&gt;
&lt;p&gt;GAS や Game Features は&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;高い汎用性&lt;/li&gt;
&lt;li&gt;拡張を前提とした設計&lt;/li&gt;
&lt;li&gt;長期運用への耐性&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;を重視しています。&lt;/p&gt;
&lt;p&gt;その結果&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;クラス構造が複雑&lt;/li&gt;
&lt;li&gt;Ability / Attribute / Effect / GameplayTag など前提概念が多い&lt;/li&gt;
&lt;li&gt;正しく使い始めるまでの学習コストが高い&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;という特徴があります。&lt;/p&gt;</description></item><item><title>🦔 Overwatchにおけるネットコードと予測技術の解説</title><link>https://wuyukwi.duckdns.org/posts/zenn-ee81f79477d4f9/</link><pubDate>Fri, 21 Nov 2025 13:06:29 +0900</pubDate><guid>https://wuyukwi.duckdns.org/posts/zenn-ee81f79477d4f9/</guid><description>&lt;blockquote&gt;
&lt;p&gt;📌 &lt;em&gt;この記事は &lt;a href="https://zenn.dev/wuyukwi/articles/ee81f79477d4f9"&gt;Zenn&lt;/a&gt; に投稿した内容のアーカイブです。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="はじめに高速対戦ゲームにおけるネットコードの本質"&gt;はじめに：高速対戦ゲームにおけるネットコードの本質&lt;/h2&gt;
&lt;p&gt;ゲームプレイ（GamePlay）エンジニアにとって、最重要テーマのひとつが &lt;strong&gt;ネット同期（netcode）&lt;/strong&gt; です。&lt;br&gt;
特に Overwatch のような高速リアルタイムアクションでは、&lt;strong&gt;「レスポンスの速さ（responsive）」&lt;/strong&gt; がゲーム性を決定づけます。&lt;/p&gt;
&lt;p&gt;そのため、プレイヤーの操作は &lt;strong&gt;サーバーの応答を待たずに即時反映&lt;/strong&gt; する必要があります。&lt;br&gt;
これを実現するのが &lt;strong&gt;予測（prediction / pre-presentation）&lt;/strong&gt; です。&lt;/p&gt;
&lt;p&gt;ただし、クライアントを信頼できない（チート対策）というFPSの前提は20年変わっていません。&lt;br&gt;
そのうえで「即時応答」と「サーバー権威」の両立を図るのがネットコード設計の核心になります。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="即時応答が必要な操作"&gt;即時応答が必要な操作&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;移動&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;スキル&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;武器（発射や装填などのスキル付き武器）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;当たり判定（Hit Registration）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;共通原則はただ一つ：&lt;br&gt;
&lt;strong&gt;「プレイヤーがボタンを押したら即、見た目の挙動が起きること」&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;どれほど ping が高くても、遅延を感じさせてはならない。&lt;/p&gt;
&lt;p&gt;しかし、予測を行う以上、避けられない問題があります──&lt;br&gt;
それが &lt;strong&gt;予測ミス（misprediction）&lt;/strong&gt; です。&lt;/p&gt;
&lt;p&gt;予測ミスは、&lt;br&gt;
&lt;strong&gt;「クライアント側では成功したように見えた操作が、サーバー上では成立していない」&lt;/strong&gt;&lt;br&gt;
状態を指します。&lt;/p&gt;
&lt;p&gt;Overwatch では、予測ミスが起きても「操作を遅延させる」のではなく、&lt;br&gt;
&lt;strong&gt;できる限り予測ミスを減らす設計（＝確定性 Determinism）&lt;/strong&gt; が採用されています。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="予測ミスの例サーバーとの食い違い"&gt;予測ミスの例：サーバーとの食い違い&lt;/h2&gt;
&lt;p&gt;ping 250ms。&lt;br&gt;
クライアントでは「ジャンプした」つもりでも、サーバー上では &lt;strong&gt;Mei の氷結を受けていた&lt;/strong&gt; 。&lt;br&gt;
その結果、クライアントは一度ジャンプの予測を行った後、サーバーからの正しい状態（氷結）で「強制的に巻き戻される」。&lt;/p&gt;
&lt;p&gt;このように、超高速応答を目指すほど、予測ミスが発生しやすくなります。&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id="-ここから低ミス予測を支える確定性determinism"&gt;▼ ここから：低ミス予測を支える「確定性（Determinism）」&lt;/h1&gt;
&lt;p&gt;以下では Overwatch が採用している &lt;strong&gt;ECS + Deterministic Simulation&lt;/strong&gt; の要点を整理します。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="1-時間の量子化command-frame"&gt;1. 時間の量子化：Command Frame&lt;/h2&gt;
&lt;p&gt;確定的なシミュレーションは、&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;時間の同期&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;固定更新周期&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;値の量子化&lt;/p&gt;</description></item><item><title>🧠 モダンなフレームワークは「低レイヤの理解」から遠ざけるか？</title><link>https://wuyukwi.duckdns.org/posts/zenn-27adec63ef2b94/</link><pubDate>Thu, 06 Nov 2025 12:43:17 +0900</pubDate><guid>https://wuyukwi.duckdns.org/posts/zenn-27adec63ef2b94/</guid><description>&lt;blockquote&gt;
&lt;p&gt;📌 &lt;em&gt;この記事は &lt;a href="https://zenn.dev/wuyukwi/articles/27adec63ef2b94"&gt;Zenn&lt;/a&gt; に投稿した内容のアーカイブです。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="意図ビジネス要件と低レイヤ知識の役割について考える"&gt;〜意図（ビジネス要件）と低レイヤ知識の役割について考える〜&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;「最近のエンジニアは低レイヤを知らない」──そんな声を耳にすることが増えました。&lt;br&gt;
それは本当に問題なのでしょうか？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="1-プログラミングの本質意図をコンピュータに伝えること"&gt;1. プログラミングの本質：意図をコンピュータに伝えること&lt;/h2&gt;
&lt;p&gt;プログラミングとは、人間の意図を&lt;strong&gt;コードという形でコンピュータに伝える行為&lt;/strong&gt; です。&lt;br&gt;
言語やフレームワークはそのための「伝達チャンネル」にすぎません。&lt;br&gt;
用途や目的が異なるからこそ、多様な言語やフレームワークが存在しています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;業務アプリ：可読性・保守性を重視&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ゲームやリアルタイム処理：性能やレイテンシを重視&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;研究・プロトタイピング：表現力・試行錯誤のしやすさを重視&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;重要なのは「&lt;strong&gt;何を伝えたいのか（ビジネスの意図）&lt;/strong&gt; 」であり、&lt;br&gt;
低レイヤ（ハードウェアや OS の仕組み）はそれを実現するための&lt;strong&gt;手段&lt;/strong&gt; にすぎません。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="2-抽象化はノイズ除去の進化である"&gt;2. 抽象化は「ノイズ除去」の進化である&lt;/h2&gt;
&lt;p&gt;ソフトウェア開発の歴史を振り返ると、それは常に「ノイズを減らす」試みの連続でした。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;アセンブリ言語：レジスタやメモリ操作のノイズを扱う&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;高級言語：ポインタ操作や手動メモリ管理のノイズを隠蔽&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;モダンフレームワーク：接続プールやリトライなど運用上のノイズを隠蔽&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;この観点から見ると、抽象化は「情報理論的に正しい方向への進化」です。&lt;br&gt;
不要な実装詳細を隠すことで、&lt;strong&gt;開発者はより本質的な意図に集中できる&lt;/strong&gt; ようになります。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="3-それでも低レイヤ知識は不要にならない"&gt;3. それでも低レイヤ知識は不要にならない&lt;/h2&gt;
&lt;p&gt;抽象化が進んだからといって、低レイヤの知識が不要になるわけではありません。&lt;br&gt;
実際には「抽象の漏れ（Leaky Abstraction）」や、フレームワークの誤用によって問題が生じることがあります。&lt;/p&gt;
&lt;p&gt;そうしたときに求められるのは、&lt;strong&gt;下のレイヤを理解し、意図が正しく実現されているかを検証する力&lt;/strong&gt; です。&lt;br&gt;
ただし、低レイヤの学習そのものが目的化してしまうと、肝心の「ビジネス意図の理解」が置き去りになります。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="4-最適化の本質は情報の圧縮である"&gt;4. 最適化の本質は「情報の圧縮」である&lt;/h2&gt;
&lt;p&gt;最適化とは、突き詰めれば「情報の圧縮」です。&lt;br&gt;
プログラムはビジネスの意図を機械命令に符号化したものとも言えます。&lt;br&gt;
良い最適化とは、&lt;strong&gt;業務知識（確信）をもとに冗長性を取り除くこと&lt;/strong&gt; によって成立します。&lt;/p&gt;
&lt;p&gt;たとえば：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;キャッシュ導入の根拠は「そのデータは一定期間変化しない」という業務知見&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;インデックス設計の根拠は「特定フィールドの検索頻度が高い」という利用傾向&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;つまり、&lt;strong&gt;最適化とは単なる技術的チューニングではなく、業務理解と技術の融合による意思決定&lt;/strong&gt; なのです。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="5-戦術的勤勉-vs-戦略的怠惰"&gt;5. 戦術的勤勉 vs 戦略的怠惰&lt;/h2&gt;
&lt;p&gt;低レイヤを極めること自体は悪いことではありません。&lt;br&gt;
しかし、それが「業務理解を放棄する言い訳」になってしまっては本末転倒です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;戦術的勤勉：低レイヤを丹念に学ぶ（手段）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;戦略的怠惰：業務要件の理解を怠る（目的の喪失）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;まずは正しい問題設定──すなわち「ビジネスの意図」を明確にすること。&lt;br&gt;
そのうえで、低レイヤの知識を活用して実装や最適化を行う。&lt;br&gt;
この順序こそが、エンジニアリングにおける本質的なアプローチです。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="6-結論抽象化の流れは正しいただしバランスが鍵"&gt;6. 結論：抽象化の流れは正しい。ただし、バランスが鍵&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;モダンな抽象化は「意図に近づく」ための進化であり、退化ではない。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;低レイヤ知識は「検証・トラブルシューティング・高性能化」のために必要だが、目的ではない。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;成功するエンジニアは、**業務理解（何を伝えるか）&lt;strong&gt;と&lt;/strong&gt; 技術力（どう実現するか）**をバランスよく使い分ける。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;本質は「技術」ではなく「意図」。&lt;br&gt;
技術は、意図を実現するための道具にすぎない。&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>🌟 C++11 が左辺値と右辺値を5分類に拡張した理由</title><link>https://wuyukwi.duckdns.org/posts/zenn-bdadcd1b03c135/</link><pubDate>Mon, 27 Oct 2025 14:31:00 +0900</pubDate><guid>https://wuyukwi.duckdns.org/posts/zenn-bdadcd1b03c135/</guid><description>&lt;blockquote&gt;
&lt;p&gt;📌 &lt;em&gt;この記事は &lt;a href="https://zenn.dev/wuyukwi/articles/bdadcd1b03c135"&gt;Zenn&lt;/a&gt; に投稿した内容のアーカイブです。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="はじめに"&gt;はじめに&lt;/h2&gt;
&lt;p&gt;C++11 で「右辺値参照（rvalue reference）」が導入されたことで、C++ の値分類（value category）は大きく進化しました。&lt;br&gt;
C++98 では「左辺値（lvalue）」と「右辺値（rvalue）」の二分法しかありませんでしたが、C++11 ではさらに細かく分類されます：&lt;/p&gt;
&lt;p&gt;C++11で導入された新しい概念である&lt;br&gt;
&lt;strong&gt;xvalue（期限切れ右辺値）&lt;/strong&gt; と &lt;strong&gt;prvalue（純粋右辺値）&lt;/strong&gt; が、&lt;br&gt;
この章の中核的な進化ポイントです。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="c98-時代の単純な世界"&gt;C++98 時代の「単純な世界」&lt;/h2&gt;
&lt;p&gt;C++98 の時代はとてもシンプルでした。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;左辺値 (lvalue)&lt;/strong&gt; ：代入の左側に置けるもの。永続的なアドレスを持つ。&lt;br&gt;
例：&lt;code&gt;a&lt;/code&gt;, &lt;code&gt;*ptr&lt;/code&gt;, &lt;code&gt;array[i]&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;右辺値 (rvalue)&lt;/strong&gt; ：一時的な値。すぐに破棄される。&lt;br&gt;
例：&lt;code&gt;a + 5&lt;/code&gt;, &lt;code&gt;42&lt;/code&gt;, &lt;code&gt;func()&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ルールも直感的でした：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int a = 3;
&amp;amp;a; // OK 左辺値はアドレスが取れる
&amp;amp;(a + 5); // エラー！右辺値はアドレスが取れない
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;しかしこの単純さが、&lt;strong&gt;性能の壁&lt;/strong&gt; になっていました。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="問題無駄なコピーが多すぎる"&gt;問題：無駄なコピーが多すぎる&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;std::vector&amp;lt;int&amp;gt; create_vector() {
std::vector&amp;lt;int&amp;gt; temp;
temp.push_back(1);
temp.push_back(2);
temp.push_back(3);
return temp; // ここで何が起こる？
}
std::vector&amp;lt;int&amp;gt; v = create_vector();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C++98 の仕様では &lt;code&gt;return temp;&lt;/code&gt; で &lt;strong&gt;コピーが発生&lt;/strong&gt; します。&lt;br&gt;
&lt;code&gt;temp&lt;/code&gt; のヒープメモリをまるごと複製し、呼び出し側に返すのです。&lt;/p&gt;</description></item><item><title>💡 【Unity UGUI】Maskを使わずに実現する「穴あき」ハイライト演出</title><link>https://wuyukwi.duckdns.org/posts/zenn-731d17a8464927/</link><pubDate>Mon, 20 Oct 2025 19:24:18 +0900</pubDate><guid>https://wuyukwi.duckdns.org/posts/zenn-731d17a8464927/</guid><description>&lt;blockquote&gt;
&lt;p&gt;📌 &lt;em&gt;この記事は &lt;a href="https://zenn.dev/wuyukwi/articles/731d17a8464927"&gt;Zenn&lt;/a&gt; に投稿した内容のアーカイブです。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="はじめに"&gt;はじめに&lt;/h2&gt;
&lt;p&gt;UGUIで部分的にハイライトを当てたい場面、特に&lt;strong&gt;チュートリアル中の誘導UI&lt;/strong&gt; では「特定のボタンだけを明るく見せ、他の部分を半透明で覆う」演出がよく使われます。&lt;br&gt;
一般的には &lt;code&gt;Mask&lt;/code&gt; や &lt;code&gt;RectMask2D&lt;/code&gt; を利用しますが、これらにはいくつかの課題があります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Mask&lt;/code&gt;&lt;/strong&gt; ：Stencilバッファを使うため、描画コストが高い&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;RectMask2D&lt;/code&gt;&lt;/strong&gt; ：矩形領域しか扱えず、&lt;strong&gt;穴あき表現（逆マスク）&lt;/strong&gt; はできない&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;そこで今回は、&lt;code&gt;MaskableGraphic&lt;/code&gt; を継承し、&lt;strong&gt;完全プログラム制御で「逆マスク（穴あきマスク）」を生成する方法&lt;/strong&gt; を紹介します。&lt;br&gt;
最終的には、&lt;strong&gt;ハイライト部分がクリック可能で、他の部分はブロックされる&lt;/strong&gt; 、高性能な &lt;code&gt;HollowOutMask&lt;/code&gt; コンポーネントを実装していきます。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="目標仕様"&gt;目標仕様&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;機能&lt;/th&gt;
&lt;th&gt;説明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;視覚効果&lt;/td&gt;
&lt;td&gt;自身の &lt;code&gt;RectTransform&lt;/code&gt; 領域内に半透明のマスクを描画し、指定の &lt;code&gt;RectTransform&lt;/code&gt; 部分を「くり抜く」&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;射線処理&lt;/td&gt;
&lt;td&gt;穴の部分は&lt;strong&gt;クリックが通過&lt;/strong&gt; し、マスク部分は&lt;strong&gt;クリックをブロック&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;動的追従&lt;/td&gt;
&lt;td&gt;対象オブジェクトが動いたりスケールが変化しても、くり抜き領域が追従&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;これを、&lt;code&gt;Mask&lt;/code&gt; 系コンポーネントを使わずに、&lt;strong&gt;頂点操作&lt;/strong&gt; だけで実現します。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="実装の基本構造"&gt;実装の基本構造&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;HollowOutMask&lt;/code&gt; は &lt;code&gt;MaskableGraphic&lt;/code&gt; を継承し、&lt;code&gt;OnPopulateMesh()&lt;/code&gt; をオーバーライドします。&lt;/p&gt;
&lt;h3 id="頂点生成の考え方"&gt;頂点生成の考え方&lt;/h3&gt;
&lt;p&gt;想像してみてください。&lt;br&gt;
マスク全体を表す「外側の矩形（Outer Rect）」と、くり抜く「内側の矩形（Inner Rect）」があるとします。&lt;/p&gt;
&lt;p&gt;この２つの矩形を組み合わせ、外側を塗りつつ内側を抜くには、&lt;strong&gt;8つの頂点&lt;/strong&gt; と&lt;strong&gt;8枚の三角形&lt;/strong&gt; が必要です。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="コード例onpopulatemesh"&gt;コード例：OnPopulateMesh()&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;protected override void OnPopulateMesh(VertexHelper vh)
{
vh.Clear();
if (_isTargetNull)
{
base.OnPopulateMesh(vh);
return;
}
// Outer Rect（自身のRectTransform基準）
float outerLx = rectTransform.rect.xMin;
float outerBy = rectTransform.rect.yMin;
float outerRx = rectTransform.rect.xMax;
float outerTy = rectTransform.rect.yMax;
vh.AddVert(new Vector3(outerLx, outerTy), color, Vector2.zero);
vh.AddVert(new Vector3(outerRx, outerTy), color, Vector2.zero);
vh.AddVert(new Vector3(outerRx, outerBy), color, Vector2.zero);
vh.AddVert(new Vector3(outerLx, outerBy), color, Vector2.zero);
// Inner Rect（穴部分）
float innerLx = _targetMin.x;
float innerBy = _targetMin.y;
float innerRx = _targetMax.x;
float innerTy = _targetMax.y;
vh.AddVert(new Vector3(innerLx, innerTy), color, Vector2.zero);
vh.AddVert(new Vector3(innerRx, innerTy), color, Vector2.zero);
vh.AddVert(new Vector3(innerRx, innerBy), color, Vector2.zero);
vh.AddVert(new Vector3(innerLx, innerBy), color, Vector2.zero);
// Triangles（外側と内側の間を埋める）
vh.AddTriangle(0, 1, 5); vh.AddTriangle(5, 4, 0);
vh.AddTriangle(1, 2, 6); vh.AddTriangle(6, 5, 1);
vh.AddTriangle(2, 3, 7); vh.AddTriangle(7, 6, 2);
vh.AddTriangle(3, 0, 4); vh.AddTriangle(4, 7, 3);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;これで、&lt;strong&gt;中央が透明な「リング状ポリゴン&lt;/strong&gt; を生成できます。&lt;/p&gt;</description></item><item><title>📚 UI開発を10倍速くするための実戦ポイント</title><link>https://wuyukwi.duckdns.org/posts/zenn-143fe2d003d031/</link><pubDate>Thu, 09 Oct 2025 12:11:28 +0900</pubDate><guid>https://wuyukwi.duckdns.org/posts/zenn-143fe2d003d031/</guid><description>&lt;blockquote&gt;
&lt;p&gt;📌 &lt;em&gt;この記事は &lt;a href="https://zenn.dev/wuyukwi/articles/143fe2d003d031"&gt;Zenn&lt;/a&gt; に投稿した内容のアーカイブです。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="はじめに"&gt;はじめに&lt;/h2&gt;
&lt;p&gt;多くの人は「UI開発＝手の速さ」だと思っています。&lt;br&gt;
でも実際のプロジェクトでは、進行を遅らせる原因は&lt;strong&gt;コードの速さではなく、データフローとUI構造設計の悪さ&lt;/strong&gt; です。&lt;/p&gt;
&lt;p&gt;Unity（UGUI）で時間を食う典型的なポイントを挙げると、以下のようになります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;データ前処理がバラバラ&lt;/strong&gt; ：ソートやフィルタが各UIに散らばっていると、UI層が処理待ちになる。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;階層構造が深すぎる&lt;/strong&gt; ：1回の更新で大量のTransformを走査、処理も重くバグも出やすい。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;アニメーション・状態管理が未抽象化&lt;/strong&gt; ：新しい状態を追加するたびにコードを壊す。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;同じランキングUIでも、ある人は半日で完成、ある人は3日かかる。&lt;br&gt;
その差は、手の速さではなく&lt;strong&gt;設計の差&lt;/strong&gt; です。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="データ層とui層を明確に分離する"&gt;データ層とUI層を明確に分離する&lt;/h2&gt;
&lt;p&gt;ありがちなアンチパターンは、&lt;code&gt;OnClick()&lt;/code&gt; の中で&lt;br&gt;
データ取得 → オブジェクト生成 → UI更新を全部やるケース。&lt;/p&gt;
&lt;p&gt;短期的には動いても、UI改修のたびに全部作り直しになります。&lt;/p&gt;
&lt;p&gt;もっと良い設計はこうです👇&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;DataService / Manager&lt;/strong&gt; にデータロジックをまとめる&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;UI は &lt;strong&gt;DTO（Data Transfer Object）&lt;/strong&gt; を受け取って表示専念&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;データ前処理は Python や外部ツールで事前に済ませる&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;こうすると要件変更が来ても、UI側はほとんど触らずに済みます。&lt;br&gt;
データ層が変わってもUIは安定、これが真の開発効率化です。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="リスト描画はオブジェクトプールが必須"&gt;リスト描画は「オブジェクトプール」が必須&lt;/h2&gt;
&lt;p&gt;ランキング、インベントリ、スキルリストなど、&lt;br&gt;
毎回 &lt;code&gt;Instantiate&lt;/code&gt; ＋ &lt;code&gt;Destroy&lt;/code&gt; していると、&lt;br&gt;
処理が重くなるだけでなく、開発時間も無駄に増えます。&lt;/p&gt;
&lt;h3 id="対策"&gt;対策：&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;オブジェクトプールを構築する&lt;/strong&gt; ：&lt;br&gt;
再利用可能なUI要素をキャッシュして、再描画時はデータだけ差し替え。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;シンプルな PoolManager でOK&lt;/strong&gt; ：&lt;br&gt;
使い終わった要素は &lt;code&gt;SetActive(false)&lt;/code&gt; して再利用。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ScrollRect の仮想化レンダリングと併用&lt;/strong&gt; ：&lt;br&gt;
数千件でも軽く動作。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;あるプロジェクトでは、インベントリUIの描画時間が&lt;br&gt;
500セルで200ms → プール導入後は30msに短縮。&lt;br&gt;
体感で「カクつき」が消えました。&lt;/p&gt;</description></item><item><title>💡 C++ の「奇妙な再帰テンプレートパターン（CRTP）」を理解する</title><link>https://wuyukwi.duckdns.org/posts/zenn-b13f0c8ee91a17/</link><pubDate>Tue, 30 Sep 2025 12:36:20 +0900</pubDate><guid>https://wuyukwi.duckdns.org/posts/zenn-b13f0c8ee91a17/</guid><description>&lt;blockquote&gt;
&lt;p&gt;📌 &lt;em&gt;この記事は &lt;a href="https://zenn.dev/wuyukwi/articles/b13f0c8ee91a17"&gt;Zenn&lt;/a&gt; に投稿した内容のアーカイブです。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="はじめに"&gt;はじめに&lt;/h2&gt;
&lt;p&gt;C++ のテンプレートには数多くの応用テクニックがありますが、その中でも「&lt;strong&gt;CRTP（Curiously Recurring Template Pattern：奇妙な再帰テンプレートパターン）&lt;/strong&gt; 」は特にユニークで強力な手法です。&lt;br&gt;
Boost をはじめとする有名ライブラリでも多用されており、C++ の表現力を大きく広げてくれます。&lt;/p&gt;
&lt;p&gt;この記事では、CRTP の基本から実用例、さらには応用パターンまでを整理して解説します。&lt;/p&gt;
&lt;h2 id="crtp-とは"&gt;CRTP とは？&lt;/h2&gt;
&lt;p&gt;CRTP の基本形は以下のようになります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;template &amp;lt;typename T&amp;gt;
class Base {
public:
T&amp;amp; getDerived() { return static_cast&amp;lt;T&amp;amp;&amp;gt;(*this); }
};
class Derived : public Base&amp;lt;Derived&amp;gt; {
// Derived 自身を Base のテンプレート引数として渡す
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;一見すると「派生クラス &lt;code&gt;Derived&lt;/code&gt; が、まだ完成していない自分自身を基底クラス &lt;code&gt;Base&lt;/code&gt; に渡している」ように見えます。この“自己参照”こそが CRTP の特徴です。&lt;br&gt;
コンパイラはこれを問題なく処理でき、基底クラスはコンパイル時に派生クラスの型情報を知ることができます。&lt;/p&gt;
&lt;h2 id="実用例比較演算子の自動生成"&gt;実用例：比較演算子の自動生成&lt;/h2&gt;
&lt;p&gt;C++ では &lt;code&gt;==&lt;/code&gt; や &lt;code&gt;&amp;lt;&lt;/code&gt; などの比較演算子を定義するのはよくある作業ですが、すべてを個別に書くと冗長になりがちです。&lt;br&gt;
CRTP を用いると、基底クラスに「共通の比較演算子」をまとめ、派生クラスは最小限の実装だけで済ませられます。&lt;/p&gt;
&lt;h3 id="基底クラス"&gt;基底クラス&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;template &amp;lt;typename Derived&amp;gt;
class Comparable {
public:
bool operator==(const Derived&amp;amp; other) const {
return static_cast&amp;lt;const Derived*&amp;gt;(this)-&amp;gt;equalsImpl(other);
}
bool operator!=(const Derived&amp;amp; other) const {
return !(*this == other);
}
bool operator&amp;lt;(const Derived&amp;amp; other) const {
return static_cast&amp;lt;const Derived*&amp;gt;(this)-&amp;gt;lessImpl(other);
}
bool operator&amp;gt;(const Derived&amp;amp; other) const { return other &amp;lt; *this; }
bool operator&amp;lt;=(const Derived&amp;amp; other) const { return !(*this &amp;gt; other); }
bool operator&amp;gt;=(const Derived&amp;amp; other) const { return !(*this &amp;lt; other); }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id="派生クラス例"&gt;派生クラス例&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;class Point : public Comparable&amp;lt;Point&amp;gt; {
public:
Point(int x_val, int y_val) : x(x_val), y(y_val) {}
bool equalsImpl(const Point&amp;amp; other) const {
return x == other.x &amp;amp;&amp;amp; y == other.y;
}
bool lessImpl(const Point&amp;amp; other) const {
return (x != other.x) ? (x &amp;lt; other.x) : (y &amp;lt; other.y);
}
private:
int x, y;
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;これで &lt;code&gt;==&lt;/code&gt;, &lt;code&gt;!=&lt;/code&gt;, &lt;code&gt;&amp;lt;&lt;/code&gt;, &lt;code&gt;&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;=&lt;/code&gt;, &lt;code&gt;&amp;gt;=&lt;/code&gt; がすべて利用可能になります。&lt;/p&gt;</description></item><item><title>🔥 ゲームプログラマーとして成長するために大切な3つの力</title><link>https://wuyukwi.duckdns.org/posts/zenn-f6d20f7d12e8b4/</link><pubDate>Thu, 18 Sep 2025 16:43:12 +0900</pubDate><guid>https://wuyukwi.duckdns.org/posts/zenn-f6d20f7d12e8b4/</guid><description>&lt;blockquote&gt;
&lt;p&gt;📌 &lt;em&gt;この記事は &lt;a href="https://zenn.dev/wuyukwi/articles/f6d20f7d12e8b4"&gt;Zenn&lt;/a&gt; に投稿した内容のアーカイブです。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="はじめに"&gt;はじめに&lt;/h2&gt;
&lt;p&gt;「どうすればプログラミングが上手くなるのか？」&lt;br&gt;
これは、ゲーム業界を目指すエンジニアにとって、常につきまとうテーマです。&lt;/p&gt;
&lt;p&gt;Unity や Unreal Engine などの便利なエンジンやライブラリが整っている時代でも、「本当にゲームを作れる」プログラマーになるためには、&lt;strong&gt;言語やフレームワークの知識以上に重要な根本的スキル&lt;/strong&gt; があります。&lt;/p&gt;
&lt;p&gt;本記事では、ゲームプログラマーとして実務を経験する中で特に大事だと感じる&lt;strong&gt;3つの力&lt;/strong&gt; を紹介します。&lt;/p&gt;
&lt;h2 id="-抽象化の力--巨大なコードを分けて考える"&gt;① 抽象化の力 —— 巨大なコードを「分けて」考える&lt;/h2&gt;
&lt;p&gt;ゲーム開発は、数千〜数百万行にもなるコードの集合です。&lt;br&gt;
その全てを頭に入れることは不可能なので、&lt;strong&gt;必要な部分だけをブラックボックスとして扱う&lt;/strong&gt; 考え方が必須になります。&lt;/p&gt;
&lt;p&gt;例えば、「プレイヤーが持つ全ての武器を取得する」処理を作る場合を考えます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Repositoryパターンによる例
class WeaponRepository {
public List&amp;lt;Weapon&amp;gt; GetAllWeapons(PlayerId playerId);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;この &lt;code&gt;WeaponRepository&lt;/code&gt; クラスを作るときは、&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;DBやセーブデータへのアクセス&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ログやエラーハンドリング&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;フォーマット変換&lt;br&gt;
など、たくさんの下位レイヤのライブラリを呼び出しますが、&lt;strong&gt;上のレイヤからは「GetAllWeapons」だけ見えればよい&lt;/strong&gt; のです。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これが抽象化であり、&lt;strong&gt;モジュールを積み重ねて大規模ゲームを成立させる基本&lt;/strong&gt; です。&lt;/p&gt;
&lt;h3 id="実戦ポイント"&gt;実戦ポイント&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;オブジェクト指向（OOP）、関数型（FP）、手続き型といった &lt;strong&gt;複数のパラダイムを状況に応じて使い分ける&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;トップダウン（設計から実装）とボトムアップ（共通処理の抽出）を行き来しながら開発する&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;抽象化しすぎると開発が重くなり、抽象化しなさすぎるとコピペ地獄になるため、バランスを取る&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="-デバッグの力--ブラックボックスを開ける技術"&gt;② デバッグの力 —— ブラックボックスを「開ける」技術&lt;/h2&gt;
&lt;p&gt;抽象化したコードは便利ですが、&lt;strong&gt;バグが起きたときには中を開ける必要&lt;/strong&gt; があります。&lt;/p&gt;
&lt;p&gt;たとえば「インベントリ画面に武器一覧が表示されない」と報告されたとき、どこから原因を追うべきでしょうか？&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;F12（DevTools）や &lt;code&gt;curl&lt;/code&gt; でクライアント→サーバ間通信を確認&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;サーバで &lt;code&gt;WeaponRepository.GetAllWeapons()&lt;/code&gt; の戻り値をログ出力&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DBにクエリを直打ちして期待通りの結果か確認&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;こうして&lt;strong&gt;層を一つずつ下って調査&lt;/strong&gt; するのがデバッグの基本です。&lt;br&gt;
このスキルはバグ修正だけでなく、&lt;strong&gt;新しいプロジェクトやチームに参加したときにコードを理解する力&lt;/strong&gt; にもなります。&lt;/p&gt;
&lt;p&gt;実戦ポイント&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;ログやアサートを常に入れておく&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;デバッガでステップ実行できるように設計する&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;バグ報告を「再現可能な条件」に落とし込む&lt;/p&gt;</description></item><item><title>😯 C++で高性能計算を書くときに意識すべき最適化ポイントまとめ</title><link>https://wuyukwi.duckdns.org/posts/zenn-d2508bad444e4d/</link><pubDate>Mon, 04 Aug 2025 20:10:19 +0900</pubDate><guid>https://wuyukwi.duckdns.org/posts/zenn-d2508bad444e4d/</guid><description>&lt;blockquote&gt;
&lt;p&gt;📌 &lt;em&gt;この記事は &lt;a href="https://zenn.dev/wuyukwi/articles/d2508bad444e4d"&gt;Zenn&lt;/a&gt; に投稿した内容のアーカイブです。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="はじめに"&gt;はじめに&lt;/h2&gt;
&lt;p&gt;本記事では、私自身が経験したことや、信頼できる実践的な知見を元に、&lt;strong&gt;C++で高速な数値処理や行列演算を行う際に意識すべき最適化ポイント&lt;/strong&gt; をわかりやすく整理しました。&lt;br&gt;
HPCやリアルタイム演算に関心のある方に参考になれば幸いです。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="1-メモリのアライメントとキャッシュ効率"&gt;1. メモリのアライメントとキャッシュ効率&lt;/h2&gt;
&lt;h3 id="アライメント__attribute__alignedn"&gt;アライメント（&lt;code&gt;__attribute__((aligned(n))&lt;/code&gt;）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;CPUは&lt;strong&gt;キャッシュライン（通常64バイト）単位&lt;/strong&gt; でメモリを読み込む。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;メモリが正しく整列されていないと、&lt;strong&gt;キャッシュミスやfalse sharing&lt;/strong&gt; が発生し、性能が大幅に低下。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;GCC/Clangなら &lt;code&gt;__attribute__((aligned(32)))&lt;/code&gt; など、MSVCでは &lt;code&gt;__declspec(align(32))&lt;/code&gt; を使う。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="連続したメモリを使用するstdvectortなど"&gt;連続したメモリを使用する（&lt;code&gt;std::vector&amp;lt;T&amp;gt;&lt;/code&gt;など）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;行列は行優先(row-major)の順番で連続配置することで、CPUの事前読み込み(prefetch)が効きやすくなる。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;std::vector&amp;lt;std::vector&amp;lt;float&amp;gt;&amp;gt;&lt;/code&gt; のような非連続構造は避ける。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="2-メモリ確保の最適化高速メモリアロケータ"&gt;2. メモリ確保の最適化：高速メモリアロケータ&lt;/h2&gt;
&lt;p&gt;標準の &lt;code&gt;malloc&lt;/code&gt; や &lt;code&gt;new&lt;/code&gt; は汎用的で安全ですが、性能面ではボトルネックになることがあります。&lt;/p&gt;
&lt;h3 id="おすすめのアロケータ"&gt;おすすめのアロケータ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;tcmalloc&lt;/strong&gt; （Google製、スレッドセーフ）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;jemalloc&lt;/strong&gt; （Facebook製、ゲームやサーバーで人気）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Hoard&lt;/strong&gt; （スケーラブルなスレッド対応）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これらを使うと、&lt;strong&gt;多スレッド環境でのアロケーション性能が大幅に向上&lt;/strong&gt; します。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="3-行列演算の高速化手法"&gt;3. 行列演算の高速化手法&lt;/h2&gt;
&lt;h3 id="strassenアルゴリズムon281"&gt;Strassenアルゴリズム（O(n^2.81)）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;通常のO(n³)よりも理論上速い。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;再帰的に分割しながら計算することで、掛け算回数を削減。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="ブロック分割block-based-multiplication"&gt;ブロック分割（Block-based Multiplication）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;大きな行列を&lt;strong&gt;小さなサブブロックに分けて計算&lt;/strong&gt; すると、キャッシュが有効活用できる。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;代表的なライブラリ（後述するBLASなど）ではこの最適化が組み込まれている。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="4-並列計算マルチスレッド化"&gt;4. 並列計算（マルチスレッド化）&lt;/h2&gt;
&lt;h3 id="c11の標準スレッド"&gt;C++11の標準スレッド&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;std::thread&lt;/code&gt;, &lt;code&gt;std::async&lt;/code&gt; を使って並列化可能。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;シンプルな制御だが、スレッド数の管理や同期は自前で対応が必要。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="openmp"&gt;OpenMP&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;#pragma omp parallel for&lt;/code&gt; のように、簡潔にfor文を並列化。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;コンパイラ依存（GCC/Clang/MSVC全て対応）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="intel-tbbthread-building-blocks"&gt;Intel TBB（Thread Building Blocks）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;動的なタスクスケジューリング・負荷分散・ワークスティーリングが可能。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;不規則な処理を高速並列化したいときに強力。&lt;/p&gt;</description></item><item><title>💡 C++ の emplace_back は push_back を完全に置き換えられるか？</title><link>https://wuyukwi.duckdns.org/posts/zenn-c73aa0d12885ff/</link><pubDate>Tue, 24 Jun 2025 12:40:20 +0900</pubDate><guid>https://wuyukwi.duckdns.org/posts/zenn-c73aa0d12885ff/</guid><description>&lt;blockquote&gt;
&lt;p&gt;📌 &lt;em&gt;この記事は &lt;a href="https://zenn.dev/wuyukwi/articles/c73aa0d12885ff"&gt;Zenn&lt;/a&gt; に投稿した内容のアーカイブです。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="はじめに"&gt;はじめに&lt;/h2&gt;
&lt;p&gt;C++11 から導入された &lt;code&gt;emplace_back&lt;/code&gt; は、コンテナに要素をその場で構築できる便利なメソッドです。&lt;br&gt;
一方、それ以前から使われてきた &lt;code&gt;push_back&lt;/code&gt; とはどんな違いがあり、&lt;code&gt;emplace_back&lt;/code&gt; は完全に &lt;code&gt;push_back&lt;/code&gt; を代替できるのでしょうか？&lt;/p&gt;
&lt;p&gt;本記事では、&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;emplace_back&lt;/code&gt; が本当に &lt;code&gt;push_back&lt;/code&gt; より常に速いのか&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;両者がどんなケースに使えるのか&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;実装の違いと注意点&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;について、自分なりに整理した考えをまとめます。&lt;/p&gt;
&lt;h2 id="push_back-と-emplace_back-の違い"&gt;&lt;code&gt;push_back&lt;/code&gt; と &lt;code&gt;emplace_back&lt;/code&gt; の違い&lt;/h2&gt;
&lt;h3 id="push_back"&gt;&lt;code&gt;push_back&lt;/code&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;// C++20以降
constexpr void push_back(const T&amp;amp; value); // コピー
constexpr void push_back(T&amp;amp;&amp;amp; value); // ムーブ
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;push_back&lt;/code&gt; は、すでに生成されたオブジェクトをコピーまたはムーブして格納する関数です。&lt;/p&gt;
&lt;h3 id="emplace_back"&gt;&lt;code&gt;emplace_back&lt;/code&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;// C++20以降
template&amp;lt;class... Args&amp;gt;
constexpr reference emplace_back(Args&amp;amp;&amp;amp;... args); // その場で構築
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;emplace_back&lt;/code&gt; は、コンストラクタに渡す引数をそのまま受け取り、コンテナ内部で直接オブジェクトを構築します。そのため、&lt;strong&gt;中間オブジェクトなし&lt;/strong&gt; に要素を追加できる点が特徴です。&lt;/p&gt;
&lt;p&gt;これらの大きな違いは、&lt;code&gt;push_back&lt;/code&gt;が&lt;strong&gt;既に生成されたオブジェクト（T型）&lt;strong&gt;をコピーまたはムーブする一方で、&lt;code&gt;emplace_back&lt;/code&gt;は&lt;/strong&gt;任意のコンストラクタ引数からその場でT型のインスタンスを構築できる&lt;/strong&gt;点です。&lt;/p&gt;
&lt;h2 id="llvmにおける内部実装"&gt;LLVMにおける内部実装&lt;/h2&gt;
&lt;p&gt;以下はLLVM(libc++)における&lt;code&gt;push_back&lt;/code&gt;内部の実装です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if (this-&amp;gt;__end_ != this-&amp;gt;__end_cap()) {
__construct_one_at_end(__x); // 残り容量がある場合、__xをコピーまたはムーブ構築
} else {
__push_back_slow_path(__x); // 足りない場合、新規領域を確保して再配置
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;__construct_one_at_end&lt;/code&gt; の中では、allocatorが提供する &lt;code&gt;construct()&lt;/code&gt; を使って、指定されたメモリにオブジェクトを構築しています。&lt;br&gt;
また、allocatorが &lt;code&gt;construct()&lt;/code&gt; を持たない場合には単純に in-place new を呼び出す仕組みです。&lt;/p&gt;</description></item><item><title>🎉 std::function がヒープメモリを確保する条件とは？— コピーキャプチャされた変数の型がカギ</title><link>https://wuyukwi.duckdns.org/posts/zenn-fdcfc181acf35d/</link><pubDate>Thu, 05 Jun 2025 13:03:20 +0900</pubDate><guid>https://wuyukwi.duckdns.org/posts/zenn-fdcfc181acf35d/</guid><description>&lt;blockquote&gt;
&lt;p&gt;📌 &lt;em&gt;この記事は &lt;a href="https://zenn.dev/wuyukwi/articles/fdcfc181acf35d"&gt;Zenn&lt;/a&gt; に投稿した内容のアーカイブです。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="はじめに"&gt;はじめに&lt;/h2&gt;
&lt;p&gt;C++ の &lt;code&gt;std::function&lt;/code&gt; は「小さいオブジェクトならヒープ確保しない（Small Object Optimization, SOO）」という知識は一般的です。しかし、以下のようなコードでは意外な挙動が観察されます：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;struct A {
int value;
A(int v) : value(v) {}
A(const A &amp;amp;other) : value(other.value) {}
};
struct B {
int value;
B(int v) : value(v) {}
};
A a{0};
B b{0};
std::function&amp;lt;void()&amp;gt; funcA = [a] {}; // ヒープ確保あり
std::function&amp;lt;void()&amp;gt; funcB = [b] {}; // ヒープ確保なし
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;このように、&lt;strong&gt;コピーコンストラクタの有無だけ&lt;/strong&gt; で挙動が変わるのはなぜでしょうか？&lt;/p&gt;
&lt;h2 id="stdfunction-がローカル格納を行う条件gcclibstdc-編"&gt;&lt;code&gt;std::function&lt;/code&gt; がローカル格納を行う条件（GCC/libstdc++ 編）&lt;/h2&gt;
&lt;p&gt;libstdc++ の実装（GCC 標準ライブラリ）では、以下の条件を満たすとオブジェクトはヒープではなくローカルに保存されます：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;static const bool __stored_locally =
(__is_location_invariant&amp;lt;_Functor&amp;gt;::value &amp;amp;&amp;amp;
sizeof(_Functor) &amp;lt;= _M_max_size &amp;amp;&amp;amp;
__alignof__(_Functor) &amp;lt;= _M_max_align &amp;amp;&amp;amp;
(_M_max_align % __alignof__(_Functor) == 0));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;この中で特に重要なのが：&lt;/p&gt;</description></item><item><title>💨 Fusionの[Networked]属性はどう動いている？IL変換と自動同期の仕組みを解剖する</title><link>https://wuyukwi.duckdns.org/posts/zenn-79685434adc2f5/</link><pubDate>Wed, 04 Jun 2025 19:50:30 +0900</pubDate><guid>https://wuyukwi.duckdns.org/posts/zenn-79685434adc2f5/</guid><description>&lt;blockquote&gt;
&lt;p&gt;📌 &lt;em&gt;この記事は &lt;a href="https://zenn.dev/wuyukwi/articles/79685434adc2f5"&gt;Zenn&lt;/a&gt; に投稿した内容のアーカイブです。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="はじめに"&gt;はじめに&lt;/h2&gt;
&lt;p&gt;Photon Fusionは、高性能・高柔軟性なネットワーク同期システムを提供する次世代ネットワークライブラリです。&lt;br&gt;
その中でも特に重要な役割を担っているのが、&lt;code&gt;[Networked]&lt;/code&gt; 属性です。&lt;/p&gt;
&lt;p&gt;この属性を使うことで、&lt;strong&gt;プレイヤーの位置やアニメーション状態、ゲーム内オブジェクトの変化&lt;/strong&gt; などを自動的に同期でき、煩雑な手動のデータ送受信処理を省くことができます。&lt;/p&gt;
&lt;p&gt;本シリーズでは、Fusionの内部同期処理を段階的に掘り下げて解説していきますが、今回は、&lt;code&gt;[Networked]&lt;/code&gt; 属性の裏側で何が起きているのか、どのようにして自動同期が実現されているのかを詳しく見ていきます。&lt;/p&gt;
&lt;h2 id="fusionにおけるnetworked属性の同期処理概要"&gt;Fusionにおける[Networked]属性の同期処理概要&lt;/h2&gt;
&lt;h3 id="networked-属性は"&gt;&lt;code&gt;[Networked]&lt;/code&gt; 属性は？&lt;/h3&gt;
&lt;p&gt;Fusionでは、&lt;code&gt;[Networked]&lt;/code&gt; 属性が付与されたプロパティは&lt;strong&gt;ネットワーク状態の同期対象&lt;/strong&gt; として扱われますが、ユーザーが手動で同期コードを書く必要はありません。&lt;br&gt;
この仕組みは、Unityが提供する &lt;strong&gt;ILPostProcessor API&lt;/strong&gt; を活用しており、C# で書かれたコードをビルド後に&lt;strong&gt;IL（中間言語）レベルで自動変換&lt;/strong&gt; しています。&lt;/p&gt;
&lt;p&gt;IL&lt;/p&gt;
&lt;p&gt;ILは、.NET における中間言語です。&lt;br&gt;
Unity では、C# で書いたスクリプトは必ずこの IL を経由してからネイティブコードに変換されます。&lt;/p&gt;
&lt;p&gt;具体的には、以下のような処理が行われます：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;NetworkedWeaved&lt;/code&gt; という属性を追加して、該当プロパティがネットワーク状態バッファに割り当てられることを明示&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;getter/setter が &lt;code&gt;NetworkBehaviour&lt;/code&gt; の内部バッファ（&lt;code&gt;StateBuffer&lt;/code&gt;）への&lt;strong&gt;メモリアクセスに差し替え&lt;/strong&gt; られる&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;実行時に &lt;code&gt;Spawned()&lt;/code&gt; されていない場合のアクセス制限も挿入される&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="変換前のcコード"&gt;変換前のC#コード：&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt; [Networked] private Vector2 _position { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id="il変換後ilspyで逆コンパイルしたコード"&gt;IL変換後（ILSpyで逆コンパイルしたコード）：&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;    [Networked]
    [NetworkedWeaved(0, 2)]
    private unsafe Vector2 _position
    {
        get
        {
            if (base.Ptr == null)
            {
                throw new InvalidOperationException(&amp;quot;Error when accessing PhotonCapybara._position. Networked properties can only be accessed when Spawned() has been called.&amp;quot;);
            }
            return (Vector2)base.Ptr[0];
        }
        set
        {
            if (base.Ptr == null)
            {
                throw new InvalidOperationException(&amp;quot;Error when accessing PhotonCapybara._position. Networked properties can only be accessed when Spawned() has been called.&amp;quot;);
            }
            Unsafe.Write(base.Ptr + 0, value);
        }
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id="補足解説"&gt;補足解説：&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;base.Ptr&lt;/code&gt; は &lt;code&gt;NetworkBehaviour&lt;/code&gt; に割り当てられた&lt;strong&gt;ネットワーク状態メモリの先頭ポインタ&lt;/strong&gt; です。&lt;/p&gt;</description></item></channel></rss>