オープンワールドクラフトサバイバルアクションゲーム『Craftopia』のWikiです。seesaaアカウントIDをお持ちの方であればどなたでも編集可能です。メンバーと非メンバーに差は設けていません。ここではメンバーの募集をしていませんが、どうしてもという方はトップページの「このWikiについて」を確認下さい。


概要

Mod Hubの公式対応のため、Modのアップロードが公式にサポートされました。
ここでは、そこにModをアップロードするためのMod開発の基礎の基礎を説明します。
より踏み込んだ内容についてはCraftopia modderwiki*1など関連サイトを確認ください。

ここでは、ある程度のコンピューターとC#に関する知識があるものとして説明しています。

注:ここに掲載されたModは20210623の安定版で動作確認をしています。今後データ構造が変わることにより動作しなくなる可能性があります。

Mod関連ファイルのフォルダ構造の理解

MOD関係のファイルは以下のフォルダ構造のようになっています(余計なファイルやフォルダは省略)
以下、下記のファイルについての場所の説明は省略します。

StepZero:開発環境の準備

クラフトピアのModの開発を行うためには以下の準備が必要です。
  1. ソースの確認手段の準備
  2. C#の開発環境の用意
  3. CraftopiaModLoader(BepInEx)の設定変更
  4. CraftopiaModUploaderの準備

ソースの確認手段の準備

クラフトピアの本体プログラムに追加・改変を行うModを開発するわけですから、クラフトピアの本体がどのように動いているかを確認する必要があります。
クラフトピアはあえてMod開発がしやすいような仕組みを用いて開発されています。(プログラムの解析や複製が行われやすいというリスクを背負ってくれています)

クラフトピアのdllを解読するためのソフトがまず必要になります。逆コンパイラを準備しましょう。
有名なものでは「ILSpy」や「dnSpy」がよく使われています。

ここでは「dnSpy」を用いてソースを覗いてみましょう。
  1. まずdnSpyの配布ページ*2に移動し、最新版を取得します。
  2. 適当なフォルダに展開し、dnSpy.exeを実行します。
  3. 「File⇒Open」を選択し、クラフトピアのコアdllである「AD_OverCraft.dll*3」を開きます。
  4. クラフトピアのプログラムはたいてい名前空間「Oc」もしくは「Oc.〜〜〜」の下にあるので、望む処理のものを探して確認します。
    ソースはC#で記述されています。
    Ctrl+Shift+Kで行う検索(Search)や、右クリックした変数がどこで使われているかの確認機能(Analyzer)を使って動作を確認していくとよいでしょう。

C#の開発環境の用意

Modはクラフトピア本体やUnityに合わせ、プログラム言語「C#」で開発を行います。
総合開発環境であるマイクロソフトの「Visual Studio」が適当でしょう。C#のビルドが可能であれば他のものでも構いません。
有償版もありますが、無償版でも十分開発が行えます。ただし、マイクロソフトへのアカウント登録が必要です。
マイクロソフトのVisualStudioのページ*4からVisual Studio Communityをダウンロードしてインストールしてください。

「参照の追加」などこの後行うこともありますが、それは後述します。

CraftopiaModLoader(BepInEx)の設定変更

まず、Modを使用するとき同様に、ワークショップからCraftopia Mod Loaderをサブスクライブします。
特に設定をしないで使用するとクラフトピア実行時には何もおこりませんが、
それではエラーが出た時に困りますし、ゲーム中にシステムメッセージ系に干渉しないとプログラムの結果を画面に出すことができません。
下準備として、ログを出せる環境を準備します。
※クラフトピアのアップデートをした際に設定が上書きされることがあります。設定したBepInEx.cfgのバックアップを取っておくことをおススメします。

BepInEx.cfgをメモ帳などで開き、以下のように設定を変更します
  • [Logging]の項目の「UnityLogListening」をtrue
  • [Logging.Console]の項目の「Enabled」をtrue
その他はデフォルトで構いませんが、必要に応じて変更してください。

クラフトピアの本体を起動したときに、もう1つログなどが表示されているウインドウが表示されれば成功です。
このウインドウを閉じるとクラフトピアが強制終了します(終了時のセーブも行わない)。

CraftopiaModUploaderの準備

  1. クラフトピアのSteamWorkshopを開きます。
  2. 画面上部のワークショップの説明画面にある「詳細情報」ボタンを押します。
  3. GitHubに移動しますので、右上の「Code」(緑のボタン)から「Download ZIP」を選択し、ファイルを適当な場所にダウンロードします。
  4. ダウンロードしたファイルを適当な場所に解凍します(Craftopiaのゲームフォルダか、ModLoader(BepInEx)のあるフォルダが適当だと思います)
  5. 解凍したフォルダの「\Craftopia_OfficialSteamModTools-master\Mod_UploaderBinary\Version***\」(***は一番数字が新しいもの)にある「Mod_Uploader.exe」が本体です。
    どこか使いやすい場所にショートカットでも作っておきましょう。

