従来シートインフラストラクチャ( & )とビーコンシートインフラストラクチャの違いにより、既存のModスクリプトのすべてがそのまま互換性があるわけではありません。 幸いにも、以下のドキュメントをまとめましたので、Beaconシート(例:D&D 2024)で動作するようスクリプトをアップグレードする際に参考にしてください。 また、トップスクリプトを更新し、例やゲームですぐに使えるスクリプトを用意しました! 更新されたスクリプト:
- グループイニシアチブ
- トークンモッド
- グループチェック
- ステータス情報
多くのスクリプトにおいて、2024シートとの互換性を確保するための更新は、主に二つの変更に集約されます:属性の取得・設定方法と、ロールテンプレート/チャットメッセージの解析方法です。 このドキュメントでは、両方のシートに対応する方法と、よくある問題のトラブルシューティングを説明します。これにより、D&D2014 シートと D&D2024 シートの両方に対応するように、あらゆるスクリプトを更新できるようになります。
スクリプトがこのように更新されると、D&D2024などのビーコンシートを採用したゲームでは、GMが最新機能をすべて利用するには実験的APIサーバーを使用する必要があります。 実験サーバーはデフォルトサーバーと全く同じ機能を備えているため、この切り替えによって他のスクリプトが動作しなくなることはありません。ただし、ユーザーに知らせるために、スクリプトの説明文でこの変更を明記することをお勧めします。 ビーコンシートが存在しない場合でも、デフォルトサーバーはこれらの機能と動作します。これは、従来属性取得および設定機能にフォールバックするためです。
設定の更新/取得
2014シートと2024シートのデータアクセスにおける主な変更点は、コードの観点から言えば、属性の取得と設定の方法です。 getSheetItemとsetSheetItem という新しい非同期関数のセットが追加されました。 新しい関数の使用例を以下に示します:
const getDeathSaveSuccess = async (id) =>> {
const firstSuccess = await getSheetItem(characterId, "deathsave_succ1");
log(`最初の成功は ${firstSuccess}`);
}
属性の最大値(最大値が存在する場合)を取得したい場合は、maxプロパティを渡すことができます。例:getSheetItem(characterId, "deathsave_succ1",
"max");。
上記のコードでは、`getDeathSaveSuccess` が非同期メソッドとしてマークされていることに気づくでしょう。 getSheetItemを使用するすべての関数は、この非同期/待機パターンを使用するか、プロミスを使用する必要があります。 上記の関数をプロミスとして書き直したものがこちらです:
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]}, 二番目の成功は ${results[1]}, 三番目の成功は ${results[2]}`);
}
}
非同期コードは、その構造の仕方によって、スクリプトの記述方法に多くの影響を及ぼす可能性があります。 例えば、replaceやマップ内部でgetAttrByNameを使用しているスクリプトがある場合、それらの関数は値が返されるまで待機せずに処理を継続するため、より非同期処理に適したループ構造に書き換える必要があります。
「複数の値を一度に、あるいは順番に取得しようとしていて、そのデータがあることを前提にコードの残りの部分が動いている場合」と私が書いた時を振り返ってみましょう。 残りのコードは、必ずしもその値に依存しているわけではありません。 getSheetItemを使用している場合、ほとんどの場合その値に依存することになります。なぜなら、取得した属性を使って何らかの処理を行いたいからです。 しかし、逆のsetSheetItemの場合、その処理が完了するのを待つ必要は全くないことが多い。 その場合、これらの関数が非同期であることの影響は無視して、通常通り呼び出せばよい。 スクリプトが処理を続ける間、その能力値はバックグラウンドで更新されます。
setSheetItem関 数はgetSheetItem関数と同様に動作しますが、属性を何に設定するかを決定するための追加の引数を含みます。
setSheetItem(characterId, "hp", 10);
setSheetItem(characterId, "hp", 20, "max");
ロール解析の更新
5eスクリプトの多くで更新が必要なもう一つの点は、ロールの解析処理です。 チャットに送信されるロールは完全に異なる形式でフォーマットされており、結果を取得したり内容の詳細を把握したりするには、異なる方法で解析する必要があります。 開発チームはHTMLにいくつかのデータ属性を追加し、大規模なHTML解析の必要性を最小限に抑えました。ただし、より複雑なデータが必要な場合は、チャットに送信されたメッセージから解析する必要があるかもしれません。 以下に、始めるのに役立つ一般的なニーズをいくつかまとめました。
標準ロールテンプレートでロールの結果を取得するには:
const rollResultMatch = msg.content.match(/data-result="(.+?)"/);
タイトルに基づいて、それがどの種類のロールかを確認するには:
const deathSaveMatch = msgContent.match(/header__title">Insert Header Here<\/div>/);
ロールのサブタイトルを確認して、呪文レベルやダメージタイプなどを調べるには:
const spellLevelMatch = msgContent.match(/header__subtitle">Level (.+?) /);
2024年版シートは現在も開発中であるため、ロールテンプレートの仕様が変更される可能性があり、その場合はスクリプトの追加更新が必要となる場合があります。 HTMLの文字列解析が永遠に安定し続けるとはお約束できませんが、シートの開発を進める中で、より標準化されたテンプレートの実現に向けて取り組んでいます。 上記の例は簡略化のため正規表現がやや厳密ですが、ロールテンプレートが流動的な間は、ファジーマッチングとワイルドカードを使用してマッチングの堅牢性を高めることを推奨します。
よくある問題
エラー: 属性またはシートフィールドが見つかりません。character_id (ここにあなたのIDを入力) という名前の (ここにあなたの属性を入力)
原因として考えられるのは、実験的APIではなくデフォルトAPIを使用している状態で、ビーコンの計算済みプロパティにアクセスしようとしているためです。 「サーバーを再起動」をクリックする際、API再起動メッセージに「EXPERIMENTAL」という単語が含まれており、「DEFAULT」ではないことを確認してください。 ドロップダウンが「Experimental」に設定されているのに再起動ログが「DEFAULT」と表示される場合は、デフォルトに戻して再起動し、その後再び「Experimental」に切り替えて再起動してください。 これはデフォルトと実験的モードの切り替えに関する既知の問題であり、現在調査中です。
getSheetItemの結果が値ではなく空のオブジェクトをログに出力している
原因として考えられるのは、getSheetItem関数で.thenを待機または使用していないことです。 値が返されるまで待ってから、コードを先に進める必要があります。