『スカイリム』の魔光経験値バグを解説
《上古卷轴5:天际》に長年存在するバグにより、ある呪文が本来よりはるかに多くの経験値を提供できる。Alex Bealsはゲーム内でこれを検証し、その後経験値が実際に付与されるタイミングをリバースエンジニアリングし、背後にある競合状態を突き止めた。
日本語
コピー

2026年10月6日
目次⤴︎
Magelight が経験値を与える仕組み
ゲーム内で検証する
経験値が入るタイミングを逆解析する
衝突はどう機能するのか
何かに当たったとき何が起きるか
投射物を止める
バグを分解する
リターンを最大化するには
安定して再現できる構成ガイド
『Skyrim』には、首都 Solitude の城外に、山頂で Magelight を唱えると大量の Alteration 経験値が得られる場所がある。1 回の詠唱でレベル 15 から 25 まで上がるほどだ。だが、なぜなのか。
なぜ効くのかについては、誤った説明が多く出回っている。主流なのは距離が関係しているという説だ。
「Magelight は飛行時間の長さに応じて、着弾時に経験値を与える。君が見つけたのは、ちょうど描画距離の境界に位置する場所だが、もっと上を狙う方法もある」——@Jewbacca1991
だが他の人々はすぐに、そうではないと指摘した。他の遠距離ではこの手は効かない。この山には何か特別なものがあるらしい。UESP の Skyrim wikiは、原因は見える雲にあると主張している。
「この場所で得られる大量の経験値は、複数の天候エフェクトの平面を通過することに関係しているようだ。」
だが、曇った山はいくらでもあり、そこではこの手は効かない。Magelight の経験値計算式を逆解析して、この件に決着をつけよう。
Magelight が経験値を与える仕組み
Magelight は見習い級の呪文だ。TES5Edit で読み込むと、Magnitude が 5、Duration が 60、基本エフェクトが LightFFAimed、すなわち 0001EA6D であることがわかる。このエフェクトを読み込むと、Base Cost が 2、Skill Usage Multiplier が 0.15 であることもわかる。

