Skip to content

CLI リファレンス、別のプログラムから Mercy SF を動かす ​

mercy-cli には非対話モードがあります。引数を入れると、JSON オブジェクトが 1 つ出 てきます。ダッシュボード、監視プロセス、スクリプトのためのものです。

このページが約束です。 以下のコマンドと項目名は、予告なく変わることはありませ ん。CLI のそれ以外、メニュー、その文言、出力の体裁は、いつでも変わってよいことにな っているので、そこに依存して作らないでください。

引数なしで実行すれば、対話メニューがこれまでどおり立ち上がります。

すべての応答は "api" を持ちます。今日は 1 です。項目を足してもこれは変わらず、 自分の知っている項目だけを読む呼び出し側は影響を受けません。項目が消えたり意味が変 わったときに上がるので、自分が想定していなかった形に対しては動かない、と決められま す。


ログイン ​

S&F のシングルサインオン経由で作られたアカウントには、追加で何も要りません。ある サーバーに属していて、シングルサインオンに一度も属さなかったアカウントは、その仕組 みから見れば存在せず、--server が必要です。

bash
mercy-cli --status --user <account> --server https://f1.sfgame.net/

--server は以下のすべてのコマンドで使えます。

出力 ​

--start を除くすべてのコマンドは JSON だけを出力するので、--json はすでに既定 であり、渡しても何も変わりません。既定に頼るより明示したい呼び出し側のため、そして そうしなければ人間向けのログを書く --start のために存在します。


アプリケーションが描くすべての画面 ​

bash
mercy-cli --views
mercy-cli --view <name> --user <account> --character <name>

--views は一覧を出力し、アカウントもパスワードも必要としません。--view はそのうちの一つを、一人のキャラクターについて答えます。

どの名前も、アプリケーションが画面を描くのに使うのと同じ関数につながります。 そこが要点です。二度目に計算した数はいつか別の数になり、同じインストールの 二つの画面が食い違います。

名前何に答えるか
account_overviewアカウント一覧でのこのキャラクターの行
achievements実績と、エンジンが次に狙うもの
analyticsこのキャラクターの記録された履歴
battle_history保存された戦闘、新しい順
blacksmith金属、アルカナ、今日の分解残り回数
combat_decision戦闘モジュールが最後に決めたことと理由
dungeons各ダンジョンの階層と進行
fight_calibrationこのキャラクターの学習済み戦闘モデル
gear各装備枠が鞄の中身に対して持つ価値
hellevatorヘレベーター: 階、体力、次の行動
legendary_dungeon伝説のダンジョンの画面、体力を含む
live_events開催中のイベントとその期間
scrapbook_cache偵察済みの相手が何人保存されているか
scrapbook_targets不足している装備のうち狩る価値があるもの
world_bossワールドボスとその店

応答は常に {"ok": true, "view": "<名前>", "data": …} です。五つはディスクから読み、ゲームに触れずに答えます。

読み取り ​

アカウントのキャラクター一覧 ​

bash
mercy-cli --characters --user <account>
json
{
  "ok": true,
  "characters": [
    { "character": "Hero", "server": "https://s1.sfgame.net/", "level": 345 },
    { "character": "Alt",  "server": "https://s42.sfgame.net/", "level": 88 }
  ]
}

1 回のログインでアカウントの全キャラクターを、サーバーをまたいで扱えます。そのキャ ラクターの状態を取得できなかった場合 level は null になりますが、項目自体は残り ます。存在することを知ることこそ、この呼び出しの目的だからです。

キャラクター 1 体の状態を読む ​

bash
mercy-cli --status --user <account> --character <name>

アカウントにちょうど 1 体しかいない場合、--character は省けます。

