HTML5製のゲームにSteamSDKを導入する手順（NW.js + Greenworks）

Steamに出すためのビルドをつくる流れを説明します。
Steamへの登録や申請などについてはこの記事では触れません。

# 登場人物

|name|desc|
|---|---|
|NW.js|Chromiumを内蔵してWebアプリをネイティブ化するフレームワークです。Electronと同じ類のものです。|
|SteamWorks SDK|実績機能といった各Steamの機能を使うためのSDKです。それら機能を使わないとしてもSteamへのリリースには導入必須です。|
|Greenworks|上記Steamworks SDKをNode.jsで動かすためのパッケージです。|

# NW.jsでネイティブ化

https://nwjs.io/

公式サイトから目当てのOSのファイル一式をダウンロードします。

SDK版でないと検証ツールがつかないので、開発時はそちらがいいと思います。

各OS向けにリリースする場合、各OS向けのNW.jsを用意して構築する必要があります。

ダウンロードしたら、

- その直下がpublicディレクトリとなるイメージで、エントリー画面となる`index.html`や必要な`js`や`css`などを置きます。
- 同じく直下にpackage.jsonを置きます。

例えばこんな感じです↓

```md
- NW.js本体
  - 元々あるファイルたち
  - package.json
  - index.html
  - js
    - index.js
```

ただし、mac版だと `/nwjs.app/Contents/Resources/app.nw/*` 配下に置くようです。

package.jsonのマニュアルはこちら
https://nwjs.readthedocs.io/en/latest/References/Manifest%20Format/

最小だとこんな感じ↓

```json
{
  "name": "helloworld",
  "main": "index.html"
}
```

ちなみに、ゲーム自体の資材（jsや画像など）はnwのディレクトリに含めてもいいし、自分のサーバーでホスティングしてそこへ取りに行かせてもいいです。

サーバーに置けば、ネイティブ側のアップデートなしでゲームの不具合修正などができますね。

## 起動

起動するには、OSによりますが直下にある`nw`や`nw.exe`という実行ファイルを実行してください。

Ubuntuではこの`nw`が何故か実行ファイルとして認識されなかったので、`*.desktop`ファイルを設置するようにしました。

```
[Desktop Entry]
Name=AppName
Exec=sh -c "$(dirname %k)/nw"
Terminal=false
Type=Application
```

## 自動化

