luxのメダロットブログ

ダメージ計算検証ほか

威力、成功のダメージ寄与とダメージ乱数幅の推定#1

 

この記事の概要 

こちらには、ストーリー 第4部 第6章 ロボトル6-1 ヒメダッカーx3 ベリーハードに対してハーモニーLv90で攻撃した時のダメージを計測し、この条件における威力、成功のダメージへの寄与率ダメージ乱数幅、おまけとして(かすり, 防御, ヒット, クリティカル)のダメージ比を解析した結果が掲載されています。

また初回であるため、このブログの設立背景ダメージ計算への基本的な考え方、そして解析にかかるツール群も載せています。むしろ前半半分はこの説明です。

 

このブログの設立背景

メダポン燃え尽き症候群に陥っていた去る8月7日、袴矢 (@hakamaya63) | Twitterさんの【メダロットS】ダメージ計算の試み - はんまーに乾杯を拝見し、ダメージ計算式を解明したい欲求が出てきました。

またこれまでの計測、解析でいくらか分かったことがあるのですが、Twitterでは文字数や図表の表現に限界があるため、ブログを作って公開することとしました。

 

基本方針

本ブログでは、全体を把握した後に各論を詰めていくアプローチは取らず、各論を積み上げて、最終的に全体を論じていければと思います。ゆえにニッチな議論ばかりをするため取りつきにくいかもしれませんし、全体として何が分かったのかを論じるのに多大な時間がかかります。

ダメージ計算式を利用する目的に訪れられている方へ、そのダメージが計測できる場合は、計測してしまったほうが早いです。 もしパーツ不足などで計測できない場合や、メダリーグで多数の仮想敵に対して所有パーツが出せるダメージがいくらか占う際には、もしかしたらダメージ計算式が役に立つかもしれないという立場です。

 

解析にかかるツール群

ロボトル中にダメージを記録することは、メッセージウィンドウの小ささ、送りの早さのため大変至難で、かつ客観的な証拠を残せません。

f:id:medarotter_lux:20210823140335p:plain
f:id:medarotter_lux:20210823140327p:plain
貫通時などに被弾ダメージが一瞬で送られてしまう

本ブログでは、これらの問題を解決するためツールの開発に注力しました。 具体的には、以下のようなパイプライン処理を構築し、ダメージ計測を行っています。

  1. (手動)スマートフォンでロボトルを録画する (Android標準アプリのスクリーンレコード)
  2. (自動)自宅NASに動画を転送する (AndroidサードパーティアプリのFolderSync)
  3. (自動)自宅サーバにて動画を解析しダメージ計測結果を出力する (自作のアプリケーション、後述)

結果として得られるのはターン毎のダメージ計測結果(下記表)と、ツールの動作確認用動画(Twitter参)です。

各攻撃ターン(turn_no)について、対象機体は何番目か(target_no)、どういう防御姿勢をとったか(defense)、ダメージはいくらか(damage)が分かります。 また脚部の有無がダメージに寄与するためにそのフラグ(has_leg / 1:あり, 0:なし)、頭部破壊でダメージを正しく計測できない場合を判断できるよう、どのパーツを破壊したか(destroyed)も導きます。

f:id:medarotter_lux:20210823113550p:plain

ターン毎のダメージ計測結果

 

自作の解析ツール

自作の解析ツールはPython on Jupyterで動いていて、環境はAnacondaで作りました。 また標準で入っているOpenCVで動画や画像を扱えたため、追加でインストールしたのはTesseract-OCRだけでした。

ツールがやっていることは概して下記のとおりです。 詳細なアルゴリズムは説明しません。

  1. 動画のfpsを1/10に落とす(*)
  2. 動画から自ターン候補を判断し(*)画像として保存
  3. 自ターン候補画像に対し、メッセージウィンドウに変化がある場合に(*)OCR実行
  4. 自ターン候補画像に対し、防御姿勢(文字色)判定
  5. 2.~4.の結果から自ターンを再定義、相手の防御姿勢を確定し、ターン毎のダメージ計測結果(前出)を生成
  6. (オプションとして)ツールの動作確認用動画(前出)を生成

(*)は処理コストの高いOCRの実行回数を減らすため加えています。防御姿勢を文字色判定にしているのも同じ理由です。

