【NeosVR】ヘッドレスクライアントの起動設定ファイルメモ

本記事ではNeosVRのヘッドレスクライアントの起動設定を記載するconfig.jsonについて記載します。

私自身もまだNeosVRのヘッドレスクライアントについて詳しいわけではありませんが、日本語でまとまった情報があまりにも少ないように思われるため作成しました。
情報は2021/5時点のものとなります。現在NeosVRのアップデート頻度は非常に高いため、貴方がこの記事を読んだ時には仕様が変更されているかもしれません。
基本的に最新情報はNeosVR公式Discordのどこかにあります。

#設定項目について

設定項目にはサーバー共通の設定と、セッションごとに行う設定の二種類が存在します。
文字列項目はダブルクォーテーションで囲う必要があります。

##サーバー共通設定

|設定項目|設定値|設定|例|
|:--|:--|:--|:--|
|comment|任意の文字列|configファイルの用途などを自由に記載する。挙動に影響は無い。|"comment":"常設ヘッドレス用"|
|tickRate|数値(デフォルト値:60.0)|1秒間に何回同期するかを数値で指定する。<br>値を大きくすると同期がよくなるがネットワーク負荷が増える。|"tickRate":60.0|
|maxConcurrentAssetTransfers|数値(デフォルト値:おそらく4)|1セッションあたりのアセット同時転送最大数を数値で指定する。<br>値を大きくするとアセットの転送が早くなるがネットワーク負荷が増える。|"maxConcurrentAssetTransfers":4|
|usernameOverride|文字列(デフォルト値:null)|ゲーム内でのヘッドレスのホスト名表示を上書きしたい場合に任意の文字を設定する。<br>nullの場合元の名前が使用される。|"usernameOverride":"hoge-headless"|
|loginCredential|メールアドレス(デフォルト値:null)|ヘッドレス用のNeosVRアカウントのメールアドレスを設定する。|"loginCredential":"hoge@example.com"|
|loginPassword|null|ヘッドレス用のNeosVRアカウントのパスワードを設定する。<br>loginCredentialとセットで設定する必要有。<br>アカウントを用意するとヘッドレスクライアントとフレンドになることが出来、フレンドプラスやフレンドオンリー(ヘッドレスアカウントとのフレンドオンリー)といった運用が可能となる。<br>設定を推奨。|"loginPassword":"hogehoge"|
|startWorlds|<セッション設定>|ヘッドレス起動時に開始する各セッションの設定を行う。後述の[セッション単位設定](#セッション単位設定))を参照。|"startWorlds":[{<セッション設定1>},{<セッション設定2>}]|
|dataFolder|フォルダパス|データファイルを格納するフォルダを指定する。<br>localMachineで起動する場合に機能すると思われる。<br>空の場合「<インストールフォルダ>/HeadlessClient/Data」が使用される。|"dataFolder":"D:\NeosData\Data"|
|cacheFolder|フォルダパス|キャッシュファイルを格納するフォルダを指定する。<br>localMachineで起動する場合に機能すると思われる。<br>空の場合「<インストールフォルダ>/HeadlessClient/Cache」が使用される。|"cacheFolder":"D:\NeosData\cache"|
|allowedUrlHosts|URL|ヘッドレスから通信を許可するホストを[]内にカンマ区切りで設定する。|"allowedUrlHosts":["localhost","hogehoge.com"]|
|autoSpawnItems|不明|アイテムを自動的にスポーン出来る機能だと思われるが不明。|不明|
|metamovieRoles|不明|不明|不明|

##セッション単位設定

startAsOwnerとautosaveIntervalはヘッドレス運用を行う上で非常に重要なのできちんと理解して設定してください。

|設定項目|設定値|設定|例|
|:--|:--|:--|:--|
|isEnabled|true|該当セッションを起動するかどうかをtrue/falseで設定する。|"isEnabled":true|
|saveAsOwner|null(デフォルト値)<br>CloudUser<br>LocalMachine|該当セッションの保存場所を指定したい場合に設定する。用途に応じて使い分ける。<br><br>nullの場合保存することは出来ない。<br><br>CloudUserの場合Neosクラウドにデータが保存されるが、容量に注意。基本的にPatreon連携アカウントとは別のNeosアカウントを使用してヘッドレスを起動すると思われるのでその場合容量の上限は1GBとなる。<br><br>localMachineの場合、ヘッドレスを起動している機器のローカルに保存する。<br><br>※一度設定した状態でヘッドレスを起動すると以降はloadWorldURLで管理されるためnullに置換される。|"saveAsOwner":"localMachine"|
|autoInviteUsernames|ユーザー名|セッション起動時にインバイトを送信するユーザ名を[]の中にカンマ区切りで記述する。|"autoInviteUsernames":["UserA","UserB"]|
|autoInviteMessage|文字列|autoInviteUsernamesで指定したユーザにインバイトを送信する際に送るメッセージを設定する。|"autoInviteMessage":"セッションへの接続が可能となりました。"|
|autoRecover|true/false(デフォルト値:不明)|不明。オートリカバリーを行うかどうか?<br>trueで運用していますがあまりクラッシュすることはありませんし、クラッシュした際には復旧してくれないイメージです。|"autoRecover":"true"|
|idleRestartInterval|秒(デフォルト値:-1.0)|正の値を設定することで、セッション内のユーザーが0人の状態が設定した秒数続いた際に自動的に再起動を行う。<br>再起動を行う際にセッションの状態はセーブされないため使用する場合は注意。|"idleRestartInterval":3600|
|forcedRestartInterval|秒(デフォルト値:-1.0)|正の値を設定することで、設定した秒数後に強制定期に再起動を行う。再起動を行う際にセッションの状態はセーブされないため使用する場合は注意。|"forcedRestartInterval":86400|
|forcePort|数値(デフォルト値:null)|セッションで使用するポートを明示的に指定する。|"forcePort":17777|
|saveOnExit|true/false(デフォルト値:おそらくfalse)|shutdownコマンドなどを使用して終了する際にセーブを行うかどうかを設定する。|"saveOnExit":true|
|autosaveInterval|秒(デフォルト値:-1.0)|正の値を設定することで、設定した秒毎に自動保存を行う。<br>ただし保存したデータには削除したアイテムも残ったままとなってしまうため、短い間隔で保存を行うようにするとディスク容量を圧迫してしまう。<br>使用する際には十分な注意が必要。|"autosaveInterval":-1.0|
|autoSleep|true/false(デフォルト値:不明)|不明。|"autoSleep":false|
|sessionName|任意の文字列|セッションの名前を設定する。|"sessionName":"hoge-world"|
|customSessionId|<ユーザーID>:<任意の文字列>|セッションIDを固定する場合に使用する。任意文字列の長さに制限があるかは不明。|"customSessionId":"U-hoge:hogeworld1"|
|description|任意の文字列|ゲーム内で表示されるワールドの説明を必要に応じて記載する。|"description":"ここはhoge-worldです。hogehogeしましょう。"|
|maxUsers|数値|ワールドに入れる最大人数を設定する。|"maxUsers":10|
|accessLevel|誰でも:Anyone<br>登録ユーザ:RegisteredUsers<br>フレンド+:FriendsOfFriends<br>フレンドのみ:Friends<br>LAN内のみ:LAN<br>招待のみ:Private|セッションへ入れるレベルを設定する。フレンドはホストとフレンドであるかどうか。|"accessLevel":"FriendsOfFriends"|
|hideFromPublicListing|true/false(デフォルト値)|trueの場合セッションリストから表示されなくなる。|"hideFromPublicListing":false|
|tags|文字列|ワールドの情報を示すタグを[]にカンマ区切りで定義する|"tags":["hoge","chill"]|
|mobileFriendly|true/false|モバイル用(Androidなど)に最適化するかどうか、ただし現状モバイル端末で使用することはほぼ無い。|"mobileFriendly":false
|loadWorldURL|neosrec://<レコードURL>|起動時に特定のワールドを指定する場合に設定する|"loadWorldURL":"neosrec:///G-hoge/R-00000000-0000-0000-0000-000000000000"|
|loadWorldPresetName|以下いずれかの文字列<br>SpaceWorld<br>Basic Empty<br>GridSpace<br>Microworld<br>Testing Scaling<br>ScratchSpace<br>"ScratchSpace (mobile)<br>Instancing Test<br>Physical Locomotion Test<br>UIX Test|テンプレートワールドを開く場合に指定する<br>loadWorldURLに正しい値が設定されている場合は、そちらが優先される。|"loadWorldPresetName":"SpaceWorld"|
|keepOriginalRoles|true/false(デフォルト値)|セッション内で設定したユーザーの権限を以降も保持するかどうか。<br>一時的な変更としたい場合はtrue。<br>永続的な変更としたい場合はfalse。|"keepOriginalRoles":false|
|defaultUserRoles|<ユーザ名>:<権限名>|{}内にカンマ区切りでユーザロールを定義する。|"defaultUserRoles":{"hoge:Admin","huga:Builder","badman":"Spectator"}|
|roleCloudVariable|string型CloudVariable変数|CloudVariableを用いてセッション内でのユーザ権限を設定する。<br>CloudVariableに正しい値が設定されていない場合はデフォルトのロールが適用される。<br>CloudVariableには「Admin/Builder/Moderator/Guest/Spectator」のいずれかを設定する。|"roleCloudVariable":"hoge.permission"|
|allowUserCloudVariable|bool型CloudVariable変数|CloudVarableを用いてセッション内へmaxUsersの値を無視して入場出来るようにする。<br>CloudVariableに値が設定されていない場合はfalse扱いとなる。<br>CloudVariableには「true/false」のどちらかを設定する。|"allowUserCloudVariable":"hoge.allow"|
|awayKickMinutes|分(デフォルト値:-1.0)|正の値が設定されている場合、AFK状態のユーザが指定分経過後にキックされる|"awayKickMinutes":30|

#初回起動時の設定例

私が運用しているヘッドレスをベースとした、config.jsonファイルの初回起動時の設定例を記載します。
正常に起動するとsaveAsOwnerの設定値はnullとなり、loadWorldURLに値が設定されます。

以下のように用途に合わせてカスタマイズします。

1. アセット同期を良くするため「maxConcurrentAssetTransfers」を「6」に増やす。
1. ヘッドレスでフレンド機能を活用するため、ヘッドレス用Neosアカウント(hoge-headless)の認証情報を「loginCredential」と「loginPassword」に定義。
1. 起動時にヘッドレス管理者である自分(hoge)を自動で招待したいため、「autoInviteUsernames」に「hoge」ユーザを定義。
1. 無料Neosユーザのまま大きなデータを保存したいため、「saveAsOwner」の値を「localMachine」に設定しサーバローカルにデータを保持するように設定。
1. 動作を安定させたいため、「idleRestartInterval」の値を「3600」に設定し、誰も居ない状態が1時間継続した場合セッション再起動するように設定。
1. セッション名を変更したいため、「sessionName」の値を「hoge-world」に変更。
1. 小規模のセッションとしたいため、「maxUsers」の値を「10」に変更。
1. 所謂フレンド+で動作するセッションとしたいため、「accessLevel」の値を「FriendsOfFriends」に変更。
1. 起動テンプレートを「SpaceWorld」としたいため、「loadWorldPresetName」の値を「SpaceWorld」に設定。
1. ヘッドレス管理者である自分(hoge)をセッション内でも管理者としたいため、「defaultUserRoles」に「hoge」ユーザを「Admin」にするよう定義。
1. セッション内でユーザーの権限をCloudVariable「G-Hoge-Project.hoge.permission」で管理するため、「roleCloudVariable」に「G-Hoge-Project.hoge.permission」に設定。
1. セッション内の人数に関わらず入室出来るユーザーをCloudVariable「G-Hoge-Project.hoge.allow」で管理するため、「allowUserCloudVariable」に「G-Hoge-Project.hoge.allow」を設定。

```
{
  "comment": "hoge-headless config",
  "tickRate": 60.0,
  "maxConcurrentAssetTransfers": 6,　
  "usernameOverride": null,
  "loginCredential": "<hoge-headlessアカウントのメールアドレス>",
  "loginPassword": "<hoge-headlessアカウントのパスワード>",
  "startWorlds": [
    {
      "isEnabled": true,
      "saveAsOwner": "localMachine",
      "autoInviteUsernames": [
        "hoge"
      ],
      "autoInviteMessage": null,
      "autoRecover": true,
      "idleRestartInterval": 3600.0,
      "forcedRestartInterval": -1.0,
      "saveOnExit": true,
      "autosaveInterval": -1.0,
      "autoSleep": true,
      "sessionName": "hoge-world",
      "customSessionId": null,
      "description": null,
      "maxUsers": 10,
      "accessLevel": "FriendsOfFriends",
      "hideFromPublicListing": false,
      "tags": [],
      "mobileFriendly": false,
      "loadWorldURL": null,
      "loadWorldPresetName": "SpaceWorld",
      "forcePort": null,
      "keepOriginalRoles": false,
      "defaultUserRoles": {
        "hoge": "Admin",
      },
      "roleCloudVariable":"G-Hoge-Project.hoge.permission"
      "allowUserCloudVariable":"G-Hoge-Project.hoge.allow"
      "awayKickMinutes": -1.0
    }
  ],
  "dataFolder": null,
  "cacheFolder": null,
  "allowedUrlHosts": null,
  "autoSpawnItems": null,
  "metamovieRoles": null
}
```
#編集履歴
1.01 誤字修正
1.02 Config.jsonの設定例に「roleCloudVariable」、「allowUserCloudVariable」を追加

#参照

+ NeosVR公式Discord
+ [NeosVR日本語Wiki - ヘッドレスクライアント](https://neosvrjp.memo.wiki/d/%a5%d8%a5%c3%a5%c9%a5%ec%a5%b9%a5%af%a5%e9%a5%a4%a5%a2%a5%f3%a5%c8)
+ [Neos公式wiki Headless Client/Server](https://wiki.neos.com/Headless_Client/Server)