オーバーフローで負のダメージが発生し回復するという事象について知りたい
はじめに
ポケモンチャンピオンズ(『Pokémon Champions』、公式略称ポケチャン)の仕様関連記事です。
海外で、負のダメージに関する動画が投稿されました。オーバーフローによりダメージがマイナスの値になり、結果的に攻撃を受けたポケモンが回復します。英語の投稿・動画であり、日本のポケモン界隈にはあまり情報が伝わっていないので、日本語の解説記事を作成することにしました。たぶん、チャンピオンズのオーバーフローに関する初の日本語記事です。
概要 負のダメージオーバーフロー
前提をいろいろ書いてから本題に入りますし、記事全体も長いため、先に簡単に概要だけ書きます。
<概要>
チャンピオンズのダメージ計算における値の取り扱いが、第七世代~第九世代の歴代作品とは少し違うため、ダメージ計算の過程でオーバーフローが起きることにより負の値が発生し、最終的なダメージも負の値になることがあるようです。
実験では、ダメージを受けているポケモンに、オーバーフローがなければ大ダメージになるはずの攻撃を与えたところ、そのポケモンのHPが回復しました。
前提1 過去の符号なし16bitダメージオーバーフロー
近年(おそらく第五世代~第九世代)の本編のポケモンでは、いろいろな効果を考慮した後の最終的なダメージが65536(=2の16乗)以上になった場合、ダメージオーバーフローが起きて0~65535の範囲内のダメージになるという現象があります。
この記事では、これを「符号なし16bitダメージオーバーフロー」と呼びます。
オーバーフローがどのような現象であるのかについては、別途検索して調べるのが一番よいですが、一応、簡単な説明を試みた本ブログの記事があるので紹介します。
【ポケモン】てんのめぐみ+にじ+チャージビームのオーバーフロー後の追加効果発生確率はおそらく25ではなく24である理由 - テツポンドのブログ
長針だけのアナログ時計で72分を表現しようとしてもそれが12分の表示になるのと同じような現象です。この例だと、数値が60以上になった場合、オーバーフローによって0~59の範囲内の数値になるというわけです。
さて、「符号なし16bitダメージオーバーフロー」に話を戻します。
これについて、詳しくは6年前に以下の記事で書いています。65536の倍数のダメージを出せば、最終的なダメージを0にできます。
tetspond.hatenablog.com
上記の記事では第八世代の実験を取り上げていますが、他の世代でも確認されています。
第六世代:【ORASトリプルバトル】最強の矛VS最弱の盾 - TENTA1観測(※実戦利用 https://www.youtube.com/watch?v=GljovCqN0-0)
第九世代:【ポケモンSV】一人で簡単にできるダメージオーバーフロー実験 〜約300万ダメージを耐えてもらおう〜 - テツポンドのブログ(※準備が簡単なオーバーフロー体験)
前提2 過去の符号なし32bitダメージオーバーフロー
前の項の「符号なし16bitダメージオーバーフロー」とは別に、近年(おそらく第五世代~第九世代)の本編のポケモンでは、ダメージ計算の途中で4,294,967,296(=2の32乗)以上の数値が発生した場合、オーバーフローが起きてその数値が小さい値になり、その後の計算がその値をもとに進んでいきます。
この記事では、これを「符号なし32bitダメージオーバーフロー」と呼びます。昔は、普通に「32bitダメージオーバーフロー」と呼んでいたのですが、この記事で出てくるメインの事象と区別するために、こう呼びます。
詳しくは3年半前に以下の記事で書いています。
tetspond.hatenablog.com
第七世代での海外の実験の内容を解説しつつ、協力者とともに第八世代・第九世代での検証をしています。
上記記事にも書いている、オーバーフローを発見した人と発見した経緯についての情報をここに再掲します。
日本のポケモン動画投稿者であるランドセルさんの偶然の別のバグ(ころがるばけのかわバグ)発見が最初のきっかけになり、ポケモン対戦仕様研究者のSadisticMysticさんがオーバーフローを発見しました。SadisticMysticさんがめちゃくちゃすごいです。
=====
動画内では、このオーバーフローは2018年4月に、ポケモン仕様研究者SadisticMysticさんが発見したという情報がありました。動画のコメント欄の固定コメントで以下サイトの以下投稿が紹介されています。
www.smogon.com
#203~212が今回のテーマに関連する話題です。
実は、この発見の源流を辿ると日本のポケモンの動画に行き着きます。
2018年4月15日に、日本のポケモン動画投稿者であるランドセルさんが、ころがる化けの皮バグの動画を投稿しました。ランドセルさん自身が実戦でころがるを使ったときに起こったものです。
同日、海外のポケモンの交流サイト?のSmogonにこのことが紹介されました。
同月22日、このバグを利用していろいろなことを調べていく中で発見されたこのオーバーフローについてSadisticMysticさんが紹介したのが上記投稿です。
ちなみに、ポケモン仕様研究者SadisticMysticさんは筆者に連絡をくださり2本の面白い記事を一緒に作ったことがあるので、紹介しておきます。
【ポケモン】レベルアップ時のステータス上昇量合計の最小値はいくつ? - テツポンドのブログ
【ポケモン】レベルアップ時のステータス上昇量合計の最大値はいくつ? - テツポンドのブログ ←この記事でSadisticMysticさんに提供していただいた画像は、ポケソルのとある動画(6:50)の特に引用の必要もない場面で転載されていたという裏話があります。
=====
取り扱う動画の情報
さて、過去世代で、オーバーフローがどのような起き方をしていたのかを確認したところで、今回の発見を見ていきます。
まずは、今回取り扱う動画の基本情報です。
<動画タイトル>
Negative Damage in Pokemon Champions
(和訳:ポケモンチャンピオンズにおける負のダメージ)
<媒体・リンク>
YouTube
https://www.youtube.com/watch?v=MEc9So7IwEY
<投稿日>
2026年10月4日(1週間前)
<出演者>
Leonard Craft III(@DaWoblefet)さん:仕様研究者 (筆者のTwitterFF)
Leonard Craft III (@DaWoblefet) / Twitter
<使用ソフト>
ポケモンチャンピオンズ
※投稿日は、9月17日のVer1.2.1アップデートと10月7日のVer1.2.2アップデートの間の時期であり、実験から日が経っていないなら、Ver1.2.1で実験したと思われます。
<動画の流れ>
概要説明
実験1
実験2
これまでのダメージオーバーフロー
きっかけとなった最大ダメージ実験
推測
計算
謝辞
実験1(かえんボール) ステータス・行動
動画で紹介された2つの実験のうち、1つ目のほうを見ていきます。エースバーンのかえんボールでオーバーフローを引き起こします。
<ステータス>
エースバーン: 勇敢・攻撃13振り 元々のこうげき実数値163
ゲンガー: 防御下降補正・防御0振り 元々のぼうぎょ実数値72
<行動>
1ターン目開始前
手前側 カミツオロチ・グソクムシャ
奥側 ゲンガー・チャーレム
カミツオロチ かんろなミツ発動 ゲンガー等:回避-1
1ターン目
カミツオロチ エースバーン(持ち物:メトロノーム)に交換
グソクムシャ メガグソクムシャにメガシンカ
ゲンガー ミラータイプ(グソクムシャ方向) ゲンガー:むしはがねタイプ
チャーレム スキルスワップ(エースバーン方向) エースバーン:特性ヨガパワー
メガグソクムシャ いやなおと(ゲンガー方向) ゲンガー:防御-2
2ターン目
チャーレム オーロットに交換
ゲンガー ミラータイプ失敗
エースバーン つるぎのまい エースバーン:攻撃+2
メガグソクムシャ いやなおと(ゲンガー方向) ゲンガー:防御-4
3ターン目
ゲンガー ミラータイプ失敗
エースバーン つるぎのまい エースバーン:攻撃+4
オーロット もりののろい(ゲンガー方向) ゲンガー:むしはがねくさタイプ
メガグソクムシャ いやなおと(ゲンガー方向) ゲンガー:防御-6
4ターン目
オーロット ヤレユータンに交換
メガグソクムシャ ハカドッグ(現状唯一のもふもふ持ち)に交換
ゲンガー スキルスワップ(ハカドッグ方向) ゲンガー:特性もふもふ
エースバーン つるぎのまい エースバーン:攻撃+6
5ターン目
ハカドッグ カミツオロチに交換
ゲンガー こらえる
エースバーン かえんボール(1)(カミツオロチ方向) カミツオロチ:ひんし
ヤレユータン しんぴのまもり 奥側:~9ターン目まで状態異常無効
6ターン目
ハカドッグ こらえる
ヤレユータン こらえる
ゲンガー にほんばれ
エースバーン かえんボール(2)(ヤレユータン方向) ヤレユータン:残りHP1
7ターン目
ゲンガー こらえる
エースバーン かえんボール(3)(ゲンガー方向) ゲンガー:残りHP1
ハカドッグ マッドショット(エースバーン方向) エースバーン:すばやさ-1
ヤレユータン さいはい(エースバーン方向)
エースバーン かえんボール(4)(ゲンガー方向) ゲンガー:HP変化なし
8ターン目
ハカドッグ こらえる
ヤレユータン こらえる
ゲンガー にほんばれ失敗
エースバーン かえんボール(5)(ヤレユータン方向) ヤレユータン:HP変化なし
9ターン目(目的のターン)
ハカドッグ てだすけ(エースバーン方向) ※1回目
ゲンガー こらえる
ヤレユータン さいはい(ハカドッグ方向)
ハカドッグ てだすけ(エースバーン方向) ※2回目
エースバーン かえんボール(6) (ゲンガー方向) ゲンガー:HP全回復
バトルログ上のゲンガーのHP表記
手前側から見たとき 299%→100%
奥側から見たとき 64647→167 (64480減少)
※()は個人的メモで、バトルログに表示されているわけではないです。
10ターン目(何回か試す)
ほか同上
エースバーン かえんボール(7) (ゲンガー方向) ゲンガー:HP満タンのまま
バトルログ上のゲンガーのHP表記
手前側から見たとき 530%→100%
奥側から見たとき 21255→167 (21088減少)
11ターン目(何回か試す)
ほか同上
エースバーン かえんボール(8) (ゲンガー方向) ゲンガー:HP満タンのまま
バトルログ上のゲンガーのHP表記
手前側から見たとき 755%→100%
奥側から見たとき 30119→167 (29952減少)
実験2(つけあがる) ステータス・行動
動画で紹介された2つの実験のうち、2つ目のほうを見ていきます。ゴロンダの威力660のつけあがるでオーバーフローを引き起こします。
<ステータス>
ゴロンダ: 元々のこうげき実数値192(いじっぱり・31振りなどで実現可能)
ピカチュウ: 元々のぼうぎょ実数値54(さみしがり・0振りなどで実現可能) ※チャンピオンズに現在登場するポケモンの中で可能な最低値
ピカチュウ: HP実数値142
<行動>
1ターン目開始前
手前側:ピカチュウ・ガラルマッギョ
奥側:カラマネロ・チャーレム
1ターン目
ピカチュウ はやてがえし失敗
カラマネロ つぼをつく(チャーレム方向) 攻撃アップ
チャーレム ビルドアップ チャーレム:攻撃+3 防御+1
ガラルマッギョ いやなおと(ピカチュウ方向) ピカチュウ:防御-2
2ターン目
ピカチュウ はやてがえし失敗
カラマネロ つぼをつく(チャーレム方向) 攻撃アップ
チャーレム ビルドアップ チャーレム:攻撃+6 防御+2
ガラルマッギョ いやなおと(ピカチュウ方向) ピカチュウ:防御-4
3ターン目
ピカチュウ はやてがえし失敗
カラマネロ つぼをつく(チャーレム方向) 防御アップ
チャーレム ビルドアップ チャーレム:攻撃+6 防御+5
ガラルマッギョ いやなおと(ピカチュウ方向) ピカチュウ:防御-6
4ターン目
ガラルマッギョ ヤレユータンに交換
ピカチュウ はやてがえし失敗
カラマネロ つぼをつく(チャーレム方向) 回避アップ
チャーレム ビルドアップ チャーレム:攻撃+6 防御+6 回避+2
5ターン目
ピカチュウ はやてがえし失敗
カラマネロ つぼをつく(チャーレム方向) 命中アップ
チャーレム ビルドアップ失敗 チャーレム:攻撃+6 防御+6 命中+2 回避+2
ヤレユータン スキルスワップ ヤレユータン:特性ヨガパワー
6ターン目
ピカチュウ はやてがえし失敗
カラマネロ つぼをつく(チャーレム方向) 特攻アップ
チャーレム つぼをつく(チャーレム方向) 回避アップ
ヤレユータン さいはい(カラマネロ方向)
カラマネロ つぼをつく(チャーレム方向) すばやさアップ
チャーレム:攻撃+6 防御+6 特攻+2 すばやさ+2 命中+2 回避+4
7ターン目
ピカチュウ はやてがえし失敗
カラマネロ つぼをつく(チャーレム方向) 命中アップ
チャーレム つぼをつく(チャーレム方向) 回避アップ
ヤレユータン さいはい(チャーレム方向)
チャーレム つぼをつく(チャーレム方向) すばやさアップ
チャーレム:攻撃+6 防御+6 特攻+2 すばやさ+4 命中+4 回避+6
8ターン目
カラマネロ ブリムオンに交換
ピカチュウ はやてがえし失敗
チャーレム つぼをつく(チャーレム方向) 特防アップ
ヤレユータン さいはい(チャーレム方向)
チャーレム つぼをつく(チャーレム方向) 特攻アップ
チャーレム:攻撃+6 防御+6 特攻+4 特防+2 すばやさ+4 命中+4 回避+6
9ターン目
ピカチュウ はやてがえし失敗
チャーレム バトンタッチ ゴロンダ(持ち物:メトロノーム)登場
ゴロンダ:攻撃+6 能力上昇合計32段階
ヤレユータン スキルスワップ(ゴロンダ方向) ゴロンダ:特性ヨガパワー
ブリムオン まほうのこな(ピカチュウ方向) ピカチュウ:エスパータイプ
10ターン目
ヤレユータン パンプジンに交換
ブリムオン こらえる
ピカチュウ はやてがえし失敗
ゴロンダ つけあがる(1)(ブリムオン方向) ブリムオン:残りHP1
11ターン目
ピカチュウ こらえる
ゴロンダ つけあがる(2)(ピカチュウ方向) ピカチュウ:残りHP1
パンプジン ハロウィン(ピカチュウ方向) ピカチュウ:エスパーゴーストタイプ
ブリムオン めいそう
12ターン目
パンプジン ヤレユータンに交換
ブリムオン こらえる
ピカチュウ はやてがえし失敗
ゴロンダ つけあがる(3)(ブリムオン方向) ブリムオン:HP変化なし
13ターン目
ピカチュウ こらえる
ゴロンダ つけあがる(4)(ピカチュウ方向) ピカチュウ:HP変化なし
ヤレユータン さいはい(ゴロンダ方向)
ゴロンダ つけあがる(5)(ピカチュウ方向) ピカチュウ:HP変化なし
14ターン目(目的のターン)
ブリムオン てだすけ(ゴロンダ方向)
ゴロンダ つけあがる(6)(ピカチュウ方向) ピカチュウ:HP全回復
バトルログ上のピカチュウのHP表記
手前側から見たとき 50246→142 (50104減少)
ピカチュウ ボルテッカー外れ(ゴロンダ方向)
ヤレユータン さいはい(ゴロンダ方向)
ゴロンダ つけあがる(7)(ピカチュウ方向) ピカチュウ:HP再全回復 ※残りHPがわずか(赤ゲージ)の状態から回復するように見える表示
バトルログ上のピカチュウのHP表記
手前側から見たとき 62590→142 (62448減少)
15ターン目
ヤレユータン パンプジンに交換
ブリムオン てだすけ(ゴロンダ方向)
ゴロンダ つけあがる(8)急所(ピカチュウ方向) ピカチュウ:HP再全回復 ※残りHPがわずか(赤ゲージ)の状態から回復するように見える表示
バトルログ上のピカチュウのHP表記
手前側から見たとき 47494→142 (47352減少)
ピカチュウ ボルテッカー(パンプジン方向) ピカチュウ:HP139/142
バトルログ上のピカチュウのHP表記
手前側から見たとき 142→139
推測 チャンピオンズの計算仕様
実験1と実験2で起こったことについて、DaWoblefetさんは、ポケモンチャンピオンズのダメージ計算で32bit符号付き整数が使われていると推測して説明をしています。チャンピオンズでは、プログラミング言語の関係で、これまでの32bit符号なし整数ではなく、32bit符号付き整数で計算が行われているのではないかという話です。
自分なりに説明してみます。
これまでの本編のダメージ計算では、0から2の32乗-1(=4,294,967,295)の範囲の約43億個の数字表現で、ダメージ計算の最中に出てくる数値を取り扱っていました。2の32乗以上の数値が発生したときには、その値は2の32乗で割った余り、つまり、0以上2の32乗未満の整数として扱われました。これが符号なし32bitオーバーフローです。
一方、チャンピオンズのダメージ計算では、2の31乗にマイナス1をかけたもの(= -2,147,483,648)から2の31乗-1(= +2,147,483,647)の範囲の約43億個の数字表現で、ダメージ計算の最中に出てくる数値を取り扱っていると思われます。ここでは、2の31乗-2は2の31乗-2として扱われ、2の31乗-1は2の31乗-1として扱われ、2の31乗は- (2の31乗)として扱われ、2の31乗+1は- (2の31乗)+1として扱われ、2の31乗+2は- (2の31乗)+2として扱われます。2の31乗以上で2の32乗未満の数値が発生したときには、その値は、その値から2の32乗を引いた数、すなわち負の整数として扱われます。これが符号付き32bitオーバーフローです。
追加で、分かりやすいように説明を加えます。分かっている人はこの段落は飛ばしてください。
2の32乗だと大きくて理解しにくいので、2の4乗(=16)に置き換えて考えてみます。
これまでは、0~15の16個の数字表現で、値を取り扱っていました。5+13で18になったときには、それは18÷16の余りである2として扱われました。すなわち、5+13⇒2であるかのように処理されます。
しかし、今回は、-8~7の16個(負の整数8つと0と正の整数7つ)の数字表現で、値を取り扱っています。ここでは、6は6として扱われ、7は7として扱われ、8は-8として扱われ、9は-7として扱われ、10は-6として扱われます。5+7で12になったときには、12から16を引いた数である、-4として扱われます。すなわち、5+7⇒-4であるかのように処理されます。
これのもっと桁が大きいバージョンが、今回の2の32乗の件です。
このようにして、ダメージ計算の途中で負の整数が生じて、そのままダメージが負の整数のまま進み、最終的なダメージも負の整数になったのだろうという推測です。
ゲームのコードを確認することはできないため、正しいことと断定することはできないものの、他に有効な説明がないため、この推測が正しいと筆者も考えています。
ちなみに、あとで書きますが、符号付き16bitオーバーフローによるものという説も棄却されています。
実験1(かえんボール) 計算
実際に、今回の実験ではどのように数値が動いているのか、見てみます。
補正の計算方法は、厳密にはもう少し複雑なんですが、結果に影響がない部分は、通常の計算方法を用います。すなわち、てだすけ2回を単に「1.5倍を2回適用するもの」として扱うなどします。
端数計算も、結果に関係ないところは省略します。
最終威力
かえんボール 元々の威力は120
てだすけ2回 120*1.5*1.5= 270
最終威力 270
最終こうげき
エースバーン 元々のこうげき実数値は163
こうげきランク+6 163*4 = 652
ヨガパワー 652*2 = 1304
最終こうげき 1304
最終ぼうぎょ
ゲンガー 元々のぼうぎょ実数値は72
ぼうぎょランク-6 72/4= 18
最終ぼうぎょ 18
基礎ダメージ
ここまでに計算した3つの数字を使って、補正前の基礎ダメージを計算すると、
( 22*威力*こうげき/ぼうぎょ ) /50 +2
= ( 22*270*1304/18 ) /50+2
= 430320 /50 +2
= 8606.4 +2
小数点以下切り捨てで 8608
晴れ補正
晴れている状態でほのおタイプの攻撃技を使うので、晴れ補正1.5倍がかかります。
8608の1.5倍で 12912
乱数補正
0.85~1.00まで0.01刻みの16とおりの数値をかけて小数点以下を切り捨てると、それぞれの結果は、
10975, 11104, 11233, 11362, 11491, 11620, 11749, 11879, 12008, 12137, 12266, 12395, 12524, 12653, 12782, 12912
タイプ一致補正
エースバーンはほのおタイプで、かえんボールはほのおタイプの攻撃技であるため、タイプ一致補正がかかります。
タイプ一致補正1.5倍をかけて、小数点以下を五捨五超入(※)すると、それぞれの結果は、
16462, 16656, 16849, 17043, 17236, 17430, 17623, 17818, 18012, 18205, 18399, 18592, 18786, 18979, 19173, 19368
※五捨五超入とは、小数処理の一種です。小数第1位を五捨五超入する場合、1.45は1になり、1.49999も1になり、1.5も1になり、1.50001は2になり、1.58は2になります。だいたい四捨五入と同じですが、5ぴったりの処理だけ違う(切り捨てる)、という覚え方ができます。
タイプ相性補正
むし・はがね・くさタイプに対してほのおタイプの攻撃技を使っているため、タイプ相性によりダメージが8倍になります。
131696, 133248, 134792, 136344, 137888, 139440, 140984, 142544, 144096, 145640, 147192, 148736, 150288, 151832, 153384, 154944
ダメージ補正計算中1
メトロノームを持ちながら同じ技を6回連続で使うことによるダメージ2倍の効果と、非接触炎技を特性もふもふのポケモンが受けることによるダメージ2倍の効果が入ります。
ダメージが4倍になります。
ここで、重要なポイントがあります。この4倍にするという操作を、ポケモンのダメージ計算では、厳密には、16384をかけて4096で割るという処理により行っています。
まずは、16384をかけると、こうなります。
2157707264, 2183135232, 2208432128, 2233860096, 2259156992, 2284584960, 2309881856, 2335440896, 2360868864, 2386165760, 2411593728, 2436890624, 2462318592, 2487615488, 2513043456, 2538602496
いずれも、2の31乗(=2147483648)以上です。
ダメージ補正計算中2
ここで、オーバーフローが起きます。符号付き32bitオーバーフローにより、2の31乗以上2の32乗未満の数は、その数から2の32乗を引いた数として扱われます。この操作をすると、それぞれの数値はこうなります。
-2137260032, -2111832064, -2086535168, -2061107200, -2035810304, -2010382336, -1985085440, -1959526400, -1934098432, -1908801536, -1883373568, -1858076672, -1832648704, -1807351808, -1781923840, -1756364800
ダメージ補正計算中3
負の整数が現れても、そのまま計算が進行します。16384をかけたので、4096で割ります。すると、それぞれの数値はこうなります。
-521792, -515584, -509408, -503200, -497024, -490816, -484640, -478400, -472192, -466016, -459808, -453632, -447424, -441248, -435040, -428800
0→1処理
タイプ相性以外でダメージが0になっていた場合、ここでダメージが1になります。
しかし、0のダメージを1にする処理はあっても、負の整数のダメージを1にする処理はないようです。
よって、数値はそのままで、こうなります。
-521792, -515584, -509408, -503200, -497024, -490816, -484640, -478400, -472192, -466016, -459808, -453632, -447424, -441248, -435040, -428800
16bitダメージオーバーフロー?
過去の本編のダメージ計算であれば、ここまでの処理で、数値は正の整数になっています。そして、その数値が65536以上であれば、符号なし16bitダメージオーバーフローによって、0~65535の範囲の整数になります。
今回、ここはどうなるでしょうか。ここの処理について、筆者の英語の聞き取りが正しければ、動画内で触れられてはいませんでした。
仮に、符号なし16bitダメージオーバーフローの型に収める処理が入るとすると、数値は、次のようになり、なんと、これがバトルログ上のHPの変化と一致します。太字のものが実際に一致している数値です。
2496, 8704, 14880, 21088, 27264, 33472, 39648, 45888, 52096, 58272, 64480, 5120, 11328, 17504, 23712, 29952
(なお、これらの数値は、0~65535の範囲になるまで65536を足し続けることで求められます(あるいはmod 65536) )
結果
正のダメージが攻撃対象のHPを減らすなら、負のダメージは、攻撃対象のHPを増やします。
符号なし16bitダメージオーバーフローの型に収まったのなら正のダメージになっているのでは?という疑問は残るものの、実際に起こったことを見るかぎりでは負のダメージの扱いのままになっているようで、ゲンガーのHPが回復します。
バトルログの表示のための処理と実際の処理がどこかで分岐していて、上記の0~65535の範囲に収まる現象は前者にだけ起きる、ということなどが考えられます。
実験2(つけあがる) 計算
実験2についても、計算します。
補足事項は実験1と同じなので、一部は省略します。
最終威力
つけあがる 能力ランク上昇が32段階であるため、威力は20+20*32=660
てだすけ1回 660*1.5= 990
最終威力 990
最終こうげき
ゴロンダ 元々のこうげき実数値は192
こうげきランク+6 192*4 = 768
ヨガパワー 768*2 = 1536
最終こうげき 1536
最終ぼうぎょ
ピカチュウ 元々のぼうぎょ実数値は54
ぼうぎょランク-6 54/4= 13.5 小数点以下切り捨てで13
最終ぼうぎょ 13
基礎ダメージ
( 22*威力*こうげき/ぼうぎょ )
= ( 22*990*1536/13 )
= 2573390.769...
小数点以下切り捨てで2,573,390
( 22*威力*こうげき/ぼうぎょ ) /50 +2
= 2573390 /50 +2
= 51467.8+2
= 51469.8
小数点以下切り捨てで 51469
乱数補正
0.85~1.00まで0.01刻みの16とおりの数値をかけて小数点以下を切り捨てると、それぞれの結果は、
43748, 44263, 44778, 45292, 45807, 46322, 46836, 47351, 47866, 48380, 48895, 49410, 49924, 50439, 50954, 51469
タイプ一致補正
ゴロンダはあくタイプで、つけあがるはあくタイプの攻撃技であるため、タイプ一致補正がかかります。
タイプ一致補正1.5倍をかけて、小数点以下を五捨五超入(※)すると、それぞれの結果は、
65622, 66394, 67167, 67938, 68710, 69483, 70254, 71026, 71799, 72570, 73342, 74115, 74886, 75658, 76431, 77203
タイプ相性補正
エスパー・ゴーストタイプに対してあくタイプの攻撃技を使っているため、タイプ相性によりダメージが4倍になります。
262488、265576、268668、271752、274840、277932、281016、284104、287196、290280、293368、296460、299544、302632、305724、308812
ダメージ補正計算中1
メトロノームを持ちながら同じ技を6回連続で使うことによるダメージ2倍の効果が入ります。ダメージが2倍になります。この2倍にするという操作を、ポケモンのダメージ計算では、厳密には、8192をかけて4096で割るという処理により行っています。
まずは、8192をかけると、こうなります。
2150301696, 2175598592, 2200928256, 2226192384, 2251489280, 2276818944, 2302083072, 2327379968, 2352709632, 2377973760, 2403270656, 2428600320, 2453864448, 2479161344, 2504491008, 2529787904
いずれも、2の31乗(=2147483648)以上です。
ダメージ補正計算中2
ここで、オーバーフローが起きます。符号付き32bitオーバーフローにより、2の31乗以上2の32乗未満の数は、その数から2の32乗を引いた数として扱われます。この操作をすると、それぞれの数値はこうなります。
-2144665600, -2119368704, -2094039040, -2068774912, -2043478016, -2018148352, -1992884224, -1967587328, -1942257664, -1916993536, -1891696640, -1866366976, -1841102848, -1815805952, -1790476288, -1765179392
ダメージ補正計算中3
負の整数が現れても、そのまま計算が進行します。8192をかけたので、4096で割ります。すると、それぞれの数値はこうなります。
-523600, -517424, -511240, -505072, -498896, -492712, -486544, -480368, -474184, -468016, -461840, -455656, -449488, -443312, -437128, -430952
0→1処理
数値はそのままです。
-523600, -517424, -511240, -505072, -498896, -492712, -486544, -480368, -474184, -468016, -461840, -455656, -449488, -443312, -437128, -430952
16bitダメージオーバーフロー?
仮に、符号なし16bitダメージオーバーフローの型に収める処理が入るとすると、数値は、次のようになり、なんと、これがバトルログ上のHPの変化と一致します。太字のものが実際に一致している数値です。
688,6864, 13048, 19216, 25392, 31576, 37744, 43920, 50104, 56272, 62448, 3096, 9264, 15440, 21624, 27800
急所のときは、下から6つ目の乱数の結果が47352になるので、急所に出たときの結果とも一致しています。
結果
実験1と同じようになぜ負のままなのか分かりませんが、実際に起こったことを見るかぎりでは負のダメージの扱いのままになっているようで、ピカチュウのHPが回復します。
より詳しい情報
海外のポケモン対戦コミュニティサイトである「Smogon」に、動画を投稿したDaWoblefetさんが今回のことを投稿しています。
Research - Champions Battle Mechanics Research | Page 11 | Smogon Forums
数値設定やダメージ補正適用までの計算などの記載があり、自分で計算した結果とずれていないことを確認しました。
実験2の亜種の記載もありました。ゴロンダのこうげき実数値を下げて、ダメージ補正前のダメージを221472~260560にしたところ、負のダメージは確認できなかったそうです。260560に8192をかけても、2,134,507,520で、2,147,483,648より小さいです。オーバーフローは起きず、値がそのまま次の計算(4096で割る計算)に使われます。
それから、最終的なダメージが32768以上65536未満のときに負のダメージが発生しないことから、符号付き16bitオーバーフローは発生しないようであるということも書かれていました。
未解決事項
バトルログ上の数値の表記については、前の項で紹介したDaWoblefetさんの投稿では、これらの数値がどこから来ているのか分からないと書いてありました。
本記事にて、とりあえず、数値の変化量とダメージ計算の間に関係を見出すことができたので、そこは一歩前進です。
(あとでDaWoblefetさんに伝えようと思います。)
ただ、「符号なし16bitに関係する数値がバトルログに記録されていて、正のダメージが発生していそうであるのに、実際には負のダメージが発生しているかのようにポケモンが回復する」という事象をうまく説明する方法は、まだ見つかっていません。
「バトルログの表示のための処理と実際の処理がどこかで分岐していて、上記の0~65535の範囲に収まる現象は前者にだけ起きる」という仮説は立てたものの、自分でもそういうことでいいのか信じ切れていません。
ここは今後の課題です。
<追記:他の人の意見>
貴重な日本の有識者仲間からありえそうな意見をもらえました。
類似の事象
ポケモンチャンピオンズでは、基本のバトルシステム自体はこれまでのものを踏襲しているものの、数値処理の面でいくつかの違いがあることは、他にも発見されています。
リリース直後に、以下のとおり、トリックルーム中の行動順処理が変わっていることを確認しています。
tetspond.hatenablog.com
おわりに
約1.5万字のかなり長めの記事になりました。
お読みいただきありがとうございました。
ポケモンのオーバーフローに関しては、日本国内に数人しかいない有識者の一人であるという自意識があり、その役割を果たせたと思います。
「オーバーフロー」のカテゴリの記事は自慢の記事がいろいろあるので、こちらをどうぞ!
tetspond.hatenablog.com
DaWoblefetさんに感謝を述べて、この記事を終わります。ありがとうございました。
記事一覧:https://tetspond.hatenablog.com/archive
Twitterアカウント
テツポンド (@tetspond) | Twitter
サムネイル用

ぼうぎょ最低ピカチュウ