Steamのストアには、タイトルごとに「Steam Deck 動作確認済み(Verified)」というバッジが付いています。ProtonDBには利用者の報告が何千件も溜まっています。Steam DeckのProtonも、Macの互換レイヤーも、土台はどちらもWineです。

だとしたら、この蓄積をMacの目安として読み替えられないでしょうか。「Deckで動くならMacでもいけるはず」という当て推量を、数字で確かめてみたくなりました😊

先に結論だけ書いておくと、読み替えられるのは「動かない理由」の側だけでした。しかも決め手になったのは集計ではなく、Deckが同じ判定を付けた2本を実際にMacで動かしてみたことです。1本は完璧に動き、もう1本は真っ黒でした。

この記事は集計が3つ、実験が3つあります。「承前」と付いている章は、その前の章の続きです。

スポンサーリンク

用語集

この回は略語が多いので、先に片付けておきます。

用語平たく言うとなぜ効くのか
WineWindowsのAPIをその場で置き換えて、Windows用の実行ファイルを別のOSで動かす仕組みDeckもMacも土台はこれ。だから「読み替えられるのでは」と思える
ProtonValveがゲーム向けに手を入れたWineに、翻訳部品を足したものSteam Deckが動く正体。Wine単体より対応範囲が広い
DXVKDirect3D 9/10/11 を Vulkan に翻訳する部品Linux側の主力。MacにはVulkanが無いのがこの記事の分かれ目
VKD3D-ProtonDirect3D 12 を Vulkan に翻訳する部品比較的新しいゲームはここを通る
VulkanWindowsでもLinuxでもAndroidでも使える、描画の共通規格Linuxが標準で持っている。macOSは持っていない
MetalAppleの描画のしくみ。Vulkanの代わりにmacOSが持っているものMac側の翻訳部品は最後にここへ落とす必要がある
D3DMetalDirect3DをMetalに直接翻訳するApple製の部品。Game Porting Toolkit由来★今回いちばんの主役。p967で扱ったものが、実は手元のWhiskyにも入っていた
WineD3D / DXMT同じ役目の別実装。順にWine標準(OpenGL経由)・Porting Kit採用どれを通るかで対応範囲が変わる(p989)
Rosetta 2x86向けの命令をApple Silicon(ARM)向けに翻訳するApple純正のしくみMacではWineの下にもう1段翻訳が挟まる
FEXx86の命令をARMに翻訳する、Linux側の同種のしくみValveがSteam Frame向けに使っている。Rosetta 2と役割が同じ
Steam FrameValveの、単体で動く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ピクセルを下回らないか
ProtonProtonが、その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✕ 不合格「非対応」だけ
1i 情報(回線が要る、など)どの判定でも

母数はいま最も遊ばれているタイトル100本(Steamの公開ランキング)にしました。恣意的に選ぶと結論が動いてしまうので、順位という外から決まる基準で切っています。うち1本はストア情報が取れなかったので99本で集計しました。判定の内訳はこうです。

Deckの判定本数割合
Verified3131.3%
一部動作3939.4%
非対応2525.3%
不明44.0%

そして本題。99本に付いていたテスト結果は全部で365件ありました。これを公式の審査領域に割り当てて数えます。

審査項目 365件の内訳(人気99タイトル・2026年9月) Input(操作) 182件 49.9% 読み替え不可 Performance(性能) 75件 20.5% 読み替え不可 Display(画面) 70件 19.2% 読み替え不可 Proton(動くか) 20件 5.5% ★Macにも効く 前提(回線など) 14件 3.8% Seamlessness 4件 1.1% 半分だけ 89.6%(327件)は、Macには何の意味も持たない項目だった

★★審査の89.6%は、翻訳層の話ではない
コントローラ・性能・文字の大きさで89.6%を占めます。Macに読み替えられるのはProtonの20件=5.5%だけでした。

Verifiedバッジを見て「Macでも大丈夫そう」と思うのは、試験の9割を占める科目を見て、残り1割の科目の点数を当てようとしているのと同じことになります。

【集計2・公開データ】Deckの判定とMac版の有無を突き合わせる

比率の話だけでは実感が湧かないので、実際のタイトルで見てみます。Steamのストア情報にはplatforms.mac(Macネイティブ版があるか)が入っているので、判定ごとに数えました。

Deckの判定本数Macネイティブ版あり割合
Verified311239%
一部動作391231%
非対応25416%
不明4125%

Verifiedでも39%、非対応でも16%。差はありますが、予測に使えるほどの差ではありません。そして面白いのは、非対応側にいる4本です。

★逆転している4本

「Deckで動かない」のに「Macネイティブ版がある」タイトルが4本ありました。

タイトルDeckが弾いた理由Macでは
Rustアンチチートの構成ネイティブ版あり
Total War: WARHAMMER IIISteamOSが非対応ネイティブ版あり
OBS StudioSteamOSが非対応(ソフトウェア)ネイティブ版あり
Crimson Desert EnhancedDeckのグラフィック性能が足りないネイティブ版あり

いちばん下がはっきりしています。「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ネイティブ版の有無を並べました。

ProtonDBの評価ごとの「Macネイティブ版あり」の割合 platinum(29本) 45% gold(52本) 25% silver(4本) 25% bronze(5本) 40% borked(6本) 0% ★6本すべて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
OSSteamOS(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側の相当品
ProtonWindowsのプログラム → LinuxWine(Whisky・Porting Kit など)
FEXx86の命令 → ARMの命令★Rosetta 2(役目がそっくり)
LeptonAndroidのアプリ → 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の推測です。 同じWindowsゲームを動かすまでの階層 Steam Deck x86_64 / Linux Steam Frame ARM64 / Linux Mac ARM64 / macOS Windowsゲーム(x86) Windowsゲーム(x86) Windowsゲーム(x86) CPU変換は不要 FEX(x86 → ARM) Rosetta 2(x86 → ARM) Proton(Wine) Proton(Wine) Wine DXVK(D3D9/10/11) VKD3D-Proton(D3D12) DXVK(D3D9/10/11) VKD3D-Proton(D3D12) D3DMetal / DXMT / WineD3D Vulkan Vulkan Metal GPU GPU GPU Steam FrameとMacは同じ3階建て。違うのは最下段がVulkanかMetalかだけ

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 SkyBattle 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で起動します。

MacのWhisky上で動いているEndless Skyのタイトル画面。惑星と星が描画されている

完璧です。惑星も、背後の星も、スクロールするクレジットも、UIの枠も出ています。新しいパイロットを作る画面へ進むと、写真のテクスチャもそのまま出ました。

Endless Skyのゲーム開始直後の会話画面。挿絵と本文が表示されている

ゲーム本編に入り、借金の説明を受けるところまで進みました。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✓ 描画された
opengl3,712✓ 描画された
software(CPU描画)3,581✓ 描画された
同じWesnothを2つの描画方式で起動した比較。左のdirect3d11は真っ黒、右のopenglは地図とメニューが正しく表示されている

同じゲーム、同じ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 1mingwの 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の話ではなかった、というのがいちばんの収穫です😊

それでは、今回はここまで。最後までありがとうございました😊

参考サイト

実測した環境: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日に取得した公開エンドポイントの値です。