json
{
  "ok": true,
  "character": "Hero",
  "server": "https://s1.sfgame.net/",
  "level": 345,
  "class": "DemonHunter",
  "race": "DarkElf",
  "experience": { "current": 740300000, "next_level": 769800000 },
  "silver": 725000000,
  "mushrooms": 8,
  "honor": 12043,
  "rank": 1800,
  "action": "CityGuard",
  "attributes": {
    "strength":     { "base": 4077, "bonus": 1200 },
    "dexterity":    { "base": 1000, "bonus": 300 },
    "intelligence": { "base": 900,  "bonus": 250 },
    "constitution": { "base": 3000, "bonus": 800 },
    "luck":         { "base": 700,  "bonus": 150 }
  },
  "equipment": [
    {
      "slot": "Weapon",
      "model_id": 55,
      "color": 1,
      "class": "DemonHunter",
      "epic": true,
      "legendary": false,
      "armor": 0,
      "min_damage": 900,
      "max_damage": 1400,
      "upgrades": 3,
      "attributes": { "strength": 420, "constitution": 210 },
      "rune": { "type": "FireDamage", "value": 60 },
      "enchantment": "SwordOfVengeance",
      "gem": { "type": "Strength", "value": 300 }
    }
  ],
  "arena": {
    "fights_for_xp": 7,
    "next_free_fight": "2026-08-06T12:04:11+02:00",
    "opponents": [50099, 34316, 13668]
  },
  "tavern": {
    "thirst_for_adventure_sec": 3600,
    "beer_drunk": 2,
    "mushroom_skip_allowed": true,
    "quests": [
      { "length_sec": 600, "silver": 120000, "experience": 45000,
        "location": "Wolves", "item": true }
    ]
  },
  "guild": {
    "name": "Blvck Clover",
    "rank": 12,
    "honor": 90000,
    "members": [
      { "name": "Hero", "level": 345, "last_online": "2026-08-06T09:12:00+02:00" }
    ]
  },
  "scrapbook_items": 1102
}

すべては 1 回の状態取得から得られるので、要求する区分もありませんし、少なく頼んで節 約できるものもありません。

キャラクターがギルドに属していない場合 guild は null です。スクラップブックを一 度も読んでいないうちは scrapbook_items は null です。空の装備枠は null として並 べるのではなく、省かれます。

アイテム名について。 プロトコルが運ぶのはモデル ID と枠であって表示名ではないの で、得られるのもそれです。同時にそれは絵の参照先でもあるので、ダッシュボードはデス クトップアプリとまったく同じ絵を描けます。ここで名前を作り出すのは、あなたが確かめ ようのない推測になってしまいます。

一定間隔で読み直す ​

bash
mercy-cli --status --user <account> --character <name> --watch 60

ログインは 1 回、あとはプロセスを止めるまで 60 秒ごとにオブジェクトが 1 つ。ループ でコマンドを再実行するのではなく、こちらを使ってください。実行のたびに新しいログイ ンが起こり、それは 1 つの数字を見張るのにいちばん高くつく方法で、サーバー側からいち ばん目立つ方法でもあります。下限は 30 秒です。失敗した回は出力され、ループは続きま す。最初のしゃっくりで諦める見張りは、何も起きていない見張りとまったく同じに見える からです。

次に誰と戦うか、そしてなぜか ​

bash
mercy-cli --plan --user <account> --character <name>
json
{
  "ok": true,
  "outcome": "planned",
  "reason": "Next: Someone — 3 scrapbook items, 72% odds",
  "candidates": [
    {
      "name": "Someone",
      "level": 340,
      "source": "pool",
      "missing_items": 3,
      "rank_gain": 12,
      "favourite": false,
      "win_chance": 0.72,
      "item_score": 300.0,
      "xp_score": 60.0,
      "rank_score": 25.0,
      "base": 385.0,
      "score": 277.2
    }
  ]
}

アプリが描くのと同じ判断です。候補をアイテム、日々の経験値、順位で採点し、勝率を掛 けます。outcome は planned、waiting、blocked、empty のいずれかで、 reason がどれなのかを 1 文で述べます。

これは戦闘もキノコも使いません。ただし候補を探して巡回はするので、要求という意味で は無料ではありません。詰めたループに入れないでください。

戦いの下稽古 ​

bash
mercy-cli --simulate --user <account> --character <name> --against <player>
json
{ "ok": true, "against": "Someone", "against_level": 340, "win_chance": 0.63, "iterations": 1000 }

計算です。相手が誰かを知るために照会が 1 回サーバーへ行きますが、戦い自体は決して送 られません。win_chance は決着した戦いに対する勝ち数なので、決着しきれなかったシミ ュレーションは、走らせた回数より少ない件数で報告します。

何を持っているか ​

bash
mercy-cli --inventory --user <account> --character <name>
json
{ "ok": true, "carried": 12, "backpack": [ { "slot_index": 0, "model_id": 55 } ] }

一覧は 1 つです。ゲームが 1 つしか持っていないからです。アイテムの形は --status と同じで、slot_index が加わります。

スクラップブック ​

bash
mercy-cli --scrapbook --user <account> --character <name>
json
{ "ok": true, "unlocked": true, "owned": 1102, "monsters": 214 }

スクラップブックが与えられるレベルより下では unlocked は false で、そこでは owned が null になります。これはエラーではありません。

記録された戦い ​

