Try   HackMD

No Man's Sky 基地のバックアップ・復元・移転まとめ(PC版プレイヤー向け)

Save Editorを使用した基地のバックアップ・復元・移転の方法を解説する。
またBase Builder(Blenderアドオン)についても簡易的に解説する。

  • 2023Q4、ゲームバージョン4.45時点の情報
  • 記述は全てWindows環境のもの
  • 免責事項: 本稿の情報を使用したことにより発生したあらゆる損害について筆者は一切の責任を負わない

1. Save Editor

  • セーブデータの生データ(JSON形式)を直接編集する機能を使用して基地データを操作する
    • Save Editorには専用の基地バックアップ・復元機能が存在するが本稿では使用しない
  • Java製のためJava実行環境があるプラットフォームであればOSを選ばず使用可能

1-1. セットアップ

  • Java実行環境 をインストールする
  • 公式GitHub Installation セクションの latest version のリンクからインストーラー(自己解凍7ZIP書庫)をダウンロードして実行する
    • インストール場所は任意
      • 使用方法によってはバックアップファイルが大量に作られるため、アクセスしやすい場所を推奨
    • NMSSaveEditor.bat を実行して起動する
  • 初回起動時にセーブデータの場所を指定する
    • Win+Steamであれば C:\Users\<USER_NAME>\AppData\Roaming\HelloGames\NMS\st_<ID>

1-2. セーブデータの選択方法

  • Main タブで使用するセーブデータを選択する
    • 日本語は文字化けするが実用上の問題はない
  • Game Slot のドロップダウンがゲーム内のセーブスロットに対応する
  • Save File のドロップダウンが個々のセーブデータに対応する
    • save[奇数].hg が自動セーブのデータ(スロット1のみ save.hg
    • save[偶数].hg が手動セーブ(復元ポイント)のデータ
  • Save Changes ボタンを押すと選択中のセーブデータに現在の編集状態が保存される
    • 同時にSave Editorの実行ファイルと同じ場所の backups フォルダに backup[数字]_[UNIXタイムスタンプ].zip というファイル名のバックアップが作成される
    • このバックアップは Save File のドロップダウンにも表示され、選択状態で Save Changes することで元のセーブデータが上書きされて復元される
  • 選択中のセーブデータがゲーム側で更新された場合はリロードするかどうかを確認するダイアログが開く

1-3. 基地データの取り扱い

  • メニューバーの EditEdit Raw JSON で内蔵JSONエディターを開く
  • 左側のツリーから PlayerStateDataPersistentPlayerBases と展開する
  • PersistentPlayerBases の下に並んでいる [整数] が個々の基地データに相当する
    • そのセーブデータ内で作成した基地は全てここに保存されると思われる
      • 作成日時降順で前詰めで格納されていると思われる
    • ここにある基地はセーブデータ内にキャッシュされている状態で、他のプレイヤーの基地も入ることがあるが条件は不明
  • 右側の編集可能な入力欄の内容が基地の生データとなる、以下このJSON形式の基地データを「基地JSON」と呼称する
    • 内容を保存することでバックアップできる(4-1で解説)
  • 内容を編集して内蔵JSONエディターを閉じようとすると変更を反映するかどうか確認するダイアログが開く
    • OKを押して反映し、更に Save Changes することでセーブデータに編集内容を反映できる
    • 編集する場合、JSON形式として正しければ改行やインデントの状態は不問
    • 逆にJSON形式として問題がある場合、確認ダイアログでOKを押しても再表示されて内蔵JSONエディターを閉じられなくなる
      • 特にエラーなどは出ないため、JSONの問題は別の手段で確認した方がよい(後述)

2. コードエディター

  • JSON形式は実体としてはただのテキストのためメモ帳でも編集できるが、カンマや引用符等が1個多かったり少なかったりするだけで壊れる厳密なフォーマットのため、基地JSONの編集にはJSON形式に対応したコードエディターの使用を推奨する
  • 本稿では Visual Studio Code (通称VSCode)を紹介する

2-1. Visual Studio Codeの使用

  • 公式サイト からダウンロードしてインストールする
  • ファイルの拡張子が .json であれば自動でJSON形式として認識される
    • 標準でJSON形式に対応している
    • なにかの都合でJSONと認識されなかった場合は、 Ctrl+K → Ctrlを離してM で言語選択メニューを開いてJSONを選択する
  • Ctrl+Shift+M で問題ビューを表示しておく
    • 編集中にJSONに問題が生じた場合はここに警告が表示される
  • その他Tips
    • 編集中に改行やインデントなどのフォーマットを統一したい場合は Shift+Alt+F でフォーマットできる
      • なおSave Editorに入力する内容はJSON形式として正しければよく、見た目は関係ない
    • 基地JSONのファイルを置くフォルダを作っておき、VSCodeでそのフォルダを開くとVSCode内のファイルツリーで操作できる(階層構造も可)
    • 行番号のエリアにマウスを移動すると表示される > 記号から、括弧に囲まれた範囲を開閉できる
    • 行を選択したい場合は行番号をクリックで選択可、ドラッグすると複数行選択可(前項で閉じたエリアもそのまま選択可能)
    • Shift+Alt+ドラッグ で矩形選択可
    • Ctrl+F で検索ダイアログ表示

3. 基地JSONの仕様

  • ゲームのアップデートによって基地JSONの仕様は変更される可能性がある
    • 互換性が失われる可能性もある
  • // から始まる記述は説明用のコメントであり実際には存在しない、また編集時に入力することもできない
{
  "BaseVersion": 8,
  "OriginalBaseVersion": 8,
  // 基地のある銀河・星系・惑星
  "GalacticAddress": "0x00000000000000",
  // 基地の座標
  "Position": [
    0.0,
    0.0,
    0.0
  ],
  // 基地の傾き補正値
  "Forward": [
    0.0,
    0.0,
    0.0
  ],
  "UserData": 0,
  "LastUpdateTimestamp": 1700000000,
  // 基地パーツの配列
  "Objects": [
    // 基地パーツ
    {
      "Timestamp": 1700000000,
      "ObjectID": "^BASE_FLAG", // 種類
      "UserData": 0,
      // 座標
      "Position": [
        0.0,
        0.0,
        0.0
      ],
      // 傾き
      "Up": [
        0.0,
        1.0,
        0.0
      ],
      // 傾き
      "At": [
        0.0,
        0.0,
        1.0
      ],
      "Message": ""
    },
    // 以下パーツの数だけ繰り返し
    { ... },
    { ... },
    { ... }
  ],
  // アップロード済の基地の識別ID(未アップロードの場合は "" )
  "RID": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  // 基地の所有者情報
  "Owner": {
    "LID": "00000000000000000",
    "UID": "00000000000000000",
    "USN": "Player Name",
    "PTK": "ST",
    "TS": 1700000000
  },
  // 基地の名前
  "Name": "My Awesome Base",
  "BaseType": {
    "PersistentBaseTypes": "HomePlanetBase"
  },
  "LastEditedById": "",
  "LastEditedByUsername": "",
  "ScreenshotAt": [
    0.0,
    0.0,
    0.0
  ],
  "ScreenshotPos": [
    0.0,
    0.0,
    0.0
  ],
  "GameMode": {
    "PresetGameMode": "Normal"
  },
  "Difficulty": {
    "DifficultyPreset": {
      "DifficultyPresetType": "Normal"
    },
    "PersistentBaseDifficultyFlags": 0
  },
  "PlatformToken": "",
  "IsReported": false,
  "IsFeatured": false,
  "AutoPowerSetting": {
    "BaseAutoPowerSetting": "UseDefault"
  }
}

4. 基地のバックアップと復元

4-1. バックアップ

  • Save EditorのJSONエディターからバックアップしたい基地を開き( PlayerStateData -> PersistentPlayerBases -> [整数] )、右側の入力欄の内容を全て選択( Ctrl+A )してコードエディターにコピペし、任意のファイル名で拡張子を .json として保存する
    • 基地の特定は基地名を参照のこと
    • バックアップ自体はこれで完了
  • その後は――
    • 単純に特定の時点のバックアップを取るだけで基地はそのまま残す場合はなにもしなくてよい
    • 基地を削除する場合はゲーム内で通常の手順で基地を削除する
    • 基地コンだけ残す場合や最小構成(基地コン込みでパーツ数8点)にしてアップロードする場合もゲーム内で実施する
      • 基地JSONを編集して素早く基地コンだけにする方法を4-3で後述する

4-2. 復元

  • 復元先のセーブデータで復元先となる基地を用意する
    • 新設するか、既存の基地を一つ選ぶ
    • データは全て上書きされるため基地はどこにあってもよい
  • Save Editor上で復元先の基地を特定し、復元先の基地の基地JSONをコードエディターにコピペする
    • 基地の特定は基地名を参照のこと
  • 復元元の基地JSONをコードエディターで開き、復元先の基地JSONの以下の項目を復元元の基地JSONの内容で上書きする
    • GalacticAddress : 銀河・星系・惑星(必須)
    • Position : 座標(必須)
    • Forward : 基地の傾き補正値(必須)
    • Objects : 基地パーツ(必須)
      • 同じ基地のパーツだけ復元する場合はこれだけでよい
    • Name : 基地名(任意)
  • 編集した復元先の基地JSONをSave Editor上で復元先の基地に上書きしてセーブデータを更新する
  • 更新された復元先のセーブデータをゲーム内で開き、反映されているか確認する
    • 必要であれば基地画像を撮影する
  • 復元先のセーブデータは復元元と同一である必要はない
    • 同一プレイヤーの別のセーブデータでも、別のプレイヤーでも問題ない
    • 「アップロード済の基地をバックアップして削除→別のセーブデータで復元してアップロード」という手順でアップロード済の基地を別のセーブデータでアップロードし直すこともできる

4-3.【Tips】基地コン以外を削除する

  • 基地JSONの Objects に格納されている基地パーツのうち "ObjectID": "^BASE_FLAG" が基地コンに該当する
    • つまり BASE_FLAG 以外のパーツを削除すれば簡単に基地コンだけにできる
  • 具体的には Objects の内容は以下のようになる
    • 基地コンのパラメータは変更しないこと
{
  // 前略
  "Objects": [
    {
      "Timestamp": 1700000000,
      "ObjectID": "^BASE_FLAG",
      "UserData": 0,
      "Position": [
        12.3,
        45.6,
        78.9
      ],
      "Up": [
        0.123,
        0.456,
        0.789
      ],
      "At": [
        0.123,
        0.456,
        0.789
      ],
      "Message": ""
    } // 最後の基地パーツの末尾にはカンマをつけない
  ],
  // 後略
}

4-4. 【Tips】パーツ数を確認する

  • 自明だが基地JSONの Objects に含まれるパーツの数が基地の総パーツ数である
  • 内蔵JSONエディターの左のツリーで PlayerStateData -> PersistentPlayerBases -> [整数] -> Objects を展開すると下に整数の連番で個々のパーツが並ぶ
  • 「連番の末尾の数字+1」がその時点の総パーツ数となる

5. 基地の移転

5-1. 基地の水平に関する基礎知識

  • 前提1: 既知の通り、建築モードで基地パーツを地形に置いた際、パーツは自動で水平(壁等は垂直)になる
    • 見かけ上自然な水平が出ている
    • 以下この水平が示す面を便宜上「水平面」と呼称する
    • プレイヤーキャラクターの傾きやピン(分析レンズの誘導マーカー)等も同じ方法で算出されていると思われる
  • 前提2: 基地を作成する際に内部的に基地自体の水平を出すための処理が行われ、基地データに補正値(基地JSONの Forward )が記録されるが、この処理は前提1とは異なる方法で行われていると思われる
    • こちらは見かけ上必ずしも水平になるとは限らない
    • 以下基地データに基づいた水平面を便宜上「基準面」と呼称する
    • 検証待ちだが、星の大きさが影響している可能性がある
  • 前提3: 基地データにおいて基地パーツの傾きは「基準面からの相対値」で記録されている
    • 位置は「基準面の原点からの相対値」、向きは「基地作成時の基地コンの向きからの相対値」となる
  • これら前提により、基地データに記録されている基地パーツの傾きの値は、ゲーム内での見かけが同じでも基地毎に微妙に異なる
    • よって、 異なる場所の基地間で基地パーツのデータを移植すると水平が狂うことがある

5-2. 水平の差異を考慮しない移転

  • 5-1で述べた水平の差異を考慮しないのであれば、4-2の「復元」の内容を一部変更するだけでよい
  • 復元に対する変更点は以下の通り
    • 移転先の基地を作成する際に、基地コン初期設置時の位置と向きに対して建築物が相対配置される仕様を前提に、基地コンの位置と向きを調整して設置する
      • 移転元の基地で基地コンを初期配置から動かしている場合は注意が必要
      • 何度でも再試行できるため最初から厳密に合わせる必要はない、水平がどの程度狂うかも一度設置しないとわからない
    • 移転元の基地JSONをコードエディターで開き、移転先の基地JSONの以下の項目を移転元の基地JSONの内容で上書きする
      • Objects : 基地パーツ(必須)
      • Name : 基地名(任意)
  • 移転先の基地の場所は編集せず、基地パーツのデータのみ移転元のものに差し替える形になる
  • 水平の簡易的な確認手段として、建築物の近くにピンを打って光の柱と建築物の垂直部分のズレを見る方法がある

5-3. 水平の補正を伴う移転

  • 移転により許容範囲を超えて水平が狂う場合、3DモデリングソフトウェアであるBlenderと、BlenderでNMSの基地を編集できるようにする No Mans Sky Base Builder アドオンを使用することで、基地パーツの相互の位置関係を保ったまま基地全体の傾きを補正することができる
    • そもそも基地を一からBlender上で作成できる仕組みのため、位置の微調整や不要パーツの削除なども当然可能
  • 基地JSONの内容としては Objects の中身をBase Builderで編集することになる
  • Base Builderの導入方法については次章で解説する

6. Base Builder

BlenderでNMSの基地データの読み書きと基地パーツの編集を可能にするBlenderアドオン。

以下Blender上の操作説明については特記なき場合マウスカーソルがBlenderの3Dビュー(3Dモデルが表示されているエリア)にある状態を前提とする。

6-1. セットアップ

  • Blender
    • 最新版はV4だがBaseBuilderの更新時期に合わせてV3を使用
    • 公式のLTSページ のDownloadセクションから Windows – Installer をダウンロードしてインストール
  • No Mans Sky Base Builder
  • bpy_externall
    • Blenderアドオン(Base Builderの動作に必要)
    • 公式GitHub の緑色の <> Code ボタンから Download ZIP でZIPファイルをダウンロード
  • Python

Blenderアドオンの有効化

  1. メインウィンドウのメニューバーから「編集」→「プリファレンス」
  2. プリファレンスダイアログの左のメニューから「アドオン」
  3. 右上の「インストール」ボタンを押し、 bpy_externall のZIPファイルを選択して「アドオンをインストール」
  4. リストに表示された テキストエディター: Externall のチェックボックスをチェック
  5. 右上の「インストール」ボタンを押し、 No Mans Sky Base Builder のZIPファイルを選択して「アドオンをインストール」
  6. リストに表示された Game Engine: No Mans Sky Base Builder のチェックボックスをチェック

6-2. Base BuilderのUI

  • 3Dビュー左上のドロップダウンメニューが「オブジェクトモード」になっていることを確認する
    • Tab を押すと「オブジェクトモード」と「編集モード」が切り替わる
  • N を押すと出し入れできるサイドバーのタブにある No Mans Sky を選択するとBase BuilderのUIが表示される

基地データの入出力

  • 入出力は基地JSONで行う
  • Base Builderの入出力に関連するボタンは以下のように動作する
    • 保存: 現在の編集内容をファイルに保存する
    • 読み込み: ファイルから読み込む
    • Import NMS: クリップボードから読み込む
    • Export NMS: 現在の編集内容をクリップボードにコピーする
  • 基地が複雑だと読み込みには数十秒~スペックによっては分単位で時間がかかる
    • フリーズしているように見えるが処理は行われている
  • 読み込み・Importは現在の内容をクリアする

6-3. 使い方に関するTip

Blenderの使用方法については優れたコンテンツが大量に存在するため割愛する。
ここではBase Builder特有のTipsを挙げる。

  • 建築モードでパレットから基地コンを選択し、回転させずに地面に置いた状態で、各方向がそれぞれBlender上の「前: +Y」「後: -Y」「右: +X」「左: -X」「上: +Z」「下: -Z」に対応する
  • 5-1で解説した「基準面」が「XY面」に相当する
  • 筆者が実際に実施した移設の手順は以下の通り
    • 移設元の基地から不要なパーツを削除する(ゲーム内でも可)
    • 原点(=移転先基地作成時の基地コン設置地点)を決めて位置(X軸Y軸)と高さ(Z軸)が合うように基地を移動する
    • 基地の前後と左右を決めてY軸とX軸に合うように基地を回転させる
      • 移転先基地作成時の基地コンの向きはこれに合わせる
    • Blender上でXY面に対して基地が水平になるように修正する
      • 具体的には床などの水平になる面を選択し、トランスフォームの回転の値を打ち消してゼロにする
      • この手順は省略してもよい
    • 移転先の基地を作成する
    • 移転先の基地JSONの Objects の内容をBase Builderの出力内容で上書きしてセーブデータを更新する
      • 更新したセーブデータを読み込み、地形に設置した床や壁と比較して前後および左右の傾きを確認する
        • 基地側に比較に使用できる水平ないし垂直の辺がなければ連続した床や壁を仮設置する
        • または水平出し専用の基地データで水平を出してから移設したい基地データに入れ替えてもよい
        • 初回の大雑把な確認にはピンの光柱が便利
        • 比較に使用する辺の長さを長くすれば精度は好きなだけ上げられる
      • Blenderに戻って傾きを打ち消すように回転させる
        • 前後の傾きはX軸の回転、左右の傾きはY軸の回転
      • 水平の補正が終わるまでこの手順を繰り返す
    • 満足の行く水平が出たら移設完了
  • 埋まったパーツがないかどうかの確認にも使用できる