FirstStep:とりあえずHelloWorld

Modを作成するにあたり、まず最小構成ものから作成しましょう。
Unityのログに「Hello world」と表示するだけのModです。

VSプロジェクトの作成

まず、VisualStudioでプロジェクトを新規作成します。
作成するプロジェクトの種類はC#の「クラスライブラリ (.net Framework)」です。名前と作成場所はお好みで。
ここではプロジェクト名「Example」として進めます。各自の環境に合わせて読み替えてください。

参照の追加

次に必要なファイルの参照設定を追加します。ソリューションエクスプローラーの「参照」の部分で右クリックで出てくる「参照の追加」をクリックします。
出てきたウインドウの右下の「参照」をクリックし、以下のファイルを選択、チェックボックスにチェックを入れます。
それぞれの場所は「Mod関連ファイルのフォルダ構造の理解」を参照してください。
このほかにも作成中のModで必要なものが出たらプロジェクトに追加をしていってください。
  • BepInEx.dll
  • 0Harmony.dll
  • AD__Overcraft.dll
  • UnityEngine.dll
  • UnityEngine.CoreMolude.dll

クラスの記述

Modの中身の記述を始めます。主なやることとしては以下のものがあります。
  1. using ステートメントの設定
  2. BepInExの設定と割り込み位置の指定
  3. 処理の記述

書き込む処理の全体としては次のようになります。

using System;
(他のSystem系は省略)
using BepInEx;     //これを追加
 
namespace Example{
  [BepInPlugin("ModName", "DisplayModName", "1.0")]
  //引数はそれぞれ、Modの名称、Modの表示名、バージョン表記
  //Modの名称が他のModと重複すると干渉するので、自分独自のユニークな名前を推奨。
 
  //基底クラス[BaseUnityPlugin]を実装すること。
  public class Class1:BaseUnityPlugin{
    public void Awake(){
      UnityEngine.Debug.Log("Hello, World!!");
    }
  }
}
これが終わったらビルドを行います。
正常に設定ができていればエラーもワーニングもないはずです。
出力ファイル(Example.dll)をコピーし(出力場所はソリューション構成によって異なる)、\BepInEx\pluginsの中に貼り付けます。
他のModと混ざらないよう、pluginsの中に自作Mod用のフォルダを作り、そこにdllやreadme.txtなどを置くといいでしょう。

公開を行う前・公開しないModは\BepInEx\pluginsの中に置くことで動作します。(ダウンロードしてきたModも同様)
まずは公開する前に、自分のローカルで十分な動作確認とデバッグを行いましょう。

pluginsにdllを置いてクラフトピアを起動すると、ログウインドウに以下の表示が出てきます。うまく「Hello World」が表示されていれば成功です。
タイトル画面まで行くまでに結構なログが走るので、落ち着いてからスクロールバーで最初の方のログを確認しましょう。

ログ詳細の例(細部は変わる可能性あり)

うまくいかない場合

SecondStep:アイテム情報の取得

次にHarmonyを用いて、アイテム情報の取得を行うModを作成します。
先ほどのHelloWolrdを出力するModを改造して作りましょう。

アイテム情報を探す

まず、dnSpyを用いて、アイテム情報が入った変数を探し出します。"Item"という名前をヒントにSearchやAnalyzerを使って探しましょう。
経路は省略しますが、「Oc.Item.OcItemDataMng」クラスで定義されている「validItemDataList」(ItemData型)がそれです。
初期化が同クラスのOnUnityAwakeメソッドの冒頭で行われているのを確認してください。

割り込む場所を決める

取得したい変数が判ったら、この処理に割り込んで値を取得します。
割り込みにはHarmonyを使用します。Harmonyは簡単に言うとパッチを作成するためのライブラリ群です。詳細はここ*5を確認ください(英語)。
Harmonyは特定のメソッドの前(Prefix)、もしくは後ろ(Postfix)に処理を追加できます
値を取得するには初期化の後に行う必要があるため、「OnUnityAwakeの後」「初期化後にOnUnityAwakeで必ず実行されるメソッドの前か後」に割り込ませます。
OnUnityAwake内のメソッドに割り込む場合、思っていた箇所以外で使用されていないかをAnalyzerで確認しておきましょう。
今回は、初期化の直後にある「Oc.Item.OcItemDataMng.SetUpCraftableItems()」メソッドに割り込みます。

Modを改造する

