5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[拡張版]PythonでDiscordのTRPG用のダイスボットを自作してみた

Posted at

前回、PythonでDiscordのTRPG用のダイスボットを自作してみたというものを作ってみました。
完成したウキウキ気分で早速、実際にオフセで使ってみたら使いにくいと結構不評でした。このままでは悔しいので、出てきた改善要望から特に要望の強かった機能を追加実装してみました。追加実装したのは次の4つです。

  1. ショットカットコマンド
  2. 一時的技能値補正
  3. 複数ダイス
  4. 対抗ロール
  5. シークレットダイス

需要があるのか不明ですが、アップデート版のコードはGitHubに上げておきます。

ショートカットコマンド

一番不評だったのがダイスを振るコマンドが長いということでした。「いちいちdice 1d100 SANなどと打つのは面倒」ということでしたので、単に技能名だけで振れるようにショートカットコマンドを実装します。
Discordにはスラッシュコマンドが存在するみたいなので、それに倣って

/(技能名)

でダイスを振れるようにしました。技能名は前回と同様にスプレットシートの技能名欄の文字です。ただ、当然既存のスラッシュコマンドとバッティングする技能名だと誤作動すると思います。

このままだとダイスを指定しないことになるのですが、ダイスの情報はスプレッドシートから取ってくることにします。ショートカットコマンドが欲しいという要望から推測できるように、基本的には技能に対して振るダイスはほぼ固定なのでデフォルトダイスを指定することでショートカットコマンドで技能を振れるようにしました。

結果、スプレットシートはこんな感じにしています。

NAME キャラ名 minus init 職業P 興味P dice
STR 15 0 15 0 0 1d100
CON 14 0 14 0 0 1d100
POW 15 0 15 0 0 1d100
アイデア 45 0 45 0 0 1d100
幸運 75 0 75 0 0 1d100
知識 75 0 75 0 0 1d100

一時的技能値補正

現状でもスプレッドシートの補正欄(minus)に補正値を入力すれば補正がかかるようにスプレットシートの方で計算式を組んではいます。ですが、実際にセッションを回してみると、PLの皆さんはセッション中にスプレットシートをいじるのは面倒なようで、補正がかかっているときは任意ダイスを振って成否は頭の中で判定していました。
そこで、スプレットシートを編集しなくてもそのダイスロール限定でダイス結果を補正できるようにしました。計算対象は単純な四則演算としています。

/(技能名)+20
/(技能名)-20
/(技能名)*5
/(技能名)/2

内部では技能名と演算子と補正値に分離して判定をしています。この時に便利なのがevalという関数です。evalを使うと文字列に対して計算してくれます。例えば、

print(eval('1+2'))
# 3

と言った感じです。これを使って補正付きの技能値を算出します。

dice_bot.py
def calc_ability(input_msg, charactor):
    operators = ['+', '-', '*', '/']
    for opt in operators:
        if  opt in input_msg:
            parsed_msg = parse('{}'+opt+'{}', input_msg)
            ability_name = parsed_msg[0]
            correction = parsed_msg[1]
            operator = opt
            ability = eval(
                charactor[ability_name]['value']+operator+correction
            )
            break
    else:
        ability_name = input_msg
        correction = ''
        operator = ''
        ability = charactor[ability_name]['value']

    return ability_name, int(ability), (charactor[ability_name]['value'], operator, correction)

あとは、補正された技能値に対して成否判定を行えば無事完成です。

複数ダイス

これまでは、1d4+1d6などのようにサイズの異なる複数のダイスを振りたいときは、1d41d6のダイスを別々に振らないといけなかったのですが、上記のようなロールをしたいタイミングがしばしばあったので実装してみました。

/dice 1d4+1d6

ちなみに

/dice 1d4+1d6+2-1

みたいなこともできます。

対抗ロール

これは完全にKPの準備不足だったのですが、対抗ロールの成功値を調べるのに手こずったので、対抗ロールもbotで判定できるようにしてやろうというものです。

やってることは単純に以下の式で算出される達成値を使って他の技能値判定と同じように成否の判定をしているだけです。
$$達成値 = \frac{対抗する側-対抗される側}{2}$$
【クトゥルフ神話TRPG】対抗・抵抗ロールの求め方について

対抗ロールの実行コマンドは以下のように定義しました。

VS (対抗する側の数値)/(対抗される側の数値)

シークレットダイス

Discordには一部のMarkdown記法が使えるようです。その中にネタバレ防止用のスポイラータグというものがあります。
【Discord】テキストを装飾する方法 | Markdown記法 チートシート

メッセージにマスクがかかっており、クリックをすることで表示状態にできるようです。これを使えば、シークレットダイスが実現できそうです(PLは勝手に表示しないという信頼の下であれば)。

# シークレットダイスを振る時
/dice 1d100 secret
# 判定つきでシークレットダイスを振る時
/dice 1d100(||10||) secret

Discord上ではこんな感じに見えます。
qiita.PNG

これでbotだけでできることが増えたので、セッションで使ってもらえるようになったのではないでしょうか。

それでは、皆さんもよきTRPGライフを。

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?