参考にした記事:
1. Phaser 3 で HTML5 のゲームを作成する
↑ Phaser 3 でゲーム作成を検討する場合、2024/03 に出た create-phaser-game
を使うとフレームワークとバンドラーを組み合わせたテンプレートを作ってくれる。(ただ、比較的新しいツールのためか、昔からある公式の Getting Started Tutorial や Making your First Game や Phaser 導入記事などで取り扱いが薄い。)
↑ の記事にあるような、Vite で開発するプロジェクトテンプレートを作ってくれる。v1.2.3 で作成すると、以下のような構成のプロジェクトが作成された。 (Demo Game など、バンドラーだけで Phaser 以外のフレームワークを使わない構成もある)
my-phaser-game/
- public/
- src/
- index.html
- package.json
- ...
その後 CLI は以下のように開発方法も指示してくれる。
...
o----------------------------------------------------------o
| Project created successfully |
| Thank you for using Phaser |
| Tell us about your game! - games@phaser.io |
o----------------------------------------------------------o
Next steps:
1. cd my-phaser-game
2. npm install
3. npm run dev
CLI の指示どおり npm install
npm run dev
することで、Vite を使ったブラウザで常時確認しながらの開発ができる。npm run build
では公開用のファイルをビルドすることができて、dist
ディレクトリに成果物ができる。
my-phaser-game/
- ...
- dist/
- assets/
- favicon.ico
- index.html
この dist
をインターネットに公開すればそのままブラウザで動かせるゲームを公開できる。今回はこれを Steam 連携するために、NW.js で動かす。
2. Phaser 3 で作ったゲームを NW.js で動かす
2.1. NW.js のダウンロード
NW.js のダウンロードの際、Steam 連携用ライブラリの Greenworks とバージョンを揃えたい関係で、バージョンを確認する必要がある。NW.js のブログの情報と Greenworks の対応情報、Steamworks.js 内の redistributable_bin のバージョン をまとめると、2024/07 現在
NW.js (Chromium + Node) | Greenworks | Steamworks.js | Steamworks SDK |
---|---|---|---|
2024/06/25 0.89.0 Chromium 126 + Node 22.2.0 | 2024/07/27 0.17.0 Steamworks SDK 1.60 | 2024/06/26 1.60 | |
2024/05/21 0.88.0 Chromium 125 + Node 22.0.0 | |||
2024/05/21 0.87.0 Chromium 124 + Node 21.1.0 | |||
2024/05/21 0.86.0 Chromium 123 + Node 21.1.0 | 2024/04/07 0.16.0 Steamworks SDK 1.59 | 2024/02/09 1.59 | |
2024/05/21 0.85.0 Chromium 122 + Node 21.1.0 | |||
2024/05/21 0.84.0 Chromium 121 + Node 21.1.0 | |||
2024/05/21 0.83.0 Chromium 120 + Node 21.1.0 | |||
2024/05/21 0.82.0 Chromium 119 + Node 20.0.7 | 2023/11/05 0.15.0 Steamworks SDK 1.58 | 2024/06/04 0.3.2 Steamworks SDK 1.58a | 2023/10/25 1.58a |
なので、今回は nwjs-v0.89.0-win-x64.zip
と greenworks-v0.17.0-nw-v0.89.0-win-64.zip
と steamworks_sdk_160.zip
をダウンロードした。Steam 連携などを考えなければどの NW.js で問題なさそうだが、Steam 連携しないならそもそも Web 上でそのまま公開する方が早そう。
Greenworks は開発がしばらく止まっていたので Steamworks.js などのフォロワーが生まれていたが、2024/07 現在
- Greenworks
- Steamworks.js
と、2018 年から開発が止まっていた Greenworks にも 2023 年後半からちょこちょこ更新が入っていた。元記事が充実していたので NW.js + Greenworks を試すことにした。
2.2. dist/ を NW.js で起動
元記事 を参考に、nwjs-v0.89.0-win-x64.zip
を展開してできるファイル群に dist/
配下のファイルをコピーする。コード上、index.html
が ルートになる想定なので、dist/
ディレクトリごとコピーするとうまくいかないので注意。
my-phaser-game/ nwjs-sdk-v0.89.0-win-x64/
- ... - ...
- nw.exe
- package.json ★追加する
- dist/
- assets/ -- cp --> - assets/
- favicon.ico -- cp --> - favicon.ico
- index.html -- cp --> - index.html
↑のように、nw.exe
と同じディレクトリにファイル群をコピーする。package.json
は NW.js 用の書式で
{
"name": "my-phaser-game",
"main": "index.html"
}
のように追加する。Phaser の dist/
はブラウザコンテキストで動かせる状態なので、この時点で nw.exe
を起動して試してみても問題なく動く。
3. Phaser 3 で作ったゲームを NW.js で動かしつつ、Greenworks で Steam 連携を実装する
3.1. ディレクトリ構成
元記事 のままファイルを配置すれば OK で、それぞれのディレクトリの下から NW.js 下にコピーする場合、以下のようになる。Greenworks 用のコピーは公式も参考にする。win64 の例を書くと、
| my-phaser-game/ | greenworks-v0.17.0-*/ | steamworks_sdk_160/ | nwjs-sdk-v0.89.0-win-x64/ |
| | | | - nw.exe |
| | | | - package.json ★追加する |
| - dist/ | | | |
| - assets/ --> - assets/ |
| - favicon.ico --> - favicon.ico |
| - index.html --> - index.html |
| | | | - steam_appid.txt★追加する |
| | - greenworks.js --> - greenworks.js |
| | - lib/ --> - lib/ |
| | - greenworks-win64.node --> - greenworks-win64.node |
| | | - sdk/redistributable_bin | |
| | | - steam_api.dll | |
| | | - win64/ | |
| | | - steam_api64.dll --> - steam_api64.dll |
| | | - sdk/public/steam/lib/ | |
| | | - win64/ | |
| | | - sdkencryptedappticket64.dll --> - sdkencryptedappticket64.dll |
のように各 zip から NW.js のディレクトリへコピーする。steam_appid.txt
は appid を入れるが、開発用には 480 を入れる。
480
最終的に NW.js には
nwjs-sdk-v0.89.0-win-x64/
- ...
- nw.exe
- package.json ①追加する
- assets/ ②dist/ からコピー
- favicon.ico ②dist/ からコピー
- index.html ②dist/ からコピー
- steam_appid.txt ①追加する
- greenworks.js ③Greenworks からコピー
- lib/ ③Greenworks からコピー
- greenworks-win64.node ③Greenworks からコピー
- steam_api64.dll ④Steamworks SDK からコピー
- sdkencryptedappticket64.dll ④Steamworks SDK からコピー
のように、それぞれ作成&コピーしてきたファイルが配置される。
3.2. Phaser のゲームから Greenworks 経由で Steamwork SDK の API を呼ぶ
あとは index.html
内のソースから require('greenworks.js')
すれば Greenworks 経由で Steam の API を呼べる状態だが、ここで若干ハマった。
Vite でビルドするとソースの本体は dist/
の assets/
内、index-***.js
にバンドルされる。この時、Vite はブラウザコンテキストで動かせるようにソースをビルドするので、CommonJS ライブラリを読む時のように greenworks.js
の拡張子を cjs にして import * as greenworks from './greenworks.cjs';
などとインポートした場合、ビルド時にブラウザで動かないコードがエラーになり、うまくバンドルされなかった。(greenworks.js
は NW.js や Node.js 上で動く想定なので steam_appid.txt
を読み込む require('fs')
などが普通にある)
3.2.1 Vite プラグインで解決
上記は同様の問題を Vite プラグインで解決している模様。
ただ、上記プラグインは試していないので、実際に該当プラグインを使って Greenworks が正しくバンドル&動作するかは確認できていない。プラグインが 2023/06/08 の 1.0.0 リリースのみであり、どこまでメンテナンスされ続けるか不明瞭だったのでなんとなく避けた。
3.2.2. ブラウザの global 経由で greenworks を使う
今回、Steam 連携はコードのメインではないので、ビルド外で require('greenworks.js')
したインスタンスを window
経由で参照する方法を試した。この場合 dist/assets
下の js には greenworks.js
が含まれないため、3.1 のように手動で配置して対応している。
利用方法としては assets/
の index-***.js
実行前に読み込んでおければどこでも良さそう。Phaser の create-phaser-game
では index.html
は以下のような感じで作られるが、
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/png" href="/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="/style.css">
<title>Phaser - Template</title>
</head>
<body>
<div id="app">
<div id="game-container"></div>
</div>
<script type="module" src="src/main.js"></script>
</body>
</html>
ゲーム本体の読み込み前に window.greenworks
を作り、Phaser の Scene などから参照できるようにした。
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/png" href="/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="/style.css">
<title>Phaser - Template</title>
</head>
<body>
<div id="app">
<div id="game-container"></div>
</div>
+ <script>
+ if (typeof nw !== 'undefined' && typeof nw.require === 'function') {
+ // NWJS環境
+ window.greenworks = require('greenworks.js');
+ console.log("Running in NWJS environment");
+ if (window.greenworks.init()) {
+ console.log("Steam initialized successfully");
+ } else {
+ console.log("Steam initialization failed");
+ }
+ } else if (typeof require !== 'undefined') {
+ // Node.js環境(NWJSのNode context含む)
+ console.log("Running in Node.js environment");
+ } else {
+ // ブラウザ環境
+ console.log("Running in browser environment");
+ }
+ </script>
<script type="module" src="src/main.js"></script>
</body>
</html>
その後、ゲーム内のコードで
this.greenworks = window.greenworks || null;
if (this.greenworks) {
try {
const username = this.greenworks.getSteamId().getPersonaName();
console.log(`Logged in as: ${username}`);
} catch (error) {
console.error("Failed to get Steam username:", error);
}
}
上記のように window 経由で呼ぶことで、Steam の情報取得ができることを確認できた。ただし実行時にインスタンスが入るため Greenworks の API を IDE で参照することはできなそうだし、TypeScript できちんと呼べるかなども試せていない。
4. まとめ
元記事 は 2021 年での内容だったが、2024/07 時点でも Phaser 3 + Vite + NW.js 0.89.0 + Greenworks 0.17.0 + Steamworks SDK 1.60 が動くことを確認できた。
結局のところ、Phaser 3 でのゲーム実装のほとんどはブラウザコンテキストで動くように作られるので、Native アプリをどのように作るのかは Steam 連携用のライブラリをどれにするかで決めるのが楽そうだった。Greenworks は NW.js 用のビルドを出しているので NW.js が利用しやすそうだが、Steamworks.js + Electron 方式が活発になるようなことがあれば NW.js でなくて Electron の方が実装しやすいというケースも今後出てくるかもしれない。開発的にコストをかけたくないところなので、ここに依存して全体のパッケージ構成を変えるなどもあまりしたくないところ。
4.1. Steam Overlay 問題
解決できていないので、調べたメモだけ。
4.1.1. Construct 3 での知見
Phaser と同様の HTML5 を利用するゲームエンジンに Construct 3 がある。ブラウザ上の IDE 提供や有償プランもある大きめのプロダクトで、プロジェクトの export をする時に Windows 向けとして NW.js をターゲットにすることもでき、チェックボックスには Steam 対応というオプションもあるようだ。
Export for Steam
Change the configuration to improve compatibility with Steam. This sets the command line options --in-process-gpu and --disable-windows10-custom-titlebar, and also forces the window to constantly redraw to improve compatibility with the Steam Overlay.
↑内部的には例の --in-process-gpu
やらをつける挙動になるらしい。(有料版でしか使えない機能なので未検証)
Construct 3 の Steam 周りの対応をメンテナンスしてきたらしい方が上記スレッドでレポートしているが、最新版の完全な対応はまだできておらず、「最も安定して動く NW.js 0.72.0 で動かすしかない」という感じで、NW.js の古いバージョンを利用する案を進めている。NW.js 0.72.0 は Chromium 109 + Node 18.9.1 で 2023/01/14 にリリースされていて、Greenworks のリリースが止まっていた期間 (2018/11 ~ 2023/11) のため該当 Node 向けバイナリは公式に無い状態。ので、元記事 にリンクがある&この方もスレッドで言及している
という Greenworks の該当 NW.js カスタムビルドのリンクから該当バージョンのバイナリを落とす必要がありそう。
試しに動かそうと思い、スレッドを参考に nwjs-sdk-v0.72.0-win-x64
+ steamworks_sdk_158a
+ greenworks-v0.15.0-nw-v0.82.0-win-64
(の、greenworks-win64.node
をダウンロードしたファイルに変えた版) を動かしてみたが、自分の環境だと Overlay しないというかクライアントが急に落ちたり、1. ~ 3. 項で試した NW.js 0.89 版より不安定になったのであまり検証できていない。
4.1.2. Overlay 問題で動かない部分
試してみて気付いたのは、Overlay がうまくいってない状態であっても右下から実績解除のポップアップなど出すことはできるので、ゲームによってはまぁなくてもなんとかなるかな… といった感じ。