まず、前回のもの(Class1)でusingステートメントに「HarmonyLib」を追加してください。

次にAwake()メソッドを次のように書き換えます。(太文字部が変更する部分です)

次にソリューションエクスプローラーでソリューションの下にあるExampleを右クリックをし、「追加⇒新しい項目」を選択します。
適当なクラス名を決めたら(ここではClass2とします)、リストの中から「クラス」を選択してください。

新しく作ったクラスに次のように書き込みます。

using System;
(他のSystem系は省略)
using HarmonyLib;    //これを追加。ここではBepInExは不要
using Oc.Item;    //割り込むクラスの名前空間を指定、このほかにも必要に応じてOcなどを追加する。
 
namespace Example{
   [HarmonyPatch(typeof(OcItemDataMng), "SetupCraftableItems")]
   //割り込むクラスのタイプと割り込むメソッドを指定
   //クラスの前に指定すること
 
   internal class Class2{
      public static bool Prefix(ItemData[] ___validItemDataList){
      //引数はプライベートメンバーの参照をしている。参照は「アンダーバー×3 + 変数名」

         foreach(ItemData item in ___validItemDataList){
            UnityEngine.Debug.Log($"ItemName {item.Id}:{item.DisplayName}");
         }
         return true;   //Prefixの返し値をfalseにすると、元のメソッド(この場合SetupCraftableItems)が実行されなくなる。
                     //言い換えると「Prefixで返し値をfalseにすると、Prefixが元メソッドを完全に上書きする」
                     //元のメソッドを利用する他のModがあると正常動作しなくなることがあるため、よほどでなければtrue推奨
      }
   }
}

割り込み場所について

Prefix,Postfixで使用できる引数

HelloWorldと同じように、ビルドしてModを更新しましょう。
クラフトピアを立ち上げた時に、ログにアイテムの一覧が出れば成功です。(タイトル画面が表示される前に出力されます。ログをさかのぼって確認してください。)

ThirdStep:アイテム情報の書き換え

次にアイテムの情報を書き換えるModに改造します。石のつるはし(ID=56)の価格(int型)を書き換えてみましょう。
AccessTools.FieldRefAccessを用いてプライベートなメンバーを変更することができます。
引数は【AccessTools.FieldRefAccess<アクセスするインスタンスの型 , メンバーの型>(アクセスするインスタンス , メンバー名)】 です

書き換える内容についてはdnSpyであらかじめ確認をしておいてください。今回のものはItemData型のメンバーとして登録されています。
当たり前ですがメンバーの型やメンバー名を間違えると動きません。(インスタンスに関しても同様)(VS上ではエラーが出ず、動かしてみるまで判らない)

先ほどのクラス(Class2)のPrefixを次のように書き換えます。
今回はPostfixを使ってみましょう。SetupCraftableItemsメソッドは大したことをしてないので前でも後ろでも結果は変わりません。
public static void Postfix(){
//今回validItemDataListは使ってないので引数不要。
//ただし、GetItemData_OrNull()内部で使用してるため、初期化後に実行する必要がある
 
   ItemData item = OcItemDataMng.Inst.GetItemData_OrNull(56);               //ID56のアイテム情報を取得
   ref int itemprice = ref AccessTools.FieldRefAccess<ItemData, int>(item, "price");  //価格を収納するメンバーpriceの場所を取得
   itemprice = 9999;
   return;
}
先ほどまでと同様、ビルドしてpluginsに配置、クラフトピアを起動し石のつるはしの価格を確認しましょう。
クラフト画面を確認し、価格が9999になっていれば成功です。
失敗の場合、ゲーム起動時のログに赤文字のエラーが出ていることがあります。

FinalStep:SteamWorkshopへのアップロード

最後にModのアップロード方法を紹介します。

アップロードする前の心構え

※以下は義務ではありませんが、できるだけ対応するようにお願いします。
  • アップロードするModは十分なデバッグを行い、最低でも自分の環境でエラーのないものを出すようにしてください。
  • アップロードしてそのまま放置せず、たまにコメントを確認してバグ報告があったら対応してあげてください。
  • 本体がバージョンアップされたら、自作Modの動作確認をもう一度行い、動かないようなら動くようにバージョンアップ対応してあげてください。
  • 止むをえずサポートを停止する場合、そのことを説明文などに書いてあげてください。
    (「更新停止」などと書いておく、もしくは動作確認のある最終バージョンを書いておく)

アップロードパックの準備

まず、アップロードする圧縮ファイルを作るための準備を行います。
適当な名前のフォルダを作成し、次のようなフォルダ構成を作ります。最低限必要なファイル以外は消しておきましょう(ショートカットなど)。
Modのdllは必ずpluginsかpatchersフォルダの下に置く必要があります。
\(Modを入れるフォルダ)---\plugins -+-  Mod本体dll
                          |
                         +- 設定ファイル や readme等                      

