デスクトップ出力での大冒険
PygameをクロスプラットフォームでWebアプリもデスクトップアプリも
Python環境なしでも実行できるものを出力したい、ってことで試行錯誤してました。
NW.jsでの挑戦から、Windows用Webサーバー「MiniWeb」での一瞬の成功、
そしてGoサーバーでの突破まで──その全記録をまとめます。
この記事は、同じように pygame × WASM(WebAssembly) × デスクトップ配布 に挑戦する人の参考になれば幸いです。
忙しい人のために:この記事のまとめ
- NW.jsは技術的に動かず断念。
- Windows用Webサーバー「MiniWeb」で一度は成功するも、Windows専用で配布に不向き。
- Goのhttp.FileServerでクロスプラットフォームを狙うが、MIME問題で失敗。
- MIME補正(.wasm=application/wasm, .apk=application/zip)+CDNリダイレクトで突破。
- 最小構成(index.html + myapp.apk + favicon.png)で動作確認に成功。
- 結論:Goサーバー同梱方式がPygameラッパーライブラリのデスクトップ配布解決策。
トラブルシューティング時系列
1. NW.jsでの挑戦
- 当初はNW.jsでラップして配布を狙った。
- しかしNode.jsベースの仕組みと、pygbagが生成する WASMローダー が干渉してしまい、まともに動作せず。
- 具体的には、NW.jsの内部環境がブラウザAPIを完全に再現していないため、
fetch()での.apk読み込みやSharedArrayBufferの扱いでエラーが発生。 - 「これは時間をかけても厳しい」と判断して断念。
2. 自鯖アプローチに転換
- 「ローカルにサーバーを立てて配信すればいいのでは?」と発想を転換。
- 軽量サーバーとして MiniWeb を試す。
3. MiniWebでの成功と限界
-
index.htmlとmyapp.apkを配信したら、なんと動いた! - しかしMiniWebはWindowsバイナリ前提で、クロスプラットフォーム性に欠ける。
- 「動くけど、配布用には現実的じゃない」と課題が残る。
- 更新が2013年でストップしてて古いし。
4. Goサーバーに挑戦
- 「Goなら単一バイナリでクロス配布できる」と判断。
-
http.FileServerを使って自鯖を実装。 - しかしブラウザは真っ白、コンソールには
archives 404やMEDIA USER ACTION REQUIRED。 - クリックしても
myapp.apkがロードされない。
5. 原因の特定
- GoのFileServerが
.wasmと.apkを application/octet-stream で返していた。 - pygbagローダーは
.wasm=application/wasm、.apk=application/zipを期待している。 - MIMEが違うため、apkマウントが始まらなかった。
6. 修正と突破
- GoサーバーにMIME補正を追加:
.wasm → application/wasm.apk → application/zip
- さらに
/archives/をCDNにリダイレクトする処理を追加。 - → ついにGoサーバーでも動作!しかもMiniWebより高速。
MIME補正についての実際のコード断片はこんな感じ:
import (
"mime"
"net/http"
)
func main() {
// MIME補正
mime.AddExtensionType(".wasm", "application/wasm")
mime.AddExtensionType(".apk", "application/zip")
// ./web フォルダをルートとして配信
fs := http.FileServer(http.Dir("./web"))
http.Handle("/", fs)
http.ListenAndServe(":8000", nil)
}
/archives/ のCDNリダイレクト処理
http.HandleFunc("/archives/", func(w http.ResponseWriter, r *http.Request) {
target := "https://cdn.example.com" + r.URL.Path
http.Redirect(w, r, target, http.StatusFound)
})
-
/archives/以下のリクエストはすべて外部CDNに転送される。 - ローカルには最小構成(index.html + myapp.apk + favicon.png)だけ置いておけばOK。
7. 最小構成での動作確認
-
index.html + myapp.apk + favicon.pngの3ファイルだけで動作することを確認。 - 「CDN参照モードなら最小構成で配布可能」という結論に到達。
結論
- NW.jsは使えなかった。
- MiniWebは動いたが配布に不向き。
- Goサーバー同梱方式こそが現実解。
Pygameラッパーライブラリの「デスクトップ配布モード」は、Goサーバーを同梱してブラウザを自動起動させる方式に落ち着きました。
結果的に「軽量でクロスプラットフォーム」「Python環境不要」「最小構成で配布可能」という理想的な形に。
参考リンク
最後までお読みいただきありがとうございました!
この記事が役に立ったら『いいね』や『ストック』で応援していただけると嬉しいです。
Pygameラッパーライブラリの開発記録は今後も追加予定です 🚀