bash
mercy-cli --history --user <account> --character <name> --limit 50
json
{ "ok": true, "total": 4210, "returned": 50, "battles": [] }

新しいものから。これはボットを走らせたその環境が記録したものであって、サーバーか ら取ってくるものではありません。 ですから起動したばかりのプロセスには見せるものが なく、それは不具合ではありません。total は存在する件数、returned は --limit が残した件数です。


実行 ​

ボットを走らせる ​

bash
mercy-cli --start --user <account> --character <name>

プロセスを止めるまで走り、その間ログを書きます。ここでは --character が必須で す。一覧を出すことや状態を読むことは無害ですが、ボットを起動することはゲームを遊ぶ ことであり、キャラクターを間違えるのは取り消しのきくことではありません。

--all を使うと、代わりにアカウントの全キャラクターをこの 1 プロセスで走らせます。 キャラクターごとに 1 回ではなくアカウントで 1 回のログインになるので安く済み、キャ ラクター同士がセッションを無効化し合うのも防げます。

Ctrl-C(または SIGTERM)では、要求の途中で断ち切るのではなく、現在の手を終えてから プロセスが終了します。

文章ではなくイベント ​

bash
mercy-cli --start --user <account> --character <name> --events

1 行につき JSON オブジェクト 1 つ。監視プロセスは 1 行ずつ読めます。

json
{"at":"2026-08-06T17:22:04+02:00","api":1,"event":"arena_win","character":"Hero"}
{"at":"2026-08-06T17:22:31+02:00","api":1,"event":"quest_done","character":"Hero"}

event は started、stopping、stopped、arena_win、arena_loss、 dungeon_win、dungeon_loss、quest_done、scrapbook_win、scrapbook_loss、 scrapbook_items(count を伴います)のいずれかです。

この一覧は増えます。 知らないイベントはエラーではなく、無視するものとして扱って ください。名前が Rust の出力そのままではなく、はっきり書き出されているのは、まさに そのためです。

人間向けのログを読むのではなく、こちらを使ってください。あのログは人のために書かれ ていて、いつでも書き直されてよいものです。それを解析するということは、誰かが一文を 良くしたときにあなたの道具が壊れる、ということです。

待っているものを回収する ​

bash
mercy-cli --claim --user <account> --character <name>

カレンダー、日課、保留中の解放。--character は必須で、理由は --start と同じで す。

設定を読む、または変える ​

bash
mercy-cli --config --user <account> --character <name>
mercy-cli --config --user <account> --character <name> --set auto_arena=false
json
{ "ok": true, "settable": ["auto_arena"], "changed": [ { "key": "auto_arena", "from": true, "to": false } ] }

読み取りは設定全体を config の下に返します。そのブロックの中の項目名はこの約束 に含まれません。 含まれるのは settable に並ぶキーだけです。設定は 100 をゆうに 超える項目があり、リリースごとに増えます。それらすべてを約束するということは、設定 を二度と組み替えられないということです。

--set は true/false、on/off、yes/no、1/0 を受け取り、常に --character を要求し(スイッチは 1 体のキャラクターに属するもので、「唯一の 1 体」は読むぶんに は構わないが書くには誤った推測です)、繰り返し指定できます。値はそのあとディスクか ら読み戻され、書き込まれていなければ呼び出しは失敗します。起きていない変更を報告す ることは、唯一そこから立て直せない結果だからです。


運用 ​

これはどのビルドか ​

bash
mercy-cli --version
json
{ "ok": true, "version": "2.12.0", "api": 1 }

パスワードもネットワークも要らない唯一のコマンドです。監視プロセスは、話すための認 証情報を持つ前に、何と話しているのかを尋ねられなければなりません。

届いているか ​

bash
mercy-cli --health --user <account> --character <name>
json
{ "ok": true, "character": "Hero", "level": 345, "round_trip_ms": 412 }

ログインし、取得し、報告し、終了します。あえて小さくしてあります。キャラクターシー ト全体を返す死活確認は、それを解析したくなるものを招き、そうなれば確認そのものがま た 1 つのインターフェイスになってしまいます。


パスワード ​

--password のフラグは、意図的にありません。コマンドライン引数はその機械の他のあら ゆるプロセスから読めます。ps、/proc、タスクマネージャー。ですから、これを何人分 も動かすダッシュボードは、その箱にシェルを持つ誰にでも、全員のゲームのパスワードを 渡すことになります。

代わりに 2 つの道があります。

bash
MERCY_SF_PASSWORD='…' mercy-cli --status --user someone
bash
printf '%s' "$password" | mercy-cli --status --user someone --password-stdin