呪文 ID、00043323 呪文エフェクト、0001EA6D
これらはすべて Skill Usage 値の計算に使われる。この呪文には Area がないので、式はすぐに簡略化できる。
Alteration XP はこの値を取り、スキル使用倍率(Magelight では 0.15)を掛け、さらにスキル使用乗数(Alteration では 3)を掛けて、1 回の詠唱あたりの生 XP は 37.938 になる。
ゲーム内で検証する
理想的には、壁に向かって Magelight を唱え、期待される XP 量が得られるか確認したい。残念ながら、ゲーム内(コンソールコマンドを使っても)で正確な XP を取得する方法はない。幸い、Cheat Engine を使えば Lua 経由で直接メモリを読める。1 Lua(私が最も好きな、ブラジル石油会社由来の下流プログラミング言語)は覚えているかもしれない——以前の GBA 版ハリーポッター1 の RTA 記事で触れた。
-- (Set the player's Alteration level to 15 with a console command)
-- player.setav alteration 15
-- Set the overflow XP to 0
local ALTERATION = 18
local player = readPointer(0x01B2E8E4)
local skills = readPointer(readPointer(player + 0x614))
local entry = skills + 12 * ALTERATION - 0x40
writeFloat(entry + 4, 0)
print(string.format('Alteration XP: %.3f', readFloat(entry + 4)))
-- <Cast the spell>
-- Read out the current XP
print(string.format('Alteration XP: %.3f', readFloat(entry + 4)))
Lua
コピー
上のスクリプトを実行すれば2 VEH デバッガを使うように変更した。Edit > Settings > Debugger method で設定できるが、必要かどうかはわからない。 XP を 0 にリセットし、Magelight を唱え、最後のステップを実行して新しい XP を読むと、予測どおりに増えているのがわかる。よし!
だが、ここまでの話は距離を一切考慮していない。なぜ得られる XP は 38 よりはるかに多いのか?
XP がいつ付与されるかを逆解析する
Magelight は他のほとんどの呪文と違い、人に当てる必要がない。人に当てても効果はあるが、壁や机、石に向かって唱えても同じように機能する。どの場合でも XP を与えるのだが、では何かに当たったことをどうやって知るのか?
衝突はどう機能するのか
この呪文を唱えると LightSpellProjectile が生成され、最初に狙った位置に基づく経路に沿って飛ぶ。毎 tick、何かと衝突したかどうかをチェックしており、おおまかに次の 3 ステップを踏む。
次の tick でオブジェクトが移動する経路を描画する(0x007A0090)
投射物の速度(512 単位/秒)をフレームレート(60 fps3 そう、古い Xbox 本体でプレイすると衝突判定の頻度は下がり、フレームレートを通常より上げれば頻度は上がる。 Slow Time の竜吼を使ったり、Archery/Block のパークで時間を遅くしたりした場合も同様に上がるが、1 秒あたりの衝突回数は変わらない。 )で割ると \frac{512}{60} = 8.5\bar{3} 単位/tick、方向は詠唱した方向になる。この呪文の射程は 10,000 で、4 これも ESM ファイルで決まるが、上のスクリーンショットの切り抜きには入っていない。おっと。 つまり経路に沿って約 秒飛び続けてから消える。
この経路を、コリジョンを持ちコリジョンレイヤーのフィルタを通過したすべてのオブジェクトと交差判定する。(0x00DE0040)
ゲーム内のすべてのオブジェクトにはコリジョンレイヤーがあり、何と衝突するかが定義されている(例えば L_TRANSPARENT は投射物や呪文を遮らないが、L_TERRAIN は遮る)。両者が一致しなければ衝突は発生しない。

L_TRANSPARENT L_TERRAIN
経路がそのオブジェクトに当たったかどうかを調べる。(0x00EC41C0)
まず、オブジェクト表面上で投射物に最も近い点を見つけ、その最近点における表面から離れる向きの法線を求める。
ここでは直方体で示しているが、岩や城などはもっと複雑な法線マップを持つ
次に、投射物の進行方向が法線方向と一致するかどうかを調べる。5 やり方は内積の符号を見るだけだ。数学万歳! 正なら投射物は表面から離れているので、衝突なしと判定される。向きが逆なら、すでにそのオブジェクトと交差しているか内部にあるか、あるいは次の tick でぶつかる場合に衝突とマークされる。
なお、投射物がすでにオブジェクトの内部にある場合でも法線チェックは先に実行される。オブジェクトの半分以上を貫通していて最近点が遠い側にあり、法線が進行方向と一致していれば、もう衝突は発生しない。
衝突が起きたときに何が起きるか
LightSpellProjectile が何か(複数でも)と衝突すると、衝突ごとに "OnHit" 関数(0x007A30FD)が実行され、本来起きるべきことが起きる。この関数は Magelight6 とは関係のない多くの処理を担っている。例えば wards が 0x006ECE30 で呪文を遮ったり、ターゲットが 0x006E99D0 で Destruction 呪文に吹き飛ばされたりする。だが最終的には、効果を人7 に——厳密には magic target で、アクティベーターなども含まれる(0x00664740)——適用するか、衝突した表面に適用する。ほとんどの単発詠唱呪文は person 側の分岐で XP 報酬を処理するが、0x00660353 に特別なチェックがあり、Magelight のように代替ターゲットに作用する呪文に XP を与える。8 実は Magelight は例えばではなく、まさに Magelight だ。厳密にはすべての Reanimate と Light 呪文が該当するが、Reanimate 呪文はすべてこの位置を上書きし、死体を蘇生した時点で直接 XP を与える。もう一つの Light 呪文 Candlelight は投射物ではない。
最後に "OnHit" は 0x007A2560 でヒット効果を適用する。自身が一度だけ実行されることを保証し、命中したマテリアルを調べて以降の挙動を決める(例えば人に付着する、壁なら壁のそばに浮かぶだけ、など)。マテリアルがない、あるいは未対応のマテリアルならヒットイベントは発生しない。

投射物を止める
ここまで説明したことはすべて正常に動くように見えるし、実際ほとんどの場合は動く。だが問題はここにある。何かと衝突して "OnHit" を実行した後、コードは "HandleHit" 関数を呼び、投射物が飛び続けるべきかどうかを判断する。通常は投射物を停止させるが、例外が二つある。1)非実体オブジェクトに当たった場合は飛び続ける⁹。より正確には、Havok の衝突コードにある BROAD_PHASE_PHANTOM で、トリガー(「ここに来たら罠/カットシーン/会話を起動する」といったもの)に使われる。このチェックは 0x0079f022 にある。2)レイヤータイプ 26 または 28 のオブジェクトに当たった場合で、それぞれ L_TRANSPARENT_SMALL と L_TRANSPARENT_SMALL_ANIM に対応する¹⁰。興味本位未来の自分が証拠を探しているなら、この例外判定は 0x0079f063 にある。