ここまで行った手順は、 [nw-builder](https://www.npmjs.com/package/nw-builder) というパッケージで自動化できます。

# GreenworksでSteam対応

Greenworks https://github.com/greenheartgames

ゴール:

1. 必要なファイルを準備する
2. さっきのNW.jsのプロジェクト内に配置する
3. アプリ（`index.html`）からGreenworksを使えるようになる

```
- さっきのNW.js
    - さっきのファイルたち
    - lib
        - libsdkencryptedappticket.拡張子 // ① Steamworks SDK
        - libsteam_api.拡張子 // ② Steamworks SDK
        - greenworks-OS名.node // ③ Greenworks本体
    - greenworks.js // ④ Greenworksのセットアップスクリプト
    - steam_appid.txt // ⑤ 開発時に仮でゲームIDを定義するファイル
```

①②は[Steamworks](https://partner.steamgames.com/doc/sdk?l=japanese)から入手できる。
③はビルド生成物となり、[Greenworksのリリース](https://github.com/greenheartgames/greenworks/releases)から入手できる。
④は[Greenworksのリポジトリ](https://github.com/greenheartgames/greenworks/blob/master/greenworks.js)から入手できる。
⑤は開発用で、[Steamworksのドキュメント](https://partner.steamgames.com/doc/sdk/api)に説明があります

しかし問題が一つあり、GreenworksのGithubで公開されている③のビルドは、最新のNode.jsに対応していません。

~~なので、最新のNW.js（=最新のChromium+最新のNode.js）で作る場合、Greenworksをクローンして自分でビルドしなければいけません。~~

*[2021-03-31追記] 最新のnode向けのビルドを配布してくれているリポジトリを見つけました（後述）*

## 古いNW.jsで構わない場合:

Greenworksでビルドをダウンロードする際、対応しているNW.jsが示されているので、それを[NW.jsのアーカイブ](https://dl.nwjs.io/)から取得します。

配布されているビルドを`ゴール`で示したように配置します。（[参考](https://github.com/greenheartgames/greenworks/blob/master/docs/quick-start-nwjs.md)）

`Steamworks SDK`はSteamworksからダウンロードしてください。

*追記した通り、最新のNW.jsで動くビルドを入手できるので、あえて古いNW.jsを使う必要はありません。が、さらに後述する「Steam Overlayが動かない」という問題は古いNW.jsを使うことで解決できる可能性があります。*

## 最新のNW.jsでつくる場合:

~~1. Greenworksをクローン
2. Steamworks SDKのディレクトリをまるごと`steamworks_sdk`にリネームして`deps`に配置（[参考](https://github.com/greenheartgames/greenworks/blob/master/docs/get-steamworks-sdk.md)）
3. nw-gypを使って再ビルド（[参考](https://github.com/greenheartgames/greenworks/blob/master/docs/build-instructions-nwjs.md)）~~

~~再ビルド手順~~

```bash
$ sudo npm install -g nw nw-gyp
$ cd Greenworksのディレクトリ
# targetはNW.jsのバージョン archは64bit
$ nw-gyp configure --target=0.46.1 --arch=x64
# targetはNode.jsのバージョン
$ nw-gyp build --target=v14.4.0
```

~~再ビルドに成功すると、直下の`lib`に`greenworks-OS名.node`を含む必要なファイルができるので、
それをさっきの`ゴール`のように配置する。~~

~~ビルドだとかの知識が皆無なのでよくわからないんですが、多分各OSでこの作業が必要です。~~

~~OSごとに色んな理由でうまくいかなかったりすると思いますが、それは一つずつ調査して解決しましょう…。~~

**[2021-03-31追記] こちらのリポジトリから最新のnode、steamworks SDKに対するビルドを入手できます。**

https://github.com/ElectronForConstruct/greenworks-prebuilds

Releasesのところから、最大限の感謝をこめつつダウンロードしましょう。

たくさん種類があって迷いますが、僕の例でいくと「NW.js」「v89（当時最新）」「x64（64ビットOS向け）」を各OS向けに合計3つ入手しました。

ビルドが用意できたら、`ゴール`で示したようにリネームして配置します。③です。（[参考](https://github.com/greenheartgames/greenworks/blob/master/docs/quick-start-nwjs.md)）

# Steamworks SDKを使ってみる

greenworksのビルドとSteamSDKを配置したら、エントリーポイント内から以下のようにgreenworksを読み込めるようになります。

```js
const greenworks = require('./greenworks.js')
greenworks.init()
```

最初`steamが起動していない` 的なエラーが出てなんのこっちゃと思いましたが、
本家Steamアプリが起動していないといけないようです。

問題なく読み込めたら、[Greenworksのドキュメント](https://github.com/greenheartgames/greenworks/tree/master/docs#api-references)を参考に目的の機能を使ってみましょう。

## Steam overlayが動かない

Steamオーバーレイとは、ゲーム内でSteamの機能（フレンドリストを開いたり）にアクセスできるものです。

僕はどうやってもこれを動作させることができませんでした。

色々調べた限り、これはgreenworksのせいではなく、NW.jsのグラフィック関係の処理の影響みたいです。
[Has anyone successfully integrate Steam Overlay with Greenworks SDK?](https://www.reddit.com/r/gamedev/comments/mc9s5x/has_anyone_successfully_integrate_steam_overlay/)

古いNW.jsにおいては、chromium起動オプションに`--in-process-gpu --disable-direct-composition`をつけると動作していたらしいです。

同じ問題か分かりませんが、Steamのスクリーンショット機能も動作しません。

うまくいった方が居たらぜひ情報をいただきたいです。

ちなみに、Steamに審査に出した際、Steamオーバーレイについて指摘事項に挙げられましたが、必須事項というわけではないようで、このままでもリリースは可能です。

# おわりに

NW.jsもElectronもそうですが、Chromiumを丸ごと含むので容量が大きくなることが難点ですね。

ともあれ、Greenworksという素晴らしいラッパーライブラリには心より感謝します。