スカイリムMOD導入ガイド: playthrough中のMOD互換性を確保する方法

プレイ中に導入・更新可能なSkyrim MODを作るには

プレイ中の互換性の重要性

Skyrimのプレイヤーは、1つのセーブデータに数百時間、数千時間をかけることさえある、その熱心さで知られています。そのようなプレイヤーに、あなたのMODを体験するため、あるいはアップデートのために、新規ゲームを始めることを要求することは、大きな障害となりかねません。ユーザーの視点から見ると、最初からやり直すことは、数え切れないほどのプレイ時間の損失を意味し、場合によってはあなたのMODを完全に諦めてしまうことにもなりかねません。

このガイドは、特にCreation KitとMOD制作の基本知識を持つMOD制作者向けに書かれています。ここでは、MODをプレイ中にインストールまたは更新できるようにするためのテクニックを実装する方法を探り、ユーザーにとってよりスムーズで楽しい体験を保証します。

アップデートとインストールへの対応

プレイ中の互換性を実現するための鍵は、MODの更新時や初回インストール時に、スクリプト、クエスト、オブジェクト参照をどのように管理するかを理解することです。これらのシナリオは同じ原則を共有しているため、ここでは一緒に説明します。

タイミングが全て:ロジックの実行

  • OnInitイベント: 簡単な方法は、アップデート/インストール専用に設計された新しいクエスト内でOnInit関数を使用することです。このクエストは、Creation Kitのクエストデータタブで「ゲーム開始時に有効」に設定する必要があります。スクリプトタブからこのクエストにスクリプトを添付し、OnInit関数内にアップデート/インストールのコードを記述します。

  • OnPlayerLoadGameイベント: アップデートの場合、OnPlayerLoadGameイベントが代替手段となります。エイリアスタブでエイリアスを作成し、それをプレイヤーを参照するように強制し、このエイリアスにスクリプト(ReferenceAliasスクリプトを拡張したもの)を添付します。OnPlayerLoadGame関数内にアップデートのロジックを実装します。このイベントは、新しいクエストの初期化時ではなく、セーブデータのロード時にのみトリガーされることに注意してください。ただし、OnInitはこのエイリアススクリプトのクエスト開始時にも実行されます。

  • OnCellAttachイベント: GetDistanceFindClosestReferenceOfAnyTypeInListFromRefなど、一部の関数はロードされたObjectReferenceを必要とします。アップデート/インストールのロジックがこれらに依存する場合は、OnCellAttach関数を使用します。

スクリプトの謎を解く

スクリプトは、プレイ中の互換性を懸念するMOD制作者にとって、しばしば不安の種となります。しかし、スクリプトがセーブ処理中にアクティブに実行されている場合(これはまれです)を除き、そのコードと実行状態は保存されません。スクリプトは通常、特にRegisterForSingleUpdateOnUpdateを使用してUtility.Waitの代わりに長い遅延を実装している場合は、すぐに実行されます。

主な懸念は、保存されるスクリプトのプロパティとインスタンス変数にあります。幸いなことに、これらは管理可能です。

  • プロパティ: Papyrusを使用して、値を直接目的の状態に設定します。

  • インスタンス変数: これらはスクリプトにプライベートであるため、更新するためのセッター関数を作成します。

    int myInstanceVar = 5
    
    Function SetMyInstanceVar(int newValue)
      myInstanceVar = newValue
    EndFunction
    

重要なのは、すでに初期化されたスクリプトに新しく追加されたプロパティは、プラグインで指定された値に自動的にデフォルト設定されるため、既存のプロパティを調整するだけでよいということです。

クエストの操作

クエストが実行されると(ジャーナルに表示されるだけでなく)、そのステージ、スクリプトのプロパティ、エイリアスは固定されます。これを処理する方法は次のとおりです。

  • エイリアス: ForceRefTo関数を使用して簡単に更新できます。アップデート/インストールのロジックで新しい参照をスクリプトプロパティとして追加し、ForceRefToを使用してエイリアスをその参照に向けます。

  • クエストステージ:

    1. 不要な変更は避ける: 理想的には、元のステージインデックスシーケンスを維持します。将来の追加に対応できるだけのステージIDをクエストに設計します。
    2. クエストの置き換えを検討する: 大幅な変更を加える場合は、Stopを使用して元のクエストを終了し、まったく新しいクエストを導入します。
    3. クエストの再構築: 同じフォームを使用して既存のクエストを再構築する必要がある場合は、StopResetSetStageを使用して、アップデート後にプレイヤーを目的の状態に誘導します。

