C++ ときどき ごはん、わりとてぃーぶれいく☆

USAGI.NETWORKのなかのひとのブログ。主にC++。

CITIES: SKYLINES の MOD 開発環境の整え方、デバッグ出力の出し方

(note: Windows 10, Visual Studio 2017, STEAM 環境向け)

① MOD 開発環境の整え方

理屈はめんどくさいので解説しないよー😃

  1. CITIES: SKYLINES を STEAM で導入
  2. Visual Studio Installer で Workloads タブの Game development with Unity を導入
  3. Visual Studio で MOD 開発の Class Library プロジェクトを作る。
    • Target Platform = .net Framework 3.5
  4. CITIES: SKYLINES アプリに同梱されている mono.dll をデバッガブルなビルドへ置き換える
  5. Windows環境変数MONO_DEBUGGER_AGENT = transport=dt_socket,address=127.0.0.1:56000,defer=y を追加
  6. Visual Studio の MOD 開発プロジェクトに CITIES: SKYLINES の DLL 参照を追加
    • DLLの場所: C:\Program Files (x86)\Steam\steamapps\common\Cities_Skylines\Cities_Data\Managed
    • MOD に必要最小限のDLL: ICities.dll
  7. 適当なソースへ ICities インターフェースを実装したクラスを定義†してビルド
  8. ビルドした MOD の DLL を %LOCALAPPDATA%\Colossal Order\Cities_Skylines\Addons\Mods\ 以下へ配置
    • \Mods\ore_ore_mod_name\ore_ore_mod.dll のようにディレクトリーを切って放り込んでもよい
  9. STEAM クライアントが既に動作していれば終了させておく(重要: デバッガーが挿さらない場合は忘れている可能性あり)
  10. CITIES: SKYLINES を起動し、 Content Manager の MOD に↑で放り込んだMODが列挙される事を確認
  11. Visual Studio のメニューから Debug 👉 Attach Unity Debugger 👉 Input IP 👉 127.0.0.1:56000 でデバッガーの接続を確認
  12. SKYLINES WIKI - Modding API や CITIES: SKYLINES の DLL をオブジェクトブラウザーで眺めるなどしてお好みの MOD を開発する
    • ビルドのポスト処理で MOD の DLL のコピーを自動化するとかは必要に応じて好きにしてください・w・

†適当なソース例↓

using ICities;

namespace usagi.CitiesSkylines.Example1
{
  public class Example1: IUserMod
  {
    public string Name => "うさぎさんえぐざんぽー1号";
    public string Description => "ヒャッハー!えぐざんぽーだぜ!!";
  }
}

f:id:USAGI-WRP:20190130163624p:plain

f:id:USAGI-WRP:20190130174955p:plain

デバッグ出力の出し方

  1. 参照に追加
    • UnityEngine.dll, Assembly-CSharp.dll, ColossalManaged.dll
  2. デバッグ出力メソッドを叩く
    • Debug.Log ( UnityEngine ) // C:\Program Files (x86)\Steam\steamapps\common\Cities_Skylines\Cities_Data\output_log.txt へ出力される
    • DebugOutputPanel.AddMessage ( Assembly-CSharp, ColossalManaged ) // CITIES: SKYLINES ゲーム中の F7 で表示のデバッグ出力ゲーム内ウィンドウに出力される

実装例:

using ColossalFramework.Plugins;
using ICities;
using UnityEngine;

namespace usagi.CitiesSkylines.Example2
{
  public class Example2: IUserMod, ILoadingExtension
  {
    public string Name => "うさぎさんえぐざんぽー2号";
    public string Description => "見せてもらおうか、CITIES: SKYLINES の MOD のデバッグ出力とやらを!";

    void DebugMessage( string m )
    {
      Debug.Log( m );
      DebugOutputPanel.AddMessage( PluginManager.MessageType.Message, m );
    }    

    public void OnCreated( ILoading loading )
    { DebugMessage( $"UCSE2 てすてす OnCreated; loading={loading}" ); }

    public void OnLevelLoaded( LoadMode mode )
    { DebugMessage( $"UCSE2 てすてす OnLevelLoaded; mode={mode}" ); }

    public void OnLevelUnloading()
    { DebugMessage( "UCSE2 てすてす OnLevelUnloading" ); }

    public void OnReleased()
    { DebugMessage( "UCSE2 てすてす OnReleased" ); }
  }
}

他のログと混ざるので、ログから目grepしやすいように適当にユニークな出力文字列を入れておくとよい。

↓ゲーム中にF7(キーバインドを変更していなければ)で出るやつ

f:id:USAGI-WRP:20190131013641p:plain

参考

  1. Cities:Skylines Modding’s documentation — Cities:Skylines Modding 0.0.1 documentation
  2. https://skylines.paradoxwikis.com/Debugging_Mods