動的生成の罠

Mod作成

スクリプトを使うとゲーム内で動的に何かを作り出すことができます。

マーカーを動的に生成する

マーカーを動的生成する例 (papyrus)

Form Property XMarker Auto

Function CreateNewMarker()
    ObjectReference kObject = Game.GetPlayer().PlaceAtMe(XMarker)
    Debug.Trace( "created xmarker = " + kObject )
EndFunction

生成されたリファレンスはフォームIDが0xFFから始まります。

[10/19/2020 - 06:55:44PM] created xmarker = [ObjectReference < (FF0121EC)>]

0xFFというのはセーブデータに保存されるフォームです。

Fallout4.esmの0x00にはじまり、追加されたプラグインが0x01、0x02、0x03と使われていき、セーブデータの0xFFまで、全部で256個のプラグインが使えるわけです。

セーブデータは常に0xFFです。セーブデータのフォームは最優先ということです。

1個のプラグインに使えるフォームIDは0x000000から0xFFFFFFまでです。セーブデータの場合は0xFF000000から0xFFFFFFFFまでとなります。おそらくですが、使い切るとフォームIDが0xFF000000に戻ってループします。

0xFFFFFFは約43億なので、使い切ることなんてないと思いますが、実は綺麗に使い切るわけではなく、いつの間にか値が戻ったりします。状況で使われるIDの範囲が変化するのかもしれません。

さきほどのサンプルコードではマーカーを作りました。しばらくの間であれば問題ありません。ところがプレイ日数が数日経過すると、いつのまにか他のフォームにIDを使われてしまい、上書きされるということが起こります。すると期待通りに動かなくなります。

Paryrusではこのように表示されます。

[ObjectReference < (None)>]

ObjectReferenceではあるが、IDがないのでNoneになっているということです。

その場で生成してすぐに削除するのであればOKですが、ずっと使い続けるのであれば、ゲーム内での動的生成はやめて、CKでフォームを作り、それを使うようにします。

その後の調査でわかったこと

Wikiの解説によると、abForcePersistという引数があるので、これをtrueにするといいかもしれません。persistは永続という意味なので、ゲーム内で常にロードされた状態になり、respawn処理の対象外になるということだと思います。

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