Skip to content

Latest commit

 

History

History
111 lines (74 loc) · 5.18 KB

modification_guide.md

File metadata and controls

111 lines (74 loc) · 5.18 KB

機能追加方法

このドキュメントは,simutrans world monitorにコマンドやモニタリングタスクを追加する方法を説明するものです.

いじるのはSquirrelコードだけであり,Pythonコードはいじりません.

情報源

コマンドを追加する

新しいコマンドを追加するには

  1. libs下にnutファイルを作成し,exec() 関数を持つclassを実装
  2. config.nutで,libs下のnutファイルをincludeし,commands ディクショナリにインスタンスを登録

の手順を踏みます.例として,文字列をそのまま返す「復唱」コマンドを作ってみましょう.

discordで?復唱,こんにちは と入力したときに,復唱!こんにちは と返ってくるようにします.

libs/get_echo.nut を実装ファイルとして作成します.中身はこうなるでしょう.

// メッセージ定義.出力文字列はこのようにロジックから分離しましょう.
local text_echo = "復唱!%s"

include("libs/embed_out")
class get_echo_cmd {
  function exec(str) {
    // strは,「復唱,こんにちは」という文字列が渡される.discordの文字列から冒頭の?を抜いた形.
    local params = split(str,",") // カンマで区切って配列にする
    embed_normal(format(text_echo, params[1])) // 通常メッセージとして文字列を書き込む
  }
}

※このコードでは,?復唱 とだけ投げられたときにparams[1] が存在せずエラーになるので,実際に運用する際は対策が必要です.

libs/get_echo.nut を作成したら,config.nut で以下のように追記します.

include("libs/get_echo") // libs/get_echo.nutをincludeする
commands["復唱"] <- get_echo_cmd() // コマンド名と実行インスタンスを紐付ける

これで,get_echo_cmd クラスのexec() 関数が呼ばれるようになりました.

メッセージの送信方法

Simutrans World Monitorでは、2つのメッセージ送信方法を用意しています。

  • プレーンテキスト ... file_io/out.txt に文字列を保存すると、内容がプレーンテキストとして送信されます。
  • Embedメッセージ ... libs/embed_out.nut に定義された関数群を用いると、内容をEmbedメッセージとして送信できます。内部的にはfile_io/out_embed.json を介してやりとりしています。

モニタリングタスクを追加する

モニタリングタスクの場合は,

  1. monitoring_base_cmd を継承したクラスを作成し,
  2. config.nutで,libs下のnutファイルをincludeし,monitored 配列にインスタンスを追加

の手順を踏みます.例えば,デッドロックを検知するlibs/get_stucked.nut は下のようになっています.

include("libs/monitoring_base")

// モニタリングタスクのclass名プレフィックスは'chk'がおすすめ.
class chk_stucked_cmd extends monitoring_base_cmd {
  stucked_lines = []
  warning_ratio = 0.5
  
  constructor(m, wr) {
    monthly_check_time = m // do_check()を行う間隔を,1ヶ月あたりの回数で指定
    warning_ratio = wr // デッドロック検出閾値
  }
  
  function do_check() {
    // 実際にチェックを行い,必要に応じてdiscordに通知する
  	// 中身省略
  }
}

モニタリングタスクの場合は,コンストラクタでmonthly_check_time の指定が必要です.chk_stucked_cmd の場合は,インスタンス作成時にチェック頻度と検知閾値wr を設定します.

do_check() 内でdiscordにメッセージを送るには,コマンドを実装するときと同じように,出力用ファイルオブジェクトを取得し,そこに文字列を書き込みます.

最後に,config.nut で以下のように追記します.

include("libs/get_stucked") // libs/get_stucked.nutをincludeする
monitored.append(chk_stucked_cmd(8, 0.8)) // パラメータを指定しながら登録

状態の外部保存について

ゲームを読み込むとScriptを実行するVMがリセットされるため、NSの運用などにおいて外部に状態を保存することが必要な場合があります。monitoring_state() クラスを使うことで状態を永続化することができます。使い方はlibs/chk_count.nut の例を参照してください。

common.nut について

libs/common.nut をincludeすると,

  • map(squirrel standard libraryのarray.map()で生じる諸問題 に対処しています)
  • filter(同上)
  • プレイヤー番号からプレイヤーobjectを取得
  • プレイヤーobject一覧を取得

などができるようになります.