では、実際にダメージ計算式の導出にとりかかってみましょう。まずはモンスターの攻撃力についてです。モンスターに同士討ちをさせて色々なレベルに育て、その攻撃を盾を装備せずに攻撃を受けた時の最小ダメージと最大ダメージを記録しました。ただし、サンプル数が少なくあまり正確でないデータも多いことをお断りしておきます。例えばレベル19ドラゴンの攻撃は1回分のサンプルしか採取していないので、最小値も最大値も同じ231という数値になっていますが、おそらく実際の最小値はもっと小さい値に、実際の最大値はもっと大きい値になることでしょう。他のデータも同様に、ダメージの分布範囲がこれより狭いということはありえない、ということだけを意味するデータであるという点に留意してください。
このデータを眺めていて気づくのは、複数のモンスターにおいてダメージ上昇の仕方がかなり良く一致していることです。例えばレベル1〜8のスライムとおおなめくじが与えるダメージの範囲は、順に1〜2、2〜3、4〜5、7〜8、10〜13、15〜20、23〜30、35〜45であり、最小値も最大値も1ダメージとずれることなくぴったり一致しています。また、レベル1〜7のドラキーについて見てみると、順に2〜3、4〜5、7〜8、10〜13、15〜20、23〜30、35〜45と、ちょうどスライムと1レベル分ずれているだけだということがわかります。すなわち、ダメージ範囲が2〜3のモンスターのレベルが上がると、新しいダメージ範囲は例外なく4〜5になり、決して3〜4とか5〜6にはならないというわけです。
1〜2 | 2〜3 | 4〜5 | 7〜8 | 10〜13 | 15〜20 | 23〜30 | 35〜45 | |
---|---|---|---|---|---|---|---|---|
スライム | Lv1 | Lv2 | Lv3 | Lv4 | Lv5 | Lv6 | Lv7 | Lv8 |
おおなめくじ | Lv1 | Lv2 | Lv3 | Lv4 | Lv5 | Lv6 | Lv7 | Lv8 |
ゴースト | Lv1 | Lv2 | Lv3 | Lv4 | Lv5 | Lv6 | Lv7 | |
ドラキー | Lv1 | Lv2 | Lv3 | Lv4 | Lv5 | Lv6 | Lv7 | |
爆弾岩 | Lv3 | Lv4 | Lv5 | Lv6 | ||||
うごくせきぞう | Lv3 | Lv4 | Lv5 | |||||
ギガンテス | Lv12 | Lv14 | Lv16* | Lv17* |
いくつかのモンスターについて、ダメージ上昇の様子をまとめたのが表2-1です。データによっては完全にぴったりとは合っていないものも含まれています(*の付いたデータ)。例えばレベル16ギガンテスについては、24〜30というダメージしか観測できませんでした。が、それらについても予想されるダメージをはみ出すことはなかったので、サンプル数が少ないのが理由だと考えられます。もう少し根気良くデータを集めれば、最小値・最大値の両方がぴったりと合うことが確認できることでしょう。
さて、このように種類の異なるモンスターによるダメージが一致するという現象からは、モンスターの攻撃力を表す数値は一つの整数値で表現できるのではないかという推測が可能です。このような一致は攻撃力が離散的な量であるが故に起こると考えられるからです。 一般にコンピュータプログラムでは速度やメモリを節約するために整数の値しかとらない変数を用いることが多く、離散的な量が介在しているとすればプログラム内ではこうした整数型の変数が使われている可能性が非常に高いと言えます。 内部では互いに微妙に異なる実数値を持っており、端数処理の段階で差が消えているという可能性もありますが、モンスターの攻撃力はレベルの上昇に従い指数関数的に増大するので、もしそうならレベルが上がるにつれずれが拡大していきやがて差が見えるはずです。実際には、あるレベルで同じダメージ範囲を持つモンスターの組はレベルが上がっても同じダメージ範囲のままなので、これはちょっと考えにくいと言えます。少なくとも、観測不可能なほどの差しかないのなら、差はもともとないのだと考えても不都合はないと言えるでしょう。
もう一つ、このデータを元に、レベルが1上がるたびにダメージが何倍になっているのかをプロットしてみたのが図2-1です。詳しい説明は省きますが、サンプルデータの数による推定攻撃力の精度の違いを表すため、前節の結論である「ダメージは中心値に対して±1/8の範囲に分布する」を利用して各点の位置と誤差を算出し、それを元に誤差伝播を計算してプロットしました。
※ちなみに、レベルが上がって攻撃力が下がる例もありますが、ここではそうしたデータはとりあえず例外として除いてあります。そのへんについてはまた後ほど。
図2-1: モンスターのレベルが1上がるごとに攻撃力が何倍になるかを示した図。横軸がレベルアップ後の推定ダメージ、縦軸がレベルアップ前後の比。
この図を見ると、ダメージの上昇率は1〜2の間、とりわけ1.5あたりに集中していることがわかります。ダメージが小さい部分(図の左部分)で大きくぶれるのは端数処理による丸め誤差の影響でしょう。逆にダメージが大きい部分(図の右部分)で誤差棒が大きい点が目立つのは、データ採取がより困難になるためサンプル数があまりとれなかったためです。それ以外に系統的な変化は見られないので、モンスターがレベルアップするとその攻撃力は前後の条件に関係なく常に1.5倍になると考えて良いでしょう。
さて、ここまでで得られた情報を元に、モンスターの攻撃力とその変化の式を推定してみましょう。
表2-1のモンスターについて、以上三点を満たすように攻撃力を決定してやると、表2-2のようになります。
実際のダメージ範囲 | 攻撃力 | 攻撃力×7/8 | 攻撃力×9/8 | 攻撃力×143/128 |
---|---|---|---|---|
1〜2 | 2 | 1.75 | 2.25 | 2.234375 |
2〜3 | 3 | 2.625 | 3.375 | 3.3515625 |
4〜5 | 5 | 4.375 | 5.625 | 5.5859375 |
7〜8 | 8 | 7 | 9* | 8.9375 |
10〜13 | 12 | 10.5 | 13.5 | 13.40625 |
15〜20 | 18 | 15.75 | 20.25 | 20.109375 |
23〜30 | 27 | 23.625 | 30.375 | 30.1640625 |
35〜45 | 41 | 35.875 | 46.125* | 45.8046875 |
1.5倍した時の端数はすべて切り上げとしました。攻撃力が2→3→5→8→12→18→27→41→……と上がっていくわけです。
このように攻撃力を決めてやると、「攻撃力×7/8の端数を切り下げた値」が、ダメージ最小値とぴったり一致します。が、「攻撃力×9/8の端数を切り下げた値」は残念ながらいくつかのデータで実測値と計算値が異なる結果が得られました(*のついた数字)。 前節では最大値と最小値の比はおよそ1.27〜1.28であると書きましたが、9/8と7/8の比は1.286であり、若干最大値と最小値の開きが大きくなります。 より正確を期すなら、最大値に対して「×9/8より少しだけ小さい数字」を考えなければいけません。
結論から言うと、143/128という数字を採用しました。上の表を見るとわかるように、「攻撃力×143/128の端数を切り下げた値」は実際のデータと完全に一致します。143/128という数字はいかにも中途半端で恣意的に選んだ感じを受けるかもしれませんが、この値を採用したのには実はわけがあります。その理由は、このゲームでは「同一パラメータでのダメージ分布は最大で32通りの値しかとらない」という法則があることに起因します。
図2-2は攻撃力最大時のトルネコがゴースト及びももんじゃを攻撃した時のダメージ分布です(両者はダメージの最小値と最大値が一致するため、ここではまとめて扱いました) 。これを見ると、最小値と最大値の間に絶対に生じない値というのがいくつか存在し、結果飛び飛びの分布になっているのがわかるかと思います。124〜159の範囲に分布していますが、そのうち126、136、145、155の4種のダメージはこの条件では絶対に生じません。抜けが4あるので実際に取り得る値は32通りだけなのです。他の条件下においても同様で、ダメージがある程度大きい場合は全部で32通りの値しかとらず、ところどころに抜けが生じるダメージ分布となります。
図2-2:攻撃力最大のトルネコがゴースト/ももんじゃを攻撃した時に与えるダメージを記録したもの
こうした抜けはなぜ生じるのでしょうか?ダメージがプレイヤーにとって連続分布しているように見える場合でも、実はプログラム内部では32の項からなる離散値なのでしょう。 最終的にプレイヤーが観測するダメージはもちろん整数でありいつも離散的な分布です。が、それは連続的な分布が与えられてそれを整数値に直す段階で離散的になるのではなく、 整数値に直す前のもともとの分布がすでに離散的であり、その間隔がたまたま1より大きくなった場合にこのように抜けが生じるのだと思われます。
では、その32個の数字のもともとの間隔を求めてやりましょう。 抜けている値はだいたい等間隔に並んでいるので、 分布として32の項からなる等差数列を考えてみることにします。 初項=攻撃力×7/8、第32項=攻撃力×9/8より少し小さい値、とすると (9/8-7/8)/32=1/128より公差≒攻撃力×1/128になります。 32個の数列が正確に攻撃力×1/128の間隔から成るとすると、 第32項=最大ダメージ=攻撃力×143/128になるというわけです。 いちいち示しませんが、143/128という値を採用することで、 別表のモンスターリストに記載したように攻撃力を決めると、そこからレベルアップした分も含めて先ほどのデータのすべてが必ずこの範囲に収まること、そして十分多いサンプル数からなるデータについては表2-2で示したように予想値と実測値が完全に一致することが確認できました。
ちなみに、レベルが上がって攻撃力が下がる事象については、1.5倍すると255を超える時にのみ起こるようです。1.5倍した後256を引くという操作を行うことで、ダメージ範囲を正確に予想することができました。
トップ > ゲームの話 > トルネコの大冒険 > 補足その2:ダメージ計算式の導出 > 2.モンスターの攻撃力とダメージ分布その2