現在のところ、およそ動画の長さと同じくらいの時間で結果が出てきます。

 

8月21日現在の進捗 --- 威力、成功のダメージ寄与とダメージ乱数幅の推定#1 ---

ついに本エントリーのメインです。ダメージ計算式を解き明かす手始めとして、これらから取り掛かることにしました。

  1. ダメージの威力寄与度
  2. ダメージの成功寄与度
  3. ダメージの乱数幅
  4. (おまけとして)かすり・防御・ヒット・クリティカル間の関係

そしてわかったことは下記のとおりです。

(詳細を読まれる前に、些末ですが説明を挟みます)本ブログでは推定から得られた数値を[0.02, 0.04]のように区間で表すこととし、例の場合は厳密には(0.015~0.044...)を指します。この区間は、明記がない限り99%信頼区間を示します。つまり、この範囲内に真値がある確率は99%であることを意味します。推定値が一つしか書かれていない場合は、より下位の桁の打ち切りのために一つになってしまったことを意味します。例えば0.08とだけ書かれている場合は(0.075~0.0844...)を指します。

 

ダメージの威力寄与度

  • 威力が2倍になることは、ダメージが[1.66, 1.70]倍になることに相当
  • ただし例外(赤字)として、防御時は[1.95, 1.96]倍増

f:id:medarotter_lux:20210823120447p:plain

ダメージの威力寄与度

 

ダメージの成功寄与度

  • 成功が2倍になることは、ダメージが[1.69, 1.73]倍になることに相当
  • ただし例外(赤字)として、かすり時は[2.23, 2.29]倍増
  • 本計測では、概して威力寄与度よりも成功寄与度のほうが高いか同程度のよう

f:id:medarotter_lux:20210823120457p:plain

ダメージの成功寄与度

 

ダメージの乱数幅

  • 乱数幅は[7.0%, 8.2%]
  • ただし、クリティカルの場合に[9.8%, 10.5%]の傾向と、[10.9%, 11.7%]の2つの傾向あり(赤字)

f:id:medarotter_lux:20210823114016p:plain

ダメージの乱数幅

 

かすり・防御・ヒット・クリティカル間の関係

  • (かすり, 防御, ヒット, クリティカル)のダメージ比は、ヒット時を1.00とすると、([0.51, 0.53], [0.71, 0.72], 1.00, [1.38, 1.41])
  • この結果は、防御姿勢によるダメージ軽減・増加は一定倍しているだけだと示唆される。バリエーションを増やして調査したい
  • また例外(赤字)は、ダメージの威力寄与度、ダメージの成功寄与度で例外となっていた事例と一致

f:id:medarotter_lux:20210823120100p:plain

ヒットを基準としたかすり・防御・クリティカルのダメージ比

 

今回の推定に用いた計測・推定結果

今回の計測・推定結果は下記図のとおりです。ただし回避の項は無効を示すオール0となっています。 

f:id:medarotter_lux:20210823114341p:plain

計測・推定結果
計測条件

計測条件はtitledefenseのとおりです。 titleヒメダッカは素のハーモニーLv90での攻撃、オプチカルではMFオプチカルによって威力を2倍、グラビティでは成功を2倍した条件となります。 なお、計測中はフルオートで回しています。

相手にストーリー 第4部 第6章 ロボトル6-1 ヒメダッカーx3 ベリーハードを選んだ理由は様々あります。 低ENで繰り返し試行できる、同じ構成が3体ならんでいる、被ダメージが相対して小さい、症状デバフでダメージが増加減少しない(MFレベルロストを除く)、ヒール能力があり継戦性能に長けているためです。

また攻撃パーツをハーモニーLv90にした理由は、与えるダメージが相対して小さく貫通能力があるためです。 メダルはウサギ(スピード性格)にしており、脚をあまり狙わないようにしています。

計測結果

計測結果は順に、計測ダメージ最小値(obs_min: 図中水色線)、計測ダメージ最大値(obs_max: ピンク線)、計測回数(N)です。なお図中の4色点は実際の計測ダメージで、試合(動画)が変わるたびに色を変えています。これはツールの結果に異常値が含まれているかどうかの確認、追及に役立ちます。

推定結果

