Elin界隈の話を聞くとしばしば耳にする、”オーバーフロー”と、なぜ発生しているかについて解説します。
オーバーフローの基礎知識
- ゲーム内で一般的に使われている変数はint型
- int型の最大値はマイナス約21億4700万~約21億4700万(-2,147,483,648 ~ 2,147,483,647)
- 計算中、あるいは計算後にint型の上限を超えるとプラスマイナスが反転する
- 例:マイナス21億4700万 から更にマイナスするとプラス21億に
詳しい仕組みについては”int型 最大値”とかで検索するとゲームオタクの先人達が解説してくれているはずなのでここは省きます。
なんでオーバーフローが発生するの?
Elinの実装上のオーバーフローの話をしていきます。
数値を盛りすぎて発生
Elinの現在のダメージキャップは攻撃評価1億、実ダメージ9999万9999ですが、ダメージ修正や全特攻、反魔法粒子が大量に乗った攻撃をすると純粋に数値が大きすぎて21億を超えます。
ダメージ計算式を理解し、最大ダメージを叩こうとしてセットアップすると、100万階層ぐらいでダメージがオーバーフローして0ダメージ化します。(3敗)
全特攻8000が罠だなんて夢にも思わないよね。
人によっては60億ダメージを出すことで一周回って正常なダメージに戻したりするらしいです。
計算処理中の事故
A.内部で計算処理をする際、*110 /100 のような処理をして21億を超える
ゲームコード上では、以下のような書き方で倍率系の計算をします。
例:商人ギルドLv6の商店規模へのボーナス
店の規模 * 110 / 100
110をかけた後に100で割ることで1.1倍にするという処理の書き方です。
int型は小数点以下を扱うのが苦手なので(誤差が出る)、店の規模 * 1.1 とは書けず、ゲーム業界では昔から100以上の数で掛けてから100で割る方法で割合ボーナスを実装する習慣があるようです。
この際、計算中にint型の最大値を超えてしまうとオーバーフローが発生します。
Elinのコードを見た感じはオーバーフローが特に発生しやすい部分はlong型で宣言して対策したり(int型より扱える桁数が多い)、オーバーフローした場合はプラスに戻すようにしたり対策していますが、修正が完全には追いついていない状況です。
例えば勤勉拠点に釣りLv10万のNPCを配置して釣りさせると何も生産しなくなったり、店の規模への投資は1900万でオーバーフローしたり、重量の上限が10000sみたいなのはこのあたりのオーバーフロー関連の仕様や制限によるものです。
狙って発生
int型の仕組み上の問題なので、狙って発生させる悪い人たちも存在します。
例えば反転魅力シャンパンコールやOF窃盗金策は簡単に使えるオーバーフロー技ですし、ルビナス装備を錆びさせまくったものを複製して生命力を+21億にしたり(HP10億シルバーベル)、エヘカトル短剣を錆びさせまくってファクション+21億魅力にしたりといった使い方がされています。
じゃあ、なんでlong型にしないの?
A.うーん?
int型の倍の桁数を扱えるlong型の変数に置換していくことで約21億でのオーバーフローは避けられます。
int型の上限は約21億ですがlong型の上限は約9.22京です。
ゲームコードを見ても、要所要所はlong型で宣言したりキャストすることでオーバーフロー対策を施しています。
なので、シロウトの考えでは「全部long型にすればいいじゃん!」なのですが、そうならない理由があるはずです。
というわけで、以下は、業界人のN君に聞いてきたlong型ではなくint型のままゲームを実装する、考えられる理由です。
- セーブデータの肥大化:int型からlong型への移行で保存に必要な容量が増加します。(全long化したら単純に2倍)
- セーブデータの互換性確保:これもint型からlong型に移行する際に何れかの不具合が発生する可能性があるようです。
- 処理の低速化:現代のPCではそうそう起こり得ないらしいですが、処理するデータ型が変わると処理の低速化を招く可能性があるようです。現状でも多刀ペットで斬撃無双すると処理落ちしたりするので結構致命的かも。
- 習慣的に:諸々の理由で昔からのコーダーは習慣的にint型で宣言しているようです。
N君曰く「習慣的なモノじゃないの?」との意見でしたが、”処理の低速化””セーブデータの互換性”あたりが主な理由になるでしょうか。
~200時間程度の一般的なプレイではオーバーフロー関連にたどり着くことはないので、対策や対処が後回しになるのは当然とも言えるでしょう。

コメント
コメント一覧 (1件)
そこら辺の変数は何となくintに宣言するのありですね