Steamのストアには、タイトルごとに「Steam Deck 動作確認済み(Verified)」というバッジが付いています。ProtonDBには利用者の報告が何千件も溜まっています。Steam DeckのProtonも、Macの互換レイヤーも、土台はどちらもWineです。
だとしたら、この蓄積をMacの目安として読み替えられないでしょうか。「Deckで動くならMacでもいけるはず」という当て推量を、数字で確かめてみたくなりました😊
先に結論だけ書いておくと、読み替えられるのは「動かない理由」の側だけでした。しかも決め手になったのは集計ではなく、Deckが同じ判定を付けた2本を実際にMacで動かしてみたことです。1本は完璧に動き、もう1本は真っ黒でした。
この記事は集計が3つ、実験が3つあります。「承前」と付いている章は、その前の章の続きです。
用語集
この回は略語が多いので、先に片付けておきます。
| 用語 | 平たく言うと | なぜ効くのか |
|---|---|---|
| Wine | WindowsのAPIをその場で置き換えて、Windows用の実行ファイルを別のOSで動かす仕組み | DeckもMacも土台はこれ。だから「読み替えられるのでは」と思える |
| Proton | Valveがゲーム向けに手を入れたWineに、翻訳部品を足したもの | Steam Deckが動く正体。Wine単体より対応範囲が広い |
| DXVK | Direct3D 9/10/11 を Vulkan に翻訳する部品 | Linux側の主力。MacにはVulkanが無いのがこの記事の分かれ目 |
| VKD3D-Proton | Direct3D 12 を Vulkan に翻訳する部品 | 比較的新しいゲームはここを通る |
| Vulkan | WindowsでもLinuxでもAndroidでも使える、描画の共通規格 | Linuxが標準で持っている。macOSは持っていない |
| Metal | Appleの描画のしくみ。Vulkanの代わりにmacOSが持っているもの | Mac側の翻訳部品は最後にここへ落とす必要がある |
| D3DMetal | Direct3DをMetalに直接翻訳するApple製の部品。Game Porting Toolkit由来 | ★今回いちばんの主役。p967で扱ったものが、実は手元のWhiskyにも入っていた |
| WineD3D / DXMT | 同じ役目の別実装。順にWine標準(OpenGL経由)・Porting Kit採用 | どれを通るかで対応範囲が変わる(p989) |
| Rosetta 2 | x86向けの命令をApple Silicon(ARM)向けに翻訳するApple純正のしくみ | MacではWineの下にもう1段翻訳が挟まる |
| FEX | x86の命令をARMに翻訳する、Linux側の同種のしくみ | ValveがSteam Frame向けに使っている。Rosetta 2と役割が同じ |
| Steam Frame | Valveの、単体で動くVRヘッドセット。中身はスマホと同じARMのチップで、SteamOSが動く | ★Macと同じ問題にValveがぶつかった例。この記事の比べる相手 |
| SDL2 | ゲームがOSの違いを気にせず窓・入力・描画を扱えるようにする土台のライブラリ | ★描画のしかたを後から切り替えられる。これが実験3の決め手になった |
| EAC / BattlEye | 不正対策(アンチチート)の代表的な2つ | ★ここだけはDeckのほうが恵まれている。後の章で詳しく書きます |
| ProtonDB | 利用者が「自分の環境で動いたか」を報告し合う、有志のデータベース | platinum〜borkedの5段階。Valveの公式判定とは別物 |
【下調べ】Steam Deckの「Verified」は、何を審査しているのか
読み替えを考える前に、そもそも何を審査しているのかを公式で確かめました。Valveの開発者向けドキュメントには、判定が4段階で示されています。
| 判定 | Valveの説明(要約) |
|---|---|
| Verified | すべての互換性チェックに通った。利用者が設定をいじらなくても全機能を使える |
| Playable(一部動作) | 動くが、利用者側の手作業が要ることがある |
| Unsupported(非対応) | Protonまたはハードウェアと合わず、動作しない |
| Unknown(不明) | 審査がまだ終わっていない |
問題は「互換性チェック」の中身です。公式は審査領域を次のように挙げています。
| 領域 | 何を見るか |
|---|---|
| Input(入力) | 既定のコントローラ設定で全機能に手が届くか/画面の表記がコントローラ用になっているか/文字入力のときソフトキーボードが出るか |
| Performance(性能) | 既定の設定のまま800pで30fps出るか(Steam Machineでは1080p/30fps) |
| Seamlessness(引っかかりの無さ) | 「非対応の環境です」と警告を出さないか/ランチャーをコントローラだけで操作できるか |
| Display(画面) | 1280×800で、いちばん小さい文字が9ピクセルを下回らないか |
| Proton | Protonが、そのWindows版を致命的な不具合なしに動かせるか |
★5つのうち、Macに関係があるのは1つだけ
Macで気になるのは「翻訳層が動かせるか」=Protonの1項目だけです。コントローラの表記も、800pで30fps出るかも、文字が9px以上かも、Macには何の意味もありません。
つまりVerifiedバッジは、その大半が「携帯ゲーム機として快適か」の証明です。
ここまでは定義の話です。では実際のタイトルでは、この5領域がどんな比率で出てくるのでしょうか。数えてみました。
【集計1・公開データ】審査項目365件を、内訳で数えてみる
Steamのストアには、判定バッジの裏に個別のテスト結果が入っています。公開のエンドポイントから取れます。
curl -s "https://store.steampowered.com/saleaction/ajaxgetdeckappcompatibilityreport?nAppID=1091500&l=english"
返ってくるJSONの resolved_items[] に、こういう項目が並びます。
{"display_type":4,"loc_token":"#SteamDeckVerified_TestResult_DefaultControllerConfigFullyFunctional"}
{"display_type":4,"loc_token":"#SteamDeckVerified_TestResult_ControllerGlyphsMatchDeckDevice"}
{"display_type":4,"loc_token":"#SteamDeckVerified_TestResult_InterfaceTextIsLegible"}
{"display_type":4,"loc_token":"#SteamDeckVerified_TestResult_DefaultConfigurationIsPerformant"}
display_type の意味は、集めた365件を通して例外なく一貫していました。
| 値 | 意味 | 付くのは |
|---|---|---|
| 4 | ✓ 合格 | どの判定でも |
| 3 | ⚠ 注意(=Verifiedに届かない理由) | 「一部動作」まで |
| 2 | ✕ 不合格 | 「非対応」だけ |
| 1 | i 情報(回線が要る、など) | どの判定でも |
母数はいま最も遊ばれているタイトル100本(Steamの公開ランキング)にしました。恣意的に選ぶと結論が動いてしまうので、順位という外から決まる基準で切っています。うち1本はストア情報が取れなかったので99本で集計しました。判定の内訳はこうです。
| Deckの判定 | 本数 | 割合 |
|---|---|---|
| Verified | 31 | 31.3% |
| 一部動作 | 39 | 39.4% |
| 非対応 | 25 | 25.3% |
| 不明 | 4 | 4.0% |
そして本題。99本に付いていたテスト結果は全部で365件ありました。これを公式の審査領域に割り当てて数えます。
★★審査の89.6%は、翻訳層の話ではない
コントローラ・性能・文字の大きさで89.6%を占めます。Macに読み替えられるのはProtonの20件=5.5%だけでした。
Verifiedバッジを見て「Macでも大丈夫そう」と思うのは、試験の9割を占める科目を見て、残り1割の科目の点数を当てようとしているのと同じことになります。
【集計2・公開データ】Deckの判定とMac版の有無を突き合わせる
比率の話だけでは実感が湧かないので、実際のタイトルで見てみます。Steamのストア情報にはplatforms.mac(Macネイティブ版があるか)が入っているので、判定ごとに数えました。
| Deckの判定 | 本数 | Macネイティブ版あり | 割合 |
|---|---|---|---|
| Verified | 31 | 12 | 39% |
| 一部動作 | 39 | 12 | 31% |
| 非対応 | 25 | 4 | 16% |
| 不明 | 4 | 1 | 25% |
Verifiedでも39%、非対応でも16%。差はありますが、予測に使えるほどの差ではありません。そして面白いのは、非対応側にいる4本です。
★逆転している4本
「Deckで動かない」のに「Macネイティブ版がある」タイトルが4本ありました。
| タイトル | Deckが弾いた理由 | Macでは |
|---|---|---|
| Rust | アンチチートの構成 | ネイティブ版あり |
| Total War: WARHAMMER III | SteamOSが非対応 | ネイティブ版あり |
| OBS Studio | SteamOSが非対応(ソフトウェア) | ネイティブ版あり |
| Crimson Desert Enhanced | Deckのグラフィック性能が足りない | ネイティブ版あり |
いちばん下がはっきりしています。「Deckの性能が足りない」は翻訳の話ですらありません。Deckが積んでいるのは携帯機向けのAPUなので、そこで力尽きるタイトルはM4のMacなら動くこともあります。
★「Deckで動かない」はMacの根拠にならない
非対応の25本はいずれも不合格の項目が1つずつでした。うちMacにも効く理由(アンチチート・SteamOS非対応)が20本、残り5本はDeckというハードの性能不足で、Macには当てはまりません。
判定バッジは「Deckという1台の機械の話」であって、Wineの話ではないのだ、と考えると納得がいきます。
【集計3・公開データ】ProtonDBはMacの参考になるのか
Valveの公式判定が携帯機の都合に引きずられているなら、利用者の報告のほうが素直かもしれません。ProtonDBは「自分の環境で動いたか」を持ち寄る場所なので、コントローラや画面サイズの事情は入らないはずです。
同じ99本のProtonDB評価と、Macネイティブ版の有無を並べました。
platinum(Linuxで完璧に動く)でもMac版があるのは45%、goldでは25%。良い評価はMacの可否をほとんど予測しません。ところが最下位のborkedだけは、6本すべてにMac版がありませんでした。
★別の角度から、同じ結論に着いた
集計1(審査項目の内訳)と集計3(ProtonDB)は、まったく違うデータです。それでも「読み替えが効くのはダメな側だけ」という同じ場所に着きました。
理由は考えてみれば単純で、動かない理由は数が少なく、原因が具体的だからです。アンチチートに弾かれる、そもそも起動しない——こうした理由はOSを変えても消えません。一方「動く」は、無数の条件が全部そろって初めて成り立つので、条件がひとつ変われば崩れます。
【下調べ】そもそも構造が違う ── Deck・Steam Frame・Mac
なぜ「動く」が読み替えられないのか。3つの機械の構造を縦に並べると、はっきりします。
ここで比べる相手として面白いのが、Steam Frameです。名前だけ聞くと関係がなさそうですが、実はMacとまったく同じ問題にぶつかった機械です。
Steam Frameとは何か
Steam Frameは、Valveの単体で動くVRヘッドセットです。これまでのPC向けVRのようにパソコンとケーブルで繋ぐ必要がなく、本体だけでSteamのゲームが動きます。
| 項目 | 中身 |
|---|---|
| 頭脳(SoC) | Qualcomm Snapdragon 8 Gen 3(=ARM。スマホと同じ系統のチップ) |
| メモリ | 16GB |
| OS | SteamOS(Linux)。★ValveがSteamOSをARMに載せた最初の製品 |
| 画面 | 2160×2160 の液晶が左右に1枚ずつ/72〜144Hz |
| 保存領域 | 256GB または 1TB(microSDで増やせる) |
この記事にとって大事なのは、VRであることでも、画面の綺麗さでもありません。中身がARMで、そこでx86向けに作られたWindowsのゲームを動かそうとしている——この一点です。
★ValveはMacと同じ問題を解くことになった
Steam Deckはx86のCPUを積んでいたので、Windowsゲームの命令をそのまま実行できました。翻訳が必要だったのはWindowsのAPIとDirect3Dだけです。
ところがSteam FrameはARMです。命令そのものから翻訳しなければなりません。これはApple SiliconのMacがずっとやってきたことと、まったく同じ問題です。
Valveの答えは、翻訳のしくみを3つ用意することでした。2026年8月に、そのうち2つが公開されています。
| しくみ | 何を何に翻訳するか | Mac側の相当品 |
|---|---|---|
| Proton | Windowsのプログラム → Linux | Wine(Whisky・Porting Kit など) |
| FEX | x86の命令 → ARMの命令 | ★Rosetta 2(役目がそっくり) |
| Lepton | Androidのアプリ → Linux | ★相当品なし |
真ん中のFEXがRosetta 2と同じ役目です。x86向けに焼かれた命令を、その場でARMの命令に置き換えながら走らせます。Valveは以前からFEXの開発を支援していて、Proton 11.0-1 Beta 3ではFEX-2605に更新されました。
いちばん下のLeptonは、Androidのアプリを動かすためのものです。Macには相当するものがありません。Valveは「翻訳を重ねて遊べる物を増やす」ことを戦略として選んでいると読めます。
つまりSteam Frameは、Macがやっていること(Rosetta 2+Wine)とほぼ同じ構えで、ARMの上にWindowsゲームを載せようとしているわけです。
なぜ、変換が要るARMをわざわざ選ぶのか
ここで素朴な疑問が湧きます。x86ならそのまま動くのに、なぜ変換が要るARMにするのでしょうか。
ヘッドセットに関しては、選択の余地が薄いというのが実情のようです。頭に載せる機械なので、バッテリーは21.6Whしかなく、顔の前で大きなファンも回せません。そのうえチップの中に入っていてほしい回路が多いのです。
| 要るもの | Steam Frameでの用途 |
|---|---|
| 高リフレッシュの画面出力を2系統 | 2160×2160 を 72〜144Hz で左右に |
| カメラの低遅延処理 | 外向き4個+視線追跡2個で、自分の位置と手を追う |
| 映像の圧縮・展開 | パソコンから無線で映像を受け取る |
QualcommのXR向けSoCには、これらが最初から入っています。x86でやるなら別のチップを足すことになり、基板も消費電力も遅延も増えます。実際、単体で動くヘッドセットはほぼすべてARMです。
そしてもうひとつ。変換の代償は、思われているほど大きくありません。
★Rosetta 2の代償は「遅さ」ではなく「メモリ」だった
p986で実測したところ、整数演算は0.99倍(ほぼ差なし)で、効いたのはメモリの1.7倍でした。
理由は3つあります。変換した結果は保存されて使い回されること、GPUの仕事は変換を通らないこと(ゲームで重いのはGPU側です)、そして命令の変換は翻訳の階層のうち1段でしかないことです。
⚠そしてここが面白いところなのですが、Steam Deckも「変換なし」ではありませんでした。x86なので命令の変換は不要でしたが、WindowsのAPIとDirect3Dは翻訳していました。つまりDeckも最初から翻訳の機械で、ARMになって増えるのは階層が1段だけです。「素直なx86 対 変換だらけのARM」ではなく、「翻訳2段 対 翻訳3段」が実態でした。
そう考えると、ValveがProton・FEX・Leptonと翻訳の道具を揃えているのも筋が通ります。★翻訳の能力さえ持っていれば、その時いちばん良いチップを選べる——ハードに縛られないための投資に見えます。
⚠なお、Valveが選定理由を説明した公式の資料は見つけられませんでした。この節のうち、仕様(Snapdragon 8 Gen 3・21.6Wh・カメラ構成)とp986の実測値は確かめた事実ですが、「だからARMを選んだ」の部分はeightの推測です。
ARM機どうしで比べると、Steam FrameとMacの構造はほとんど同じです。x86を変換して、Wineを通して、Direct3Dを翻訳して、描画のしくみに落とす。3階建ての形はそっくりです。
違うのは最下段だけ。Steam Frameの下にはVulkanがあり、Deckと同じDXVK・VKD3D-Protonがそのまま乗ります。Macの下にはMetalしかないので、まったく別の翻訳部品を用意しなければならないのです。
★読み替えが壊れる場所は、いちばん下
「同じWineだから読み替えられるはず」という当て推量が外れるのは、Wineより下が別物だからです。DeckとSteam Frameの間なら、Protonの実績はかなり読み替えられます(部品が同じなので)。MacとDeckの間だけは、そこが断ち切れています。
——と、この時点では「たぶんそうだろう」と考えていました。実験3で、それが目に見える形で出てきます。
ちなみに2026年時点のProton 11は、DXVKを2.7.1に、VKD3D-Protonをproton-20260410の枝に更新しています。FEXはProton 11.0-1 Beta 3でFEX-2605になりました。この2つの部品はMacには一切来ません。
【実験1・Mac】読み替える先は、何を持っているのか
ここまでは公開データと資料の話でした。では読み替える先であるMac側は、実際どこまで持っているのでしょうか。手元で測ります。
BlenderのAndroid版のときと同じ構えで、小さなプローブを自分で書きます。ゲームを起動して「動いた・動かない」を見るのではなく、翻訳層に直接、何を持っているか申告させるやり方です。
使ったのはWhisky 2.3.5(同梱のWineは7.7)です。手元にある無料の層で、いちばん多くの人が持っているものです。
プローブの作り方
Windows用の実行ファイルは、Macからそのまま作れます。
brew install mingw-w64
x86_64-w64-mingw32-gcc -O2 -o d3dgate.exe d3dgate.c -ldxguid -luuid -lole32
中身の要点はすべて動的に引くことです。d3d12.dll が無い環境で「起動できずに終わる」と、何も分からないまま終わってしまいます。無ければ「無い」と報告して次へ進ませます。
/* D3D12: あるか → device が作れるか → どの機能レベルか */
HMODULE h = LoadLibraryA("d3d12.dll");
if (!h) { P(" d3d12.dll: 読み込めない ← この層はD3D12を持っていない\n"); return; }
PFN_D3D12CreateDevice fn = (PFN_D3D12CreateDevice)GetProcAddress(h, "D3D12CreateDevice");
if (!fn) { P(" D3D12CreateDevice: 無い\n"); return; }
static const D3D_FEATURE_LEVEL want[] = {
(D3D_FEATURE_LEVEL)0xc200, D3D_FEATURE_LEVEL_12_1,
D3D_FEATURE_LEVEL_12_0, D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0,
};
for (size_t i = 0; i < sizeof want / sizeof want[0]; i++) {
ID3D12Device *dev = NULL;
HRESULT hr = fn(NULL, want[i], &IID_ID3D12Device, (void **)&dev);
if (SUCCEEDED(hr)) { P(" ✓ 成功 機能レベル %s\n", fl_name(want[i])); return; }
}
結果
$ wine64 d3dgate.exe
Wine: 7.7
論理プロセッサ数: 4
[DXGI] アダプタの一覧
#0 "AMD Compatibility Mode"
VendorId=0x1002 DeviceId=0x66af VRAM=25559 MiB flags=0x0
[D3D9] ✓ 成功
[D3D11] ✓ 成功 機能レベル 11_1
[D3D12] ✓ 成功 機能レベル 12_2
[Vulkan] vulkan-1.dll = C:\windows\system32\vulkan-1.dll
✓ vkCreateInstance あり
まず目に付くのはアダプタ名です。手元はApple M4のMacなのに、「AMD Compatibility Mode」・VendorIdは0x1002(AMD)・VRAMは25GBと申告されました。論理プロセッサ数も4です(M4は10コア)。
★★中の自己申告は、そのまま信じてはいけない
このブログでは3回目です。p982ではUTMの仮想マシンがVendorId 0x1414(Microsoft)を返し、実体はCPU描画でした。p990ではAndroidエミュレータの中でGPU名が「Apple M4」でした。今回はM4が「AMD」と名乗り、25GBのVRAMがあると言い張っています。
翻訳層は「ゲームが困らない答え」を返すのが仕事なので、正直であることは仕事に入っていません。この数字を見て性能を判断してはいけません。
⚠ここでeightはひとつ思い込みをしました。WhiskyはDXVKを既定で無効にしているので、「ではWine標準のWineD3Dが引き受けているのだろう」と考えたのです。これは後で外れます(実験3)。プローブは「何ができるか」は測れましたが、「誰がやっているか」は測っていませんでした。
さて、D3D9もD3D11もD3D12も「成功」と出ました。Wine 7.7でD3D12が機能レベル12_2まで通る——本当でしょうか。ここで止めたら、まさに「動いた」を鵜呑みにすることになります。
【承前】「デバイスが作れた」と「絵が出た」を分ける
デバイスが作れることと、絵が出ることは別です。そこで2本目のプローブを書きました。64×64の描画先を作り、決めた色で塗りつぶし、CPU側へ読み戻して、その色が本当に返ってくるかまで見ます。
期待する色は R=0x40 G=0x80 B=0xC0 A=0xFF。中途半端な値にしたのは、たまたま一致する事故を避けるためです。
ID3D11DeviceContext_ClearRenderTargetView(ctx, rtv, CLEAR_RGBA);
ID3D11DeviceContext_Flush(ctx);
/* 読み戻し用のテクスチャへコピーして、CPUから覗く */
td.Usage = D3D11_USAGE_STAGING; td.BindFlags = 0;
td.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
ID3D11Device_CreateTexture2D(dev, &td, NULL, &stg);
ID3D11DeviceContext_CopyResource(ctx, (ID3D11Resource *)stg, (ID3D11Resource *)rt);
ID3D11DeviceContext_Map(ctx, (ID3D11Resource *)stg, 0, D3D11_MAP_READ, 0, &m);
D3D12のほうは、コマンドキューを作り、コマンドリストを積み、フェンスで完了を待ってから読み戻します。途中のどこで転んでも分かるように、段ごとに印字しました。
[D3D11] 塗りつぶして読み戻す
device 作成 ✓(機能レベル 0xb000)
読み戻した画素: R=40 G=80 B=C0 A=FF → ✓ 期待どおり(本当に描けている)
[D3D12] 塗りつぶして読み戻す
device 作成 ✓
コマンドキュー ✓
コマンドリスト ✓
実行と完了待ち ✓
読み戻した画素: R=40 G=80 B=C0 A=FF → ✓ 期待どおり(本当に描けている)
予想が外れました。Wine 7.7で、D3D11もD3D12も本当に画素が返ってきます。コマンドキューもフェンスも通ります。「古いWineだからD3D12は形だけだろう」と思っていたので、これは意外でした😳
ただし、塗りつぶしは描画のなかでいちばんやさしい操作です。これだけで「ゲームが動く」とは言えません。もう一段深く、シェーダを走らせて三角形を描くところまでやります。
【承前・切り分け】3通りのシェーダで、止まっている場所を確かめる
三角形を描くには、頂点シェーダとピクセルシェーダが要ります。HLSLで書いて、その場でコンパイルして流し込みます。まず、ごく普通の書き方で。
float4 VSMain(uint id : SV_VertexID) : SV_POSITION {
float2 p[3] = { float2(-0.9,-0.9), float2(0.0, 0.9), float2(0.9,-0.9) };
return float4(p[id], 0, 1);
}
float4 PSMain() : SV_TARGET { return float4(1.0, 0.5, 0.0, 1.0); }
これが通りませんでした。
A: 配列を変数で引く書き方 → ✕ 失敗 hr=0x80004001
t.hlsl:3:21: E5017: Aborting due to not yet implemented feature:
Dereference with non-constant offset of type HLSL_IR_EXPR.
配列を変数で引くのが未実装、と言っています。ここで「D3D11は使えない」と結論づけるのは早すぎます。 止まっているのが描画なのか、コンパイラなのかが、まだ分かれていません。書き方を変えて切り分けます。
/* B: 配列をやめて、三項演算子で書き下す */
float x = (id == 0) ? -0.9 : ((id == 1) ? 0.0 : 0.9);
/* C: 三項演算子もやめて、比較の結果を数値に変換して足し算だけにする */
float x = 0.9 * ((float)(id == 1) - (float)(id == 0));
| 書き方 | 結果 | エラー |
|---|---|---|
| A: 配列を変数で引く | ✕ | Dereference with non-constant offset |
| B: 三項演算子 | ✕ | Ternary operator |
| C: 比較を数値に変換 | ✕ | SM4 cast from bool to float |
すべて E5017: not yet implemented。三項演算子すら未実装でした。
★★「在る」と「使える」は別
d3dcompiler_47.dll は確かにあり、D3DCompile も GetProcAddress で引けます。存在だけを確かめる検査なら合格です。それなのに、5行のシェーダが3通りとも通りません。
⚠ただし「だから市販ゲームは動かない」とは言えません。多くのゲームはコンパイル済みのシェーダを同梱していて、そちらはこの経路を通らないからです。確実に死ぬのは実行時にHLSLを組み立てる作りのものだけです。
ここまでで分かったのは「翻訳層の底は通っている」ということだけです。ゲーム1本が通るかは、まだ何も分かっていません。 実際に動かします。
【実験2・Mac】Deck「一部動作」の1本目 ── 完璧に動いた
読み替えを確かめるなら、Deckが同じ判定を付けたタイトルをMacで動かすのがいちばん素直です。題材は次の条件で選びました。
- 無料で、オープンソース(配布も検証も規約の心配がない)
- アンチチートを積んでいない(⚠これは絶対条件です。理由は後の章に書きます)
- Windows版とMac版の両方がある(読み替えの答え合わせになる)
残ったのが Endless Sky と Battle for Wesnoth です。どちらもDeckの判定は「一部動作」で、減点の中身まで同じ顔ぶれでした。
| Endless Sky | Battle for Wesnoth | |
|---|---|---|
| Deckの判定 | 一部動作 | 一部動作 |
| 減点の理由 | コントローラ表記が合わない/ソフトキーボードが出ない | コントローラ表記が合わない |
| 合格した項目 | コントローラ操作・文字の読みやすさ・性能 | 同左 |
★減点はどちらも「携帯機としての作法」だけです。集計1で見たとおりですね。この情報からMacについて分かることは、理屈のうえでは何もありません。実際はどうでしょうか。
Endless Skyは公式リリースに展開するだけのzipがあるので、そのままWineのプレフィックスへ置きます。まずは窓を出さずに、全データを読ませてみます。
$ wine64 "Endless Sky.exe" --parse-assets
Logger session beginning. Game version: 0.11.2.0.
Detected operating system version: Windows NT 10.0.19043.
Parse completed with no error(s).
4秒で、エラーなしで全部読めました。データ・画像・音声の読み込みが通っています。そのままGUIで起動します。
完璧です。惑星も、背後の星も、スクロールするクレジットも、UIの枠も出ています。新しいパイロットを作る画面へ進むと、写真のテクスチャもそのまま出ました。
ゲーム本編に入り、借金の説明を受けるところまで進みました。Deckが「一部動作」と言っていたタイトルが、Macでは何の手当てもなく動きます。
ただしログには、こんな行が残っていました。
UNSUPPORTED (log once): POSSIBLE ISSUE: unit 1 GLD_TEXTURE_INDEX_2D_ARRAY is
unloadable and bound to sampler type (Float) - using zero texture because
texture unloadable
これはゲームではなくmacOS側のOpenGLドライバが出しているものです(GLD はAppleのGLドライバ)。テクスチャ配列がひとつ読めず、代わりに空のテクスチャを使ったと言っています。画面を見るかぎり破綻はありませんでしたが、下では何かが落ちています。ゲーム自身のエラーログ(errors.txt)は1行も出ていませんでした。
★このゲームはDirect3Dを使っていない
同梱のDLLを見ると glew32.dll があり、d3d*.dll は1つもありません。つまりEndless SkyはOpenGLのゲームで、この記事でずっと話してきたDirect3Dの翻訳をまったく通っていません。
きれいに動いたのは立派ですが、読み替えの本丸を素通りしているということでもあります。
【実験3・Mac】同じ「一部動作」の2本目 ── 真っ黒だった
2本目のBattle for Wesnothへ行きます。こちらはインストーラ形式なので、無人モードで入れました。
$ wine64 wesnoth-1.18.8-win64.exe /S
(38秒で完了。C:\Program Files\Battle for Wesnoth 1.18.8 に入った)
⚠ここで小さな驚きがひとつ。「win64」と名乗るこのインストーラ自体は32bitの実行ファイルでした(NSIS製の通例です)。p967で32bitと64bitはMac上で別の経路を通ると分かっているので、身構えたのですが、インストールは何事もなく通りました。
そして起動すると——真っ黒でした。
窓は1800×1169で開いています。プロセスも生きています。40秒待っても、さらに40秒待っても、画面の色数は1色(完全な黒)のままでした。
ログにはこう出ていました。
[D3DMetal:LOG:6C44A6] Unsupported API: IDXGISwapChain1::SetRotation
★D3DMetal。Appleの翻訳部品が、自分で「このAPIには対応していない」と名乗り出ました。IDXGISwapChain1::SetRotation は画面に出す一歩手前(スワップチェーン=描いた絵を表示用に差し替える仕組み)の呼び出しです。
【承前・切り分け】描画のしかたを4通り試す
WesnothはSDL2を使っています。SDL2の便利なところは、描画のしかたを環境変数で後から選べることです。Windowsでは既定でDirect3D 11が選ばれます。
そこで、ゲームもWineも機械も変えずに、描画バックエンドだけを4通り切り替えました。
SDL_RENDER_DRIVER=direct3d11 wine64 wesnoth.exe # 既定
SDL_RENDER_DRIVER=direct3d wine64 wesnoth.exe # D3D9
SDL_RENDER_DRIVER=opengl wine64 wesnoth.exe
SDL_RENDER_DRIVER=software wine64 wesnoth.exe # CPUで描く
判定は目視ではなく、撮った画面を縮小して色の種類を数えることにしました。真っ黒なら1色になります。
| SDL_RENDER_DRIVER | 色数 | 結果 |
|---|---|---|
| direct3d11(既定) | 1 | ✕ 真っ黒/D3DMetal: Unsupported API |
| direct3d(D3D9) | 3,705 | ✓ 描画された |
| opengl | 3,712 | ✓ 描画された |
| software(CPU描画) | 3,581 | ✓ 描画された |
同じゲーム、同じWine、同じ機械。違うのは描画のしかただけです。そして落ちたのは4つのうち1つ、しかもそれが既定でした。
★★「Direct3Dがだめ」ではなかった
最初は「Direct3Dの翻訳がだめなのだろう」と思いました。ところがD3D9(direct3d)は通っています。落ちたのはD3D11のスワップチェーンだけでした。
1つ試して「Direct3Dはだめ」と書いていたら、間違ったことを書くところでした。4通り試したから、原因が1点に絞れました。
ちなみに右の画面をよく見ると、日本語のメニューが豆腐にならず出ています。p956やp967では日本語が四角に化けて苦労したので、これは素直に嬉しい変化でした😊
⚠【承前】ここで実験1の思い込みが崩れた
ログに出た「D3DMetal」の4文字で、実験1の前提が崩れました。eightは「WhiskyはDXVKが無効だからWineD3Dだろう」と思っていたのです。
確かめる方法はp989で分かっています。d3d11.dll の大きさです。D3DMetalは本体がmacOS側にあるので、Windows側に置くDLLは薄いつなぎで済みます。WineD3Dは全部を自分で持つので大きくなります。
$ ls -l wine/drive_c/windows/system32/d3d11.dll
108.0 KB ← ★薄い。WineD3Dなら5MB級になる
$ strings -a d3d11.dll | grep -i d3dmetal
Sources/D3DMetalDLLsBase/D3DMetalDLLsBase-15/D3D4Mac/...
108KB、そして中にはAppleのビルド環境のパス(D3DMetalDLLsBase / D3D4Mac)がそのまま埋まっていました。決まりです。
★プローブは「誰がやっているか」を教えてくれなかった
実験1のプローブは「何ができるか」を正確に測りました。D3D11もD3D12も本当に画素を返す、という結果は今も正しいままです。
けれど「それを誰がやっているのか」は測れていませんでした。それを教えてくれたのは、プローブではなく実際のゲームが吐いた1行のログです。
そして「AMD Compatibility Mode / VRAM 25GB」の正体もこれでした。D3DMetalは、ゲームが素直に動くようにAMDのGPUのふりをしているのです。M4が「AMD」と名乗っていた理由が、ようやく分かりました。
つまり手元のWhiskyは、p967で扱ったGame Porting Toolkitと同じ部品を積んでいたことになります。無料の互換レイヤーだと思っていたものの中に、Apple純正の翻訳器が入っていたわけです。
【手順】自分のゲームを、自分で確かめる
ここまでの話を、手元で使える形にまとめます。気になるタイトルが1本あるとき、何を見れば時間を無駄にせずに済むかの手順です。
手順1: まずMacネイティブ版を探す(30秒)
Steamのストアページで、価格の下にあるOSのアイコンを見ます。林檎のマークがあればそれで終わりです。翻訳を通さないのが常に最善です。⚠ただしアイコンがあっても中身がIntel専用のことがあるので、そこはp986を見てください。
手順2: Deckの判定は「非対応」だけ見る(30秒)
ストアページのDeck互換性の欄を開き、✕が付いている項目だけを読みます。次の2つに当たったら、そこで諦めてよいです。
- アンチチート関連(⚠Macでは動かないうえに危険。次章)
- SteamOSが非対応
「Deckの性能が足りない」で弾かれている場合は諦める理由になりません。M4のほうが速いことがあります。
個別のテスト結果は、ストアページを見なくてもコマンドで取れます。l=english を付けると機械で読める形(loc_token)で返ってきます。
curl -s "https://store.steampowered.com/saleaction/ajaxgetdeckappcompatibilityreport?nAppID=<appid>&l=english" \
| python3 -c 'import sys,json; r=json.load(sys.stdin)["results"]; \
[print(x["display_type"], x["loc_token"]) for x in r["resolved_items"]]'
先頭の数字が2なら不合格、3は注意、4は合格です。appidはストアページのURLに入っています。
手順3: ProtonDBは borked だけ見る(30秒)
protondb.com/app/<appid> を開きます。borked(全く動かない)なら諦めてよいです。platinumやgoldは、残念ながらMacの参考になりません。
手順4: ここまでで決まらなければ、実際に試す
Deckの情報から分かることは、ここで尽きます。あとは手元で動かすしかありません。そのとき真っ黒だったら、諦める前に描画のしかたを変えてみるのが今回の収穫です。
# SDL製のゲームなら、これだけで直ることがある
SDL_RENDER_DRIVER=opengl wine64 game.exe
# うまくいったら恒久設定にする(Whiskyなら「環境変数」の欄)
SDLを使っているかは、ゲームのフォルダに SDL2.dll があるかで分かります。Unity製やUnreal製には効きませんが、個人開発やオープンソースのゲームでは当たりが多い手です。
★真っ黒は「詰み」とは限らない
p956・p967でSteamが黒画面になったときは、打つ手がありませんでした。今回のWesnothも見た目はまったく同じ「真っ黒」です。
それでも環境変数ひとつで直りました。同じ症状でも原因は違います。ログを読んで、切り替えられるところを切り替える——それだけで越えられる壁があります。
⚠アンチチートだけは、Macのほうが立場が悪い
ひとつだけ、読み替えると危険な方向に間違えるものがあります。
99本のうち、アンチチートを理由に弾かれていたのは8本。PUBG、Apex Legends、GTA V(LegacyとEnhancedの両方)、Rainbow Six Siege、Rust、Call of Duty、Destiny 2。8本すべてが「非対応」でした。
ここで注意が要ります。Deckで非対応なのは、Deckが冷遇されているからではありません。 EACとBattlEyeは2021年からProton向けの対応を用意していて、開発元が有効にすれば動きます。2026年5月時点で、EAC採用作の66%、BattlEye採用作の55%がLinuxで動作するという集計もあります。門番になっているのはアンチチートの提供元ではなく、各ゲームの開発元です。
Macの互換レイヤーには、この仕組みそのものがありません。
⚠⚠ここは実際に痛い目に遭っています
p982(仮想マシンでWindowsゲーム)の検証で、ゲームのアカウントが2035年まで停止されました。規約は「広告収益化が許諾されているか」だけを確認していて、「仮想化環境で実行してよいか」を確認していなかったのが原因です。
そして、そのタイトルはSteam Deckでは Verified です。
つまり「Deckで動く」を根拠にMacの互換レイヤーで起動すると、アカウントが飛びます。ここだけは、読み替えが「効かない」ではなく「逆に危険」です。検証タイトルの規約は「収益化の可否」と「仮想化の可否」の2軸で見てください。
今回わざわざオープンソースの2本を選んだのも、この理由です。アンチチート採用作には触れませんし、無料でアンチチートの無いものも、規約が「動画向けの許諾」に限られていることが多いのです(p988で3例続けて当たりました)。
【ここから整理】読み替えの判断表
集計と実験をまとめると、こうなります。
| Deck側で見えている情報 | Macへの読み替え | 理由 |
|---|---|---|
| Verified である | ✕ 読み替えない | 審査の89.6%は携帯機の快適さの話。実際Verified 31本中Mac版は12本(39%) |
| 一部動作 である | ✕ 読み替えない | ★同じ判定・同じ減点理由の2本が、Macでは完璧と真っ黒に割れた |
| アンチチートで非対応 | ★★そのまま効く。しかもMacはもっと悪い | Deckには開発元が有効化できる道があるが、Macには仕組みが無い。起動しないこと |
| SteamOSが非対応 | ★ だいたい効く | そもそも起動しない・ソフトの性質による、が理由なのでOSを変えても残りやすい |
| Deckの性能不足で非対応 | ✕ 読み替えない | 携帯機のAPUの話。M4のほうが速いこともある(実際4本が該当) |
| ランチャーで減点 | △ 半分効く | Macでも問題になるが、原因が同じとは限らない |
| ProtonDBが borked | ★ 効く | 6本すべてMac版も無い。「全く動かない」は共通している |
| ProtonDBが platinum / gold | ✕ 効かない | Mac版がある割合は45% / 25%。予測にならない |
| Macネイティブ版がある | ★★これが最優先 | 翻訳を通さないのが常に最善(p986) |
身も蓋もない結論ですが、使えるのは「諦める判断」だけです。とはいえ、無駄になる時間を先に削れるのは、それはそれで役に立ちます。今回もWesnothの導入だけで38秒、起動を見届けるのに何度も1分近く待ちました。
つまずき集
| 症状 | 原因と対処 |
|---|---|
ビルドで undefined reference to 'wWinMain' | -municode を付けると wmain/wWinMain を要求される。main() で書くなら付けない |
D3D12で macro ... passed 2 arguments, but takes just 1 | mingwの COBJMACROS は構造体を返すメソッドで形が変わる。#define WIDL_C_INLINE_WRAPPERS を足して、戻り値で受ける形にする |
| アダプタ名が文字化けする | mingwの printf("%ls") は当てにならない。WideCharToMultiByte で明示的に変換する |
★wesnoth.exe --version が5分経っても返らない | 止まっていない。Wineがコンソール窓を別に開き、そこで「Press enter to continue...」で待っていた。ターミナルには何も返らない |
| ウィンドウはあるのに真っ黒 | ★ログを読む。今回はD3DMetalが未対応APIを自分から名乗った。SDL製なら SDL_RENDER_DRIVER を替えてみる |
| APIから何も返らなくなる | Steamのエンドポイントは連続で叩くと弾かれる。1本あたり3秒空けた(100本で約5分) |
timeout コマンドが無い | macOSには標準で入っていない |
もうひとつ、⚠今回できなかったことを書いておきます。Endless Skyの名前入力欄に文字を入れようとしたのですが、手元の自動化からキー入力を送り届けられませんでした(マウスのクリックは通るのに、キーだけ届かない)。Wineの性質ではなく操作環境の制約なので、「文字入力が動くか」はこの記事では確かめられていません。
まとめ
- Steam Deckの審査項目365件のうち89.6%は、コントローラ・性能・文字の大きさといった携帯機としての快適さの話だった。Macに読み替えられるのはProtonの20件=5.5%だけ
- ★Verifiedでも、Macネイティブ版があるのは39%。非対応の16%と比べて、予測に使えるほどの差はない
- ★逆転が4本あった。Deck非対応なのにMac版がある。うち1本は「Deckの性能不足」が理由で、翻訳の話ですらない
- ★ProtonDBも同じで、platinum 45% / gold 25%と良い側はばらばら。一致したのはborkedの6本だけ(Mac版0本)
- ★★Deckが同じ「一部動作」と判定し、減点理由まで同じだった2本をMacで動かしたら、1本は完璧、1本は真っ黒に割れた。判定はこの差を何ひとつ教えてくれない
- ★★真っ黒の犯人は D3DMetal が
IDXGISwapChain1::SetRotationに未対応だったこと。ゲーム自身のログが名乗り出た - ★★描画のしかたを4通り試すと、落ちたのは既定のdirect3d11だけ。D3D9もOpenGLもCPU描画も通った。「Direct3Dがだめ」ではなく「D3D11のスワップチェーンだけがだめ」だった
- ⚠実験1の思い込みが外れた。WhiskyはWineD3Dだと思っていたが、実はApple製のD3DMetalを積んでいた(
d3d11.dllが108KB+中にAppleのビルドパス)。「AMD Compatibility Mode / VRAM 25GB」の正体もこれ - ★プローブは「何ができるか」は測れても「誰がやっているか」は測れなかった。教えてくれたのは実際のゲームが吐いた1行のログ
- Steam FrameとMacは同じ3階建て。違うのは最下段がVulkanかMetalかだけで、読み替えが断ち切れるのはまさにそこ
- ⚠⚠アンチチートだけは読み替えると危険。Deckには開発元が有効化できる道があり(EAC 66% / BattlEye 55%)、Macには無い。実際にp982でアカウントが2035年まで停止され、そのタイトルはDeckではVerifiedだった
- 使い方は「まずMacネイティブ版を探す→非対応の理由だけ見て諦める判断に使う→それ以外は試す」。真っ黒でも
SDL_RENDER_DRIVERで越えられることがある
「同じWineなんだから読み替えられるはず」という当て推量から始めましたが、同じ判定の2本がこれほど割れるとは思っていませんでした。バッジは「Deckという1台の機械の話」であって、Wineの話ではなかった、というのがいちばんの収穫です😊
それでは、今回はここまで。最後までありがとうございました😊
参考サイト
- Steamworks ドキュメント: Steam Deck 互換性レビュー(審査4段階と各領域の基準・800p/30fps・文字9pxの根拠)
- ValveSoftware/Proton(Protonの構成部品:Wine・DXVK・VKD3D-Proton・FEX)
- vkd3d-proton(Direct3D 12 を Vulkan の上に実装する部品)
- DXVK(Direct3D 9/10/11 を Vulkan へ翻訳する部品)
- ProtonDB(利用者の報告による5段階の評価。集計にはAPIを使用)
- Endless Sky(GPLv3。検証に使った v0.11.2 の公式Windowsビルド)
- Battle for Wesnoth(GPLv2+。検証に使った 1.18.8 の公式Windowsインストーラ)
- SDL2 のよくある質問(
SDL_RENDER_DRIVERで描画バックエンドを選ぶ方法) - GamingOnLinux: Proton Experimental が Proton 11 へ(DXVK 2.7.1 / VKD3D-Proton の版)
- GamingOnLinux: Proton 11.0-1 Beta 3 の FEX 更新(ARM64向け FEX-2605)
- Road to VR: Steam Frame の仕様(Snapdragon 8 Gen 3・16GB・2160×2160×2・72〜144Hz・256GB/1TB)
- TechSpot: Valve が Lepton と FEX を公開(2026年8月・Steam Frame 向けの互換のしくみ)
- It's FOSS: EAC と BattlEye の Proton 対応(2021年からの opt-in 方式)
- Can I Play on Linux?: Anti-Cheat on Linux in 2026(EAC 66% / BattlEye 55%・2026年5月時点の集計)
実測した環境:Apple M4 / メモリ32GB / macOS 26.6.2、Whisky 2.3.5(同梱 Wine 7.7・★D3DMetal経由)、クロスコンパイラ mingw-w64(GCC 16.2.0)。検証タイトルは Endless Sky 0.11.2(公式win64版)と Battle for Wesnoth 1.18.8(公式win64インストーラ)。互換性データは2026年9月5日に取得した公開エンドポイントの値です。