--password-stdin は標準入力の最初の 1 行を読みます。これなら秘密は環境変数にも残 りません。


終了コード ​

コード意味
0成功、および --help のとき
1実行して失敗した。理由は error にあり、ok は false
2呼び出しが誤り。未知のオプション、値の欠落、アクション指定なし。stderr に出ます

1 と 2 の違いは監視プロセスにとって意味があります。2 は毎回同じように失敗し、人の手 が要ります。1 は次の試行でうまくいくかもしれません。


エラー ​

失敗も JSON なので、1 つのパーサーで両方さばけます。

json
{ "ok": false, "error": "no character called 'Typo' on this account" }

ok はすべての応答にあります。何よりも先にそれを確かめてください。

よくある原因:

メッセージどうするか
--user is required--user がない(--version を除くすべてのアクション)
--start needs --character (or --all)対象を指定してください。推測はしません
this account has N characters — name one with --character複数あります。1 体を選んでください
no character called '…' on this account綴り違い。--characters が有効な名前を出します
no password: set MERCY_SF_PASSWORD or pass --password-stdinパスワードの 2 つの道のどちらかを選んでください
login failed: …認証情報かサーバーを確認。シングルサインオン外のアカウントには --server が必要です
'…' is not settable from here許可一覧にありません。--set なしの --config が settable を出します
'…' did not save — it still reads back unchanged変更が書き込まれていません。書き込み権限を確認してください

Raspberry Pi などの小型ボード ​

デスクトップ版は ARM 向けにはビルドしていません。ARM 上の WebKitGTK は、 まさに Pi の利用者がログイン直後のクラッシュを報告した場所であり、ここで誰も 検証できないビルドを配ることは、このプロジェクトが守れない約束になります。 CLI には画面がないためその問題とは無縁で、リリースのたびに ARM64 向けにも ビルドしています。

まずボードが 64 ビットのシステムで動いているか確認してください:

bash
uname -m   # aarch64 なら正解、armv7l は 32 ビットシステム

32 ビットの Raspberry Pi OS 向けのビルドはありません。64 ビットのイメージで 入れ直すのが唯一の道です。別のターゲットなので、変換できるものは何もありません。

そのうえでダウンロードページから mercy-cli-linux-arm64 を取得します:

bash
chmod +x mercy-cli-linux-arm64
sudo mv mercy-cli-linux-arm64 /usr/local/bin/mercy-cli
mercy-cli --version

あとはこのページの内容がそのまま通用します。Pi 4 なら複数キャラクターを余裕で 動かせますし、Pi Zero 2 W でも 1 体は動きます。mercy-node-linux-arm64 は 同じページにありますが、こちらはフリート用のワーカーで、最初に触るものでは ありません。

下の systemd のレシピでサービスとして登録し、systemctl enable しておけば、 ボードの再起動後に自動で戻ってきます。

レシピ ​

すべてのアカウントで 1 日 1 回まとめて回収する

bash
for account in alpha beta gamma; do
  MERCY_SF_PASSWORD="$(pass mercy/$account)" \
    mercy-cli --claim --user "$account" --character Hero || echo "failed: $account"
done

ダッシュボードのタイルを最新に保つ

bash
MERCY_SF_PASSWORD='…' mercy-cli --status --user someone --character Hero --watch 60

ログインは 1 回、1 分に 1 オブジェクト。代わりに cron から毎分これを回さないでくだ さい。それは毎回新しいログインです。

イベントをファイルに記録する

bash
MERCY_SF_PASSWORD='…' mercy-cli --start --user someone --character Hero --events \
  >> events.ndjson

ログインする前に、何と話しているかを確かめる

bash
api=$(mercy-cli --version | jq -r .api)
[ "$api" = "1" ] || { echo "unknown contract version: $api"; exit 1; }

systemd のサービスとして

ini
[Service]
Environment=MERCY_SF_PASSWORD=…
ExecStart=/usr/local/bin/mercy-cli --start --user someone --all --events
Restart=on-failure
KillSignal=SIGTERM

SIGTERM なら現在の手を終えられます。SIGKILL は使わないでください。


まだできないこと ​

複数のキャラクターを起動して個別に止めること(--all は全部を起動し、全部をまとめ て止めます)、動作中のプロセスへの制御チャンネル、そしてモジュールのスイッチを超え た変更。

そのどれかが必要なら、どれなのか教えてください。当て推量で作って使われないままにす るより、正しいものを作るほうが簡単です。

Mercy SF は Shakes & Fidget および Playa Games とは無関係です。ご利用は自己責任でお願いします。