L_TRANSPARENT、L_SPELL とは衝突しない L_TRANSPARENT_SMALL、L_PROJECTILE と L_SPELL には衝突する
L_TRANSPARENT_SMALL はそのコリジョンレイヤーで投射物や呪文と「衝突する」ため、この表面は衝突を登録し続けるのに投射物を止めない。ここでバグが発生する。
Bug の解剖
Magelight を、L_TRANSPARENT_SMALL のバウンディングボックスに入るまで撃ち続ける。そのコリジョンレイヤーは L_SPELL と衝突するので、衝突としてカウントされる。人でも呪文ターゲットでもないので fallback 経路を通り、38 ポイントの経験値を与える。しかし L_TRANSPARENT_SMALL は "HandleHit" の対象外なので、投射物は飛び続ける。次の tick でも同じことが起きる。バウンディングボックス内にあるので衝突としてカウントされ、38 ポイントの経験値が与えられる。最近点の法線が進行方向と一致するまで、つまりおおよそ半分を貫通するまでこれが続く。
だが、その L_TRANSPARENT_SMALL の物体は一体どこにあるのか。予想どおり、Solitude の隣にあるあの山だ。11 Ï Skyrim Creation Kit で手早く mod を作り、壁を表示させてみた。ただし .esm を直接編集し、コリジョンレイヤーにデバッグ用の色を付けるだけでも同じ結果が得られる。
他の場所にもある。たとえば High Hrothgar の両脇:
あるいは Thieves' Guild クエストラインの最後、Irkngthand の像の周囲:
Thalmor Embassy の外側にある極薄の平面などもそうだ。
だが最も大きな塊は Solitude の隣にある。だから呪文を撃つべきはあの山であって、遠くにある霧がかった山ならどれでもいいわけではない。
どう最大化するか
ほとんどの攻略記事は山頂を狙えと言うが、本当に狙うべきは、呪文が L_TRANSPARENT_SMALL ブロックを通過する時間が最も長くなる線だ(しかも正しい領域を通ること)。山頂は悪くないが、もっと上がある。12 山頂ではおよそ ~280 回しか発動しないが、最適な位置なら ~850 回に達する。

Ï すぐに13 本当にすぐだ。Claude Opus 5.5 はわずか約 10 分で、スクリーンショット 1 枚だけから問題の在り処を突き止め、mod を 2 回書くだけで完成させた。 SKSE で mod を書き、不可視の壁をレンダリングし、狙っている位置に応じて予想 XP 発動回数と XP 収益を最大化する最適角度をリアルタイムで計算するようにした。近くを一周するだけで最適位置がすぐ見つかる。14 大量の計算でもあの「最適」位置は導き出されたが、それは下にあり、入れない。完璧だ。

フォントの選択がほぼ読めない
Alteration レベル 15 から 100 まで上げるには、 = 528,804.0234 XP が必要だ。1 回の発動で 37.938 XP、つまりほぼ 14,000 回の発動となる。だから 1 本の線で 250 回発動するか 850 回発動するかの違いは、55 回の詠唱か 17 回の詠唱かの違いになる。だが鍵は安定して再現できることだ——「空のこの点を狙え」と言うだけでは意味がない。他の人には到底真似できない。というわけで、以下が実行可能なガイドだ!
安定ポジションガイド
まず Solitude にファストトラベルし、正面門から出る。するとちょうど門の外に立つことになる。次に、左側の岩場を登る。そこに不可視の壁が 1 枚あるので、それに張り付いて立ち、同時に最も遠い角の城壁にもたれかかる。

狙うのは、張り付いている壁の左上角のレンガのモルタル目地だ。

正しい角度を見つけるには、しゃがみ、照準の中心をそのモルタル目地に合わせる(最適なのは右側のレンガの左上角