Papyrusログに MHP_ConfigQuest のスタックが溜まって落ちる人へ
私的経緯
例えば歩いているだけで錬金素材が集まるMOD
なんかを入れていると、
「持てるだけ持ち歩いて後でまとめて錬金しよう」とか思うわけです。
持ち歩ける重量が多ければ多いほど、のちのち「山の青い花 (280)
」とかになる。
ちなみに私が愛用させてもらっているのはこちら。
当然300
回近く R
キーを押すなんて人間には至難の業で、
漏れそうな下を必死こいた気分で我慢しながら駅のトイレのドアを叩くような事態に陥るよりも、
きっとこういう連打ツールを使いたくなるはずなのです。
しかし使ってみるとわかるんですが、人智を超えたスピードでアイテムが作成されるため
Papyrus
スクリプトエンジンには途方も無い負荷がかかります。
いや、本来は(多分)スクリプト関係ないんだけど、MOD
によってはあるようで。
MHP = More HotKeys Please
タイトルにある MHP_ConfigQuest
は比較的有名かつ高機能なホットキーMOD
である*1
に含まれている MHP_PlayerScript.psc
に含まれているものです。
上記ブログで言及されているように、More HotKeys Please
(以下MHP
)は
インベントリへのアイテムの追加、およびアイテムの削除をモニタリングしているので、
一度の錬金につき「一つ目の材料削除」「二つ目の材料削除」(オプション材料削除)「薬の追加」という
少なくとも合計3
つ以上のイベントが同時に発生することになります。
原因はスクリプトの過負荷
さらにそのイベント内で深くネストされたIf - EndIf
とWhile - EndWhile
ブロックが大量にあって、
Papyrus
コード的には結構な負荷がかかります。落ちても仕方がないレベルと言ってもいいです。
これはホットキーにポーションを選択したときの<mag>
を計算している――
つまり同じ名前の薬のうちどれを優先的に使用するかの判断をしているわけですが、
個人的に薬は[http://skyrim.2game.info/detail.php?id=29512:title=SwiftPotionReborn]
を使っているのであんまり必要ありません。
ので、とにかく落ちないようにするためにスクリプトを書き換えてみました。
需要があればコンパイル済みの MHP_PlayerScript.pex
もどこかに置きますが、
MHP
の作者さんに申し訳が立たないので多分やりません。コードのみ。
スクリプトの書き換え準備
バージョンは More HotKeys Please v3.0
です。
必要なもの:
[http://skyrim.nexusmods.com/mods/23416/?:title=MHP]
スクリプトのソース。デフォルトでData\Scripts\Source\
に展開済み。[http://skyrim.nexusmods.com/mods/3863/?:title=SkyUI]
スクリプトのソース。デフォルトでは展開されないので、[http://wiki.skyrim.z49.org/?MOD%2FTool#bsaunpacker:title=BSA Unpacker]
を使って取り出し・配置すること。[http://skse.silverlock.org/:title=SKSE]
スクリプトのソース。インストーラを使った場合は展開されていないので、アーカイブからData\Scripts\Source
に放り込む。[http://wiki.skyrim.z49.org/?MOD%2FTool#h952bf0b:title=Creation Kit]
スクリプトのコンパイルに Creation Kit
本体は使いません。
くっついてくる Papyrus Compiler
というものを使います。
\SteamApps\common\Skyrim\Papyrus Compiler
に存在が確認できるはず。
無ければそこはプレイ用のSkyrim
フォルダなので、Creation Kit
をインストールしたフォルダを漁りましょう。
発見できたら、デスクトップとか適当なところに簡単な .bat
ファイルを作ります。
ドラッグ&ドロップでスクリプトをコンパイルしてくれる親切設計ですが、
CK
をインストールしたフォルダとプレイ用 Skyrim
フォルダを把握しておく必要があります。
が、今回は同一フォルダにインストールされているものとしましょうね。*2
compile_pupyrus.bat:
"D:\SteamLibrary\steamapps\common\skyrim\Papyrus compiler\PapyrusCompiler.exe" %1 -f="TESV_Papyrus_Flags.flg" -i="D:\SteamLibrary\steamapps\common\skyrim\data\scripts\source" -o="D:\SteamLibrary\steamapps\common\skyrim\Data\Scripts" pause
D:
ドライブの直下にSteam
ライブラリフォルダがあると仮定します。
場合によっては C:\Program Files(x86)\Steam\steamapps\...
のようになっている可能性もあります。
PapyrusCompiler.exe
は第一引数にスクリプトもしくはフォルダを取り、
-i
にソーススクリプトの場所を指定、 -o
にコンパイル済みスクリプトの出力先を指定するようです。
-f
引数についてはよくわかりませんが、あまり深く触らないほうが良さそうなのでおまじない。
スクリプトの改竄
MHP_PlayerScript.psc
をどこか適当なところ(やはりデスクトップとか)にコピーし、適当なエディタで開きます。
このとき Data\Scripts\Source
にあるものを直接編集してしまうとオリジナルが行方不明になるので、
確実にコピーを取るようにしてください。
それから次の行を探します。
Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)
Event OnItemRemoved(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer)
v3.0
では81
行目、174
行目にありました。
見付けたらそれぞれ2
箇所編集します。 ;
記号から後ろはコメントとみなされて無視されますが、
日本語が入っているとコンパイルに失敗する可能性があるかもです。
まずは MHP_PlayerScript.psc: (OnItemAdded付近)
Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer) If akBaseItem.gettype() == 46 If Writer.PotionEffects.length < 58 Writer.PotionEffects = New MagicEffect[58] int i = 0 ; この下をいじくる ; while i < Writer.PotionEffects.length ←コメントアウト while i < 0 ; 追加 Writer.PotionEffects[i] = writer.MHP_AlchEffects.getat(i) as MagicEffect i += 1 endwhile endif potion tempPotion = akBaseItem as Potion int count = tempPotion.getnumeffects() int j = 0 ; この下もいじくる ; while j < count ←コメントアウト while j < 0 ; 追加
それぞれ 0
を指定するとポーションの使用に支障をきたす可能性があるので、
必要に応じて数値を変更してください。具体的な目安はわかりませんが、5
から10
など。
数値が大きくなればなるほど負荷が大きくなります。
逆に 0
を指定した場合はループが一切回らなくなるので、負荷はほとんどかからなくなります。
続いて OnItemRemoved
ですが、こちらも同じようなコードを2
箇所変更します。
作用・副作用については上記と同じ。
MHP_PlayerScript.psc: (OnItemRemoved付近)
Event OnItemRemoved(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer) If akBaseItem.gettype() == 46 && player.GetItemCount(akBaseItem) <= 0 If Writer.PotionEffects.length < 58 Writer.PotionEffects = New MagicEffect[58] int i = 0 ; この下をいじくる ; while i < Writer.PotionEffects.length ←コメントアウト while i < 0 ; 追加 Writer.PotionEffects[i] = writer.MHP_AlchEffects.getat(i) as MagicEffect i += 1 endwhile endif potion tempPotion = akBaseItem as Potion int i = 0 ; この下もいじくる ; while i < Writer.KeyForm.length ←コメントアウト while i < 0 ; 追加
コンパイルと設置
あとはもうコンパイルするだけです。
といっても簡単で、先ほど改竄した MHP_PlayerScript.psc
を compile_pupyrus.bat
にドラッグ&ドロップするだけ。
コンパイルに必要なファイルが自動的にロードされ、即座にコンパイルが始まります。
Starting 1 compile threads for 1 files... Compiling "MHP_PlayerScript"... Starting assembly of MHP_PlayerScript 0 error(s), 0 warning(s) Assembly succeeded Compilation succeeded. Batch compile of 1 files finished. 1 succeeded, 0 failed.
こんな感じの文字が表示された黒いウィンドウが出るはずです。
もし Batch compile of 1 files finished. 0 succeeded, 1 failed.
と表示されている場合は
コンパイルに失敗しているので、必要なファイルがあるかどうか確認してください。
SKSE, SkyUI
のスクリプトのソースが展開されているかどうか、
compile_pupyrus.bat
に記述されている -i=
のフォルダが正しいかどうか、などです。
Batch compile of 1 files finished. 1 succeeded, 0 failed.
と表示されていれば成功しているので、
何か適当なキーを押すか、右上の☓ボタンでウィンドウを閉じてしまって大丈夫です。
確認
さて実際にスクリプトが更新されたのかどうかですが、
Data\Scripts
フォルダを開いて日付順に整列させればすぐに分かります。
直近に更新されたファイルが MHP_PlayerScript.pex
になっていれば成功です。
もしそうでなければコンパイルに失敗しているか、
どこか別のところにスクリプトが出力されている可能性があります。
compile_pupyrus.bat
の -o=
のフォルダを確認してみてください。