推定結果は順に、推定ダメージ最小値(est_min: 青線)、推定ダメージ最大値(est_max: 赤線)、推定ダメージ中央値の考えられる最小(est_mid_m: 緑線(下))、推定ダメージ中央値の考えられる最大(est_mid_p: 緑線(上))。 あと下図には表れていませんが、推定乱数幅の最小値(rate_m)、推定乱数幅の最大値(rate_p)、各推定値の信頼区間(possibility)です。数値の出し方は次項をご覧ください。

f:id:medarotter_lux:20210823141912p:plain

ダメージ計測、推定結果

 

推定方法

かなりマニアックな章です。取りつきにくい章ですが、甘い箇所があると思うので査読いただけると幸いです。

推定は、乱数の分布が離散一様分布 - Wikipediaであることを仮定しています。 分布については、下記図の灰色点(小さい順にソート)が一直線に並んでいる様子から視覚的に説明できますし、尖度 - Wikipediaがおよそ-1.2付近であるため一様分布の傾向を示しています。 

f:id:medarotter_lux:20210823144646p:plain

ダメージは一様分布の傾向

乱数振れ幅およびダメージ中央値の99%信頼区間を求めます。

  1. 計測実績から計測振れ幅(obs_length)を計算する(obs_length = obs_max - obs_min)
  2. 推定振れ幅(est_length)として計測振れ幅+1と仮定する(est_length = obs_length + 1)
  3. 計測回数(N)でその推定振れ幅を計測できなかった確率(possibility)を計算する(*) (possibility = 1 - (obs_length / est_length)^N)。
  4. その確率が99%を超える値になるまで2.~4.を繰り返す
  5. 結果得られる推定振れ幅は99%信頼区間にあたる(est_length確定)
  6. 確定した推定振れ幅から推定ダメージ最大・最小値を求める(est_min = obs_max - est_length, est_max = obs_min + est_length)
  7. 計測ダメージ最大・最小値、推定ダメージ最大・最小値から推定ダメージの中央値の最大・最小を求める(est_mid_m = (est_max - obs_min) / 2, est_mid_p = (obs_max - est_min) / 2)。これは推定ダメージ中央値の99%信頼区間にあたる。

(*)これはたとえば計測できている幅が300である場合に、推定として幅400を持ってくる「無理さ加減」が確率(possibility: むしろimpossibilityか...)に表されています。この無理さ加減は試行回数(N)にもよります。 具体的には、2回の計測で幅300と言っている場合の幅400説は「有り得るかも(possibility=43.8%)」ですが、100回の計測で幅300と言っている場合の幅400説は「決してあり得ない(possibility=100%)」です。

引き続き乱数幅の99%信頼区間を求めます。

  1. 乱数幅最小(rate_m)は、中央値が候補内最大のest_mid_pで、振れ幅が候補内最小のobs_lengthである場合(rate_m = obs_length / est_mid_p / 2)
  2. 乱数幅最大(rate_p)は、中央値が候補内最小est_mid_mで、振れ幅が候補内最大のest_lengthである場合(rate_p = est_length / est_mid_m / 2)

 

今後の進め方

正直なことを言うと、いきなり悩んでいます。 というのも、威力や成功のダメージ寄与度は固定割合であろう、乱数幅は(整数)%で、防御姿勢などによらず固定であろうと推定していたものが否定され、より複雑であることを示しているためです。一方で乱数の分布が一様分布であったこと、防御姿勢の違いによるダメージ増減が一定倍となる傾向をつかんだことは収穫です。

威力や成功のダメージ寄与度について、今回の結果を受け、威力、成功がある値を超えると傾向が変わる説を立てます。これは固定値かもしれませんし、受け手のパラメータによる可能性もあります。しかしなぜ、かすり(グラビティ)と防御(オプチカル)のときに例外的に傾向が変わったのかは、予測が立ちません。

乱数幅については、具体的な策はなく、より様々なパーツで計測して傾向をつかむことにします。

今後の進め方としては、各論ごとに固める基本方針を鑑み、攻撃パーツを変えたりバフの種類を変えたりして同様の試行を繰り返そうと考えています。特にレーダーサイトでの成功+30%は見る価値があると思っています。

そして威力や成功のダメージ寄与度、乱数幅を解明した後、攻撃側のスキルLv、防御側の補助系スキルLv計、格耐・射耐、回避値のダメージ寄与度を調査し、ダメージ計算式の推定につなげていきます。