このドキュメントは,simutrans world monitorにコマンドやモニタリングタスクを追加する方法を説明するものです.
いじるのはSquirrelコードだけであり,Pythonコードはいじりません.
新しいコマンドを追加するには
- libs下にnutファイルを作成し,
exec()
関数を持つclassを実装 - 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
を介してやりとりしています。
モニタリングタスクの場合は,
monitoring_base_cmd
を継承したクラスを作成し,- 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
の例を参照してください。
libs/common.nut
をincludeすると,
- map(squirrel standard libraryのarray.map()で生じる諸問題 に対処しています)
- filter(同上)
- プレイヤー番号からプレイヤーobjectを取得
- プレイヤーobject一覧を取得
などができるようになります.