プラグインの不正なレコードが原因でCTDするのをなおす

環境構築

Buffout 4を使うとCTDの原因を特定できることがあります。

CTDしたらクラッシュログを確認する

クラッシュログは以下の場所に生成されます。

C:\Users\<ユーザー名>\Documents\My Games\Fallout4\F4SE

開いてみると、さまざまな情報が書かれています。Buffout 4の設定や、CTDした直前のデータ構造、プラグインの一覧などです。

一番上に直接の原因があります。

crash-2020-10-10-07-53-23.log (text)

v1.16.0

Unhandled exception "EXCEPTION_INT_DIVIDE_BY_ZERO" at 0x7FF77830320E

実際にタイトル画面でCTDしてしまう時のものです。0で割り算をしたので例外が発生したとあります。

例外は要するにCTD、0で割り算とは、数字を0で割ってはいけないのにしてしまったということです。

問題のプラグインを特定する

これだけだとなんだかわりませんが、下の方に進んでいくと、問題を起こしているレコードが判明します。

crash-2020-10-10-07-53-23.log その2 (text)

STACK:
    [RSP+0 ] 0x267E1421C90 (void*)
    [RSP+8 ] 0xCD6709F3C9 (void*)
    [RSP+10 ] 0x267E13D4740 (ExtraRagDollData*)
    [RSP+18 ] 0x0 (size_t)
    [RSP+20 ] 0x64 (size_t)
    [RSP+28 ] 0x7FF7781A2C39 (void* -> Fallout4.exe+0082C39)
    [RSP+30 ] 0xCD6709F3C9 (void*)
    [RSP+38 ] 0x267E13D4740 (ExtraRagDollData*)
    [RSP+40 ] 0x267E13D46A0 (void*)
    [RSP+48 ] 0x0 (size_t)
    [RSP+50 ] 0x0 (size_t)
    [RSP+58 ] 0x7FF77B7EB140 (type_info*)
    [RSP+60 ] 0x6 (size_t)
    [RSP+68 ] 0xCD6709F489 (void*)
    [RSP+70 ] 0x267D95FDCB0 (BSFile*)
    [RSP+78 ] 0x7FF779C75AC3 (void* -> Fallout4.exe+1B55AC3)
    [RSP+80 ] 0x267D95FDCB0 (BSFile*)
    [RSP+88 ] 0xCD6709F408 (void*)
    [RSP+90 ] 0x64 (size_t)
    [RSP+98 ] 0x0 (size_t)
    [RSP+A0 ] 0x2673CB1C8D0 (void*)
    [RSP+A8 ] 0x26858EFEEC0 (void*)
    [RSP+B0 ] 0x267D95FDCB0 (BSFile*)
    [RSP+B8 ] 0x8BC (size_t)
    [RSP+C0 ] 0x2673CB1C8D0 (void*)
    [RSP+C8 ] 0x267E1423CB0 (TESObjectREFR*)
        File: Z_Horizon_Loot_Respawn.esp
        Flags: 0x40200000
        Form ID: 0x001AD268
    [RSP+D0 ] 0x0 (size_t)
    [RSP+D8 ] 0x7FF7782517D3 (void* -> Fallout4.exe+01317D3)
    [RSP+E0 ] 0x267E1423CB0 (TESObjectREFR*)
        File: Z_Horizon_Loot_Respawn.esp
        Flags: 0x40200000
        Form ID: 0x001AD268
    [RSP+E8 ] 0x9C0 (size_t)

どうやらZ_Horizon_Loot_Respawn.espで定義されているフォームの0x001AD268を処理している最中だったようです。

ExtraRagDollDataというのもヒントになります。

FO4Editで当該レコードを確認してみます。プラグインはすべて読み込みます。

左上のところにフォームIDを入れると探すのが楽です。

レコードのエレメントはこうなっていました。

Z_Horizon_Loot_Respawn.espはHorizonに含まれるパッチのひとつで、物がリスポーンしないようにするためのものです。No Respawnフラグを設定しているのがわかります。

問題はRagdoll Dataです。わかりにくいですが、HorizonはUOF4Pに対応していないので、レコードがバニラに巻き戻るのですが、それを自作のxEditスクリプトを書いて、反映させたところです。

バニラはRagdoll Dataが設定されています。UOF4Pがそれを消して(remove)います。Horizonはバニラ同様の値に設定されていました。それを消した(空データ)わけです。

Removeでデータそのものを無くすのと、データの中身を空にするのでは処理が違ってきます。

Fallout 4のゲームエンジンは、Ragdoll Dataが存在するときは中身から空であっても処理を行い、中身が空のときは0として扱うので、その結果0で割り算をしてしまう、ということのようです。本来であればRagdoll Dataの中身が空になることはないのでしょう。

というわけで、Ragdoll DataをRemoveしたところ、CTDしなくなりました。

今回は特殊な例でしたが、Buffout 4がないとノーヒントなので、問題を特定するのはかなり難しくなっていたでしょう。

タイトルとURLをコピーしました