Readmeファイルの準備

できればModの動作や操作方法について記載された「Readme.txt」のような配布テキストを用意しておきましょう。

ポケットペア(公式)からMODの配布に関して、指定文章の記載が必要という指示があった場合*6は、該当の文章を配布テキストに記載します。
また、自身の免責に関する文章を書いておいてもいいかもしれません。(このModの動作による損害に関して一切の責任を負いません・・・のような)

ModUploaderの操作

※同じファイルを再度アップロードするとModや情報が更新されます。
※上書きアップロードを行う時には、アップロード先を示した「ModInfo.txt」がModPathの階層に必要です。
 無い場合は、自分のMODをサブスクライブし、該当のファイルを取得してください。
 また、英語版の説明文は再アップされる内容で上書きされます。あらかじめ保存しコピペできるようにしておきましょう。

ModUploaderはSteamへのログインが必要なため、まずSteamを立ち上げておいてください。
次に、用意しておいた「Mod_Uploader.exe」を起動します。

起動したらそれぞれ必要な項目を埋めていきます。
フォルダの読み込み機能はないため、フォルダ名は手入力が必要です。
エクスプローラーのココをクリックして、フルパスをコピーし、該当部にペーストしましょう。

項目説明
ModPathMODの入っているパスを指定します。Modの入ったPluginsフォルダの一つ上のフォルダを指定します。
上のアップロード構成図の「modを入れるフォルダ」にあたるものを指定してください
DLLを直接指定しないこと
指定フォルダ以下の余計なファイル・ショートカットは削除しておいてください(アップロードされてしまいます)
ModNameワークショップに表示されるModの名前です
Steam言語設定の「英語」に収納されるため英名をおススメします。
アップロード後にも変更可能です
ModDetailsワークショップで選択した時に表示されるModの説明です。
Steam言語設定の「英語」に収納されるため、機械翻訳でもよいのでできれば英語での記述をおススメします。
アップロード後にも変更可能です
ImagePathワークショップでのサムネイルを設定できます。設定すると下の四角にサムネイルが表示されます。
このサムネイルは大きさ固定のため大きい画像では大きく崩れますが、アップロード後のものは普通に表示されます
アップロード後に追加・変更が可能です。

必要な項目の記入が終わったら、一番下にある「Upload」ボタンを押します。
しばらくすると一番下に「Upload Success」と出るのでこれでアップロードは完了です。

ただし、アップロード直後は「非公開」の状態ですので、設定が必要です。
次の項目で調整をしていきます。

SteamWorkshopでの編集

最後に、アップロードされたファイルの確認と詳細設定を行います。
まず、Steamのクラフトピアのワークショップを開き、右側にある「あなたのワークショップファイル」をクリックします。
そうすると、先ほど投稿したModが一覧にあるはずです。
投稿したModを開くと、ダウンロードする画面と同じような画面が出てきます。

主に右側のものを操作し、設定を行います。使うのは以下のものです。
タイトル&説明の編集
先ほどアップロードされた説明は「言語:英語」に収納されています。(説明が英語のみの場合、あらゆる言語でここにあるタイトルと説明が表示されます)
言語をクリックすることで他言語(日本語を含む)の環境で見ている場合に個別に設定したタイトルや説明を表示することができるようになります。
アップローダーで英語で記入した場合は「言語:日本語」に変更し、日本語でのタイトルと説明を記入しましょう。
画像&動画の編集と追加
説明画面に表示される画像や動画を追加したり変更することができます。
アップローダーでは1個しか画像を添付できませんでしたが、ここで追加の画像やユーチューブに投稿された動画を添付することができます。
削除
アップロードしたModを削除します。復旧はできないので、その場合は再度アップロードする必要があります。
必要アイテムの追加&削除
アップロードしたModに必要な前提Modがあればここで指定します。
ModUploaderを使用していれば自動的に「Craftopia ModLoader(BepInEx)」がついていますが、これに追加できます。
サブスクライブしたユーザーが指定したModをサブスクライブしていない時に警告を発することができます。
公開設定変更
ここを「公開」に設定することで、アップロードしたModをSteamユーザー全体に公開することができます。
フレンドのみ公開の設定とすることも可能です。

これで一通りの流れは終了です。
あとはdnSpyを眺めてコードを理解しながら、思うように改造を進めていきましょう。

参考資料:Harmonyドキュメント、Craftopia modderwiki:初心者向けページ

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

※現在 ユーザーID保持者 のみがコメント投稿可能な設定になっています。

Wiki内検索

Menu

掲示板

編集にはIDが必要です