従来のシートインフラストラクチャとBeaconシートインフラストラクチャには違いがあるため、既存のModスクリプトのすべてが、そのままの状態でBeaconシートで動作するわけではありません。以下の注意事項を参考に、Beaconシート(例:D&D 2024)で動作するようにスクリプトを更新してください。また、いくつかの主要スクリプトも更新しましたので、ゲームにすぐに使えるサンプルやスクリプトが用意されています。更新されたスクリプト:
- グループによる取り組み
- TokenMod
- グループチェック
- ステータス情報
多くのスクリプトにおいて、2024年版シートとの互換性を確保するには、主に2つの変更が必要です。それは、属性の取得と設定の方法、およびロールテンプレートやチャットメッセージの解析方法です。このドキュメントでは、その両方について順を追って説明するとともに、よくある問題についても取り上げています。これにより、スクリプトを更新して、「D&D 2014」シートと「D&D 2024」シートの両方で動作させることができるようになります。
Beaconの計算プロパティおよびuser.*のカスタム属性を使用するには、Mod Script サンドボックス v1.5(Campaign().sandboxVersion === "1.5")が必要です。 v1.5 が現在のデフォルトのサンドボックスです。 getSheetItemとsetSheetItem は、v1.0 と v1.5 の両方に存在します。 v1.0では、従来のリソース属性のget/set関数にフォールバックするため、Beaconシートがないゲームでも正常に動作します。 v1.5では、Beaconの計算プロパティやuser.*フィールドの読み取りおよび書き込みも行います。 Mod Script サンドボックス v1.5 専用です。 getComputed、setComputed、およびperformAction(「Modスクリプト:関数のドキュメント」を参照)。
ゲームのサンドボックスドロップダウンに「デフォルト」と「実験的」のラベルが表示されている場合は、ラベルではなくCampaign().sandboxVersionを使用して、実行中のサンドボックスを確認してください。 Beaconの計算プロパティには「1.5」が必要です。
get/set の更新
2014シートと2024シートのデータアクセスにおける主な変更点は、コードの観点から言えば、属性の取得と設定の方法です。 「getSheetItem」および「setSheetItem」という一連の非同期関数が追加されました。新しい関数の使用例を以下に示します:
const getDeathSaveSuccess = async (id) => {
const firstSuccess = await getSheetItem(characterId, "deathsave_succ1");
log(`First success is ${firstSuccess}`);
}
能力値の最大値(最大値が存在する場合)を取得したい場合は、max プロパティを指定して、getSheetItem(characterId, "deathsave_succ1", "max"); のように呼び出すことができます。
上記のコードを見ると、getDeathSaveSuccess がasync としてマークされていることに気づくでしょう。 getSheetItemを使用するすべての関数では、この async/await パターン、または Promise を使用する必要があります。以下は、同じ関数をプロミスとして書き直したものです:
const getDeathSaveSuccess = (id) => {
getSheetItem(characterId, "deathsave_succ1").then((firstSuccess) => {
log(`First success is ${firstSuccess}`);
});
}
一度に複数の値(あるいは順番に)を取得しようとしており、コードの残りの部分がそのデータに依存している場合は、各値を個別にawaitするか、Promise.allを使用してすべてのプロミスを一度に解決し、最終的な値を取得することができます。そうしないと、取得される値は実際の能力値ではなく、保留中のプロミスとなります。
const getSuccesses = (id) => {
const promises = [];
promises.push(getSheetItem(characterId, "deathsave_succ1"));
promises.push(getSheetItem(characterId, "deathsave_succ2"));
promises.push(getSheetItem(characterId, "deathsave_succ3"));
Promise.all(promises).then((results) => {
log(`最初の成功は ${results[0]}、2番目の成功は ${results[1]}、3番目の成功は ${results[2]}`);
});
}
非同期コードは、その構成方法によっては、スクリプトの記述方法にさまざまな影響を及ぼす可能性があります。たとえば、スクリプト内で現在 `replace` や`マップ` の内部で `getAttrByName`を使用している場合、これらの関数は値が返されるのを待たずに処理を続行するため、非同期処理に適したループに分割する必要があります。
「複数の値を一度に、あるいは次々と取得しようとしていて、コードの残りの部分がそのデータに依存している場合」という部分に戻りましょう。コードの残りの部分は、必ずしもその値に依存するわけではありません。 getSheetItem を使用している場合、ほとんどの場合そうなるでしょう。というのも、取得した属性を使って何か処理を行いたいからです。その逆であるsetSheetItem については、処理が完了するのを待つ必要がない場合がほとんどです。その場合は、非同期処理に関する考慮事項は無視して、通常通り呼び出せばよいです。スクリプトの実行を継続している間、この能力値はバックグラウンドで更新されます。
setSheetItem関数はgetSheetItem と同じように動作しますが、設定する値を示す追加の引数があります:
setSheetItem(characterId, "hp", 10);
setSheetItem(characterId, "hp", 20, "max");
ロール解析の更新
5eのスクリプトの多くに見られる、更新が必要なもう1つの点は、ダイス出目の解析です。チャットに送信されたチャットロールは形式が異なり、内容に関する結果や詳細を取得するには、別の方法で解析する必要があります。開発チームは、HTMLにいくつかのデータ属性を追加し、大規模なHTML解析の必要性を軽減しました。より複雑なデータが必要な場合は、チャットに送信されたメッセージからそのデータを解析する必要があるかもしれません。以下に、よくあるニーズをいくつか挙げます。
標準のロールテンプレートでダイスの出目を取得するには:
const rollResultMatch = msg.content.match(/data-result="(.+?)"/);
タイトルから、そのロールがどのような種類のものかを確認するには:
const deathSaveMatch = msgContent.match(/header__title">ここにヘッダーを入力してください<\/div>/);
ロールのサブタイトルを確認し、呪文のレベルやダメージの種類などの情報を調べるには:
const spellLevelMatch = msgContent.match(/header__subtitle">Level (.+?) /);
2024年版のシートは現在も開発中であるため、ロールテンプレートが変更される可能性があり、スクリプトのさらなる更新が必要になる場合があります。 HTMLの文字列解析が今後も常に安定して動作することを保証することはできませんが、シートの開発が進むにつれ、より標準化されたテンプレートの実現に向けて取り組んでいます。上記の例は、簡潔さを優先したため、正規表現がやや厳格になっています。テンプレートの内容がまだ流動的な段階では、マッチングの堅牢性を高めるために、より緩やかなマッチングやワイルドカードの使用をお勧めします。
よくある問題
エラー:character_id(ここにIDを入力)という名前の、(ここに能力値を記入)という属性またはシートフィールドが見つかりません。
考えられる原因:Mod Script サンドボックス v1.5 ではなく v1.0 を使用しており、Beacon の計算プロパティにアクセスしようとしているためです。 Campaign().sandboxVersionが「1.5」であることを確認してください。サンドボックスのドロップダウンメニューに「デフォルト」と「実験的」というラベルが表示されたままの場合、そのラベルが古くなっている可能性があります。ドロップダウンメニューの情報だけを鵜呑みにせず、再起動を行ってからsandboxVersion(および再起動ログ)を確認してください。
getSheetItemの結果が値ではなく空のオブジェクトをログに出力している
考えられる原因:getSheetItem関数で.thenを待機または使用していない。値が返されるまで待ってから、コードを先に進める必要があります。