オブジェクト参照の管理

ゲームの世界を変更するMODは、オブジェクトの配置の競合を引き起こす可能性があり、多くの場合、作者は新しいセーブデータを要求することになります。これは、永続的な参照の位置が保存されるためです。

永続的なオブジェクト参照だけが問題であることを覚えておいてください。一時的なオブジェクトは保存されないため、新しい位置に自動的に更新されます。

  • 移動可能なオブジェクト: アクティベーターコンテナ可動スタティック、マーカーなど、ほとんどの永続的なオブジェクトは、スクリプトを使用して移動できます。MoveToMyEditorLocation関数は、このために特に役立ちます。

  • 移動できないオブジェクト: 植物スタティック家具は、スクリプトで移動できません。解決策をいくつか紹介します。

    1. 無効化と置換: オブジェクトが他のMODで使用されていない場合は、古いオブジェクトを無効化し、目的の場所に新しいオブジェクトを追加します。これらのオブジェクトを参照するクエストエイリアスまたはスクリプトプロパティが適切に更新されていることを確認してください。
    2. Save Unbakerの必須化: Save Unbaker MODを必須MODとして追加します。このツールは、これらのオブジェクトを自動的に新しい位置に移動します。

その他の永続的なレコード

セーブデータに永続化されるその他のレコードを以下に示します。

例:遡及的なアップデートスクリプト

ScriptName RetroactiveFixAlias Extends ReferenceAlias

MyQuestScript Property myQuest Auto
ObjectReference Property myQuestProperty1Ref Auto
ObjectReference Property myQuestProperty2Ref Auto

ReferenceAlias Property myAlias1 Auto
ReferenceAlias Property myAlias2 Auto
ObjectReference Property myAlias1Ref Auto
ObjectReference Property myAlias2Ref Auto

ObjectReference Property myRef1 Auto
ObjectReference Property myRef2 Auto

ObjectReference Property myActor1 Auto
Outfit Property myActor1Outfit Auto

int currentVersion = -1

Event OnInit()
  HandleInstallOrUpdates()
EndEvent

Event OnPlayerLoadGame()
  HandleInstallOrUpdates()
EndEvent

Function HandleInstallOrUpdates()
  If currentVersion != 2
    myQuest.myQuestProperty1 = myQuestProperty1Ref
    myQuest.myQuestProperty2 = myQuestProperty2Ref

    myAlias1.ForceRefTo(myAlias1Ref)
    myAlias2.ForceRefTo(myAlias2Ref)

    myRef1.MoveToMyEditorLocation()
    myRef2.MoveToMyEditorLocation()

    myActor1.SetOutfit(myActor1Outfit)

    currentVersion = 2
  EndIf
EndFunction

例:セルロード後のObjectReferenceの修正

ScriptName RetroactiveFixObjectReference extends ObjectReference

int currentVersion = -1
ObjectReference Property myRef Auto
FormList Property myRefTypes Auto

Event OnInit()
  ; バージョン2で初期化されているため、修正は不要
  currentVersion = 2
EndEvent

Event OnCellAttach()
  If currentVersion != 2
    myRef = Game.FindClosestReferenceOfAnyTypeInListFromRef(myRefTypes, self, 100.0)
    currentVersion = 2
  EndIf
EndEvent

結論

このガイドでは、すべてのシナリオを網羅しているわけではありませんが、Skyrim MODをよりアクセスしやすく、ユーザーフレンドリーにするための確固たる基盤を提供しています。完璧なプレイ中の互換性を実現することは難しい場合がありますが、その方向への小さな一歩が、ユーザーの体験を大幅に向上させる可能性があることを忘れないでください。

Analytics