So aktualisierst du Mod-Skripte für D&D 2024/Beacon

Aufgrund der Unterschiede zwischen der Altsystem-Bogen-Infrastruktur und der Beacon-Bogen-Infrastruktur funktioniert nicht jedes bestehende Mod-Skript sofort mit Beacon-Bögen. Die folgenden Hinweise helfen dir dabei, Skripte so zu aktualisieren, dass sie mit Beacon-Bögen (zum Beispiel D&D 2024) funktionieren. Außerdem haben wir mehrere Kernskripte aktualisiert, damit es Beispiele und einsatzbereite Skripte für deine Spiele gibt. Skripte, die aktualisiert wurden:

  • Gruppeninitiative
  • TokenMod
  • Gruppenprobe
  • StatusInfo

Bei vielen Skripten läuft die Kompatibilität mit dem 2024-Bogen auf zwei Änderungen hinaus: wie du Attribute abrufst und festlegst und wie du Würfel-Vorlagen/Chat-Nachrichten auswertest. Dieses Dokument führt dich durch beides und behandelt außerdem häufige Probleme, damit du ein Skript so aktualisieren kannst, dass es sowohl mit dem Bogen D&D 2014 als auch mit dem Bogen D&D 2024 funktioniert.

Für berechnete Eigenschaften von Beacon und benutzerdefinierte user.*-Attribute ist Mod-Skript-Sandkasten v1.5 erforderlich (Campaign().sandboxVersion === "1.5"). v1.5 ist der aktuelle Standard-Sandkasten. getSheetItem und setSheetItem gibt es sowohl in v1.0 als auch in v1.5. In v1.0 greifen sie auf die Altsystem-Attribut-Get-/Set-Funktionen zurück, sodass Spiele ohne Beacon-Bogen weiterhin funktionieren. In v1.5 lesen und schreiben sie auch berechnete Eigenschaften von Beacon und user.*-Felder. Nur Mod-Skript-Sandkasten v1.5. getComputed, setComputed und performAction (siehe Mod-Skripte: Funktionsdokumentation).

Wenn das Sandkasten-Dropdown-Menü eines Spiels immer noch die Bezeichnungen „Standard“ und „Experimentell“ anzeigt, bestätige den laufenden Sandkasten mit Campaign().sandboxVersion statt anhand der Bezeichnung. Berechnete Eigenschaften von Beacon benötigen "1.5".

Get/Set aktualisieren

Der größte Unterschied beim Zugriff auf die Daten des Bogens 2014 und des Bogens 2024 besteht darin, wie du die Attribute erhältst und festlegst. Es gibt jetzt eine Reihe asynchroner Funktionen namens getSheetItem und setSheetItem. Hier ist ein Beispiel für die Verwendung der neuen Funktionen:

const getDeathSaveSuccess = async (id) => {
  const firstSuccess = await getSheetItem(characterId, "deathsave_succ1");
  log(`Erster Erfolg ist ${firstSuccess}`);
}

Wenn du den Maximalwert eines Attributs abrufen möchtest (sofern es einen gibt), kannst du die Eigenschaft max übergeben, z. B. getSheetItem(characterId, "deathsave_succ1", "max");.

Im obigen Code wirst du feststellen, dass getDeathSaveSuccess als async gekennzeichnet ist. Alle Funktionen, die getSheetItem verwenden, sollten dieses async/await-Muster nutzen oder mit Promises arbeiten. Hier ist dieselbe Funktion, umgeschrieben als Promise:

const getDeathSaveSuccess = (id) => {
  getSheetItem(characterId, "deathsave_succ1").then((firstSuccess) => {
    log(`Der erste Erfolg ist ${firstSuccess}`);
  });
}

Wenn du versuchst, mehrere Werte auf einmal (oder nacheinander) abzurufen, und der Rest deines Codes von diesen Daten abhängt, kannst du entweder jeden Wert einzeln mit await abwarten oder Promise.all verwenden, um alle Promises auf einmal aufzulösen und die endgültigen Werte zu erhalten. Wenn du das nicht tust, erhältst du als Wert ein „Pending Promise“ und nicht den tatsächlichen Attributwert.

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(`Der erste Erfolg ist ${results[0]}, der zweite Erfolg ist ${results[1]}, der dritte Erfolg ist ${results[2]}`);
  });
}

Asynchroner Code kann verschiedene Auswirkungen darauf haben, wie du ein Skript schreibst – je nachdem, wie du es strukturiert hast. Wenn ein Skript beispielsweise derzeit getAttrByName innerhalb von replace oder map verwendet, muss es in eine asynchronfreundlichere Schleife aufgeteilt werden, da diese Funktionen nicht auf die Rückgabe eines Werts warten, bevor sie fortfahren.

Kommen wir noch einmal auf den Satz zurück: „Wenn du versuchst, mehrere Werte auf einmal oder nacheinander abzurufen, und der Rest deines Codes von diesen Daten abhängt.“ Der Rest deines Codes hängt nicht immer von diesem Wert ab. Meistens ist das der Fall, wenn du getSheetItem verwendest, denn du möchtest ja etwas mit dem Attribut anfangen, das du abrufst. Bei der umgekehrten Funktion, setSheetItem, musst du oft nicht warten, bis sie fertig ist. In diesem Fall kannst du die Auswirkungen der Asynchronität ignorieren und die Funktion einfach ganz normal aufrufen. Das Attribut wird im Hintergrund aktualisiert, während dein Skript weiterläuft.

Die Funktion setSheetItem funktioniert genauso wie getSheetItem, enthält aber ein zusätzliches Argument für den Wert, der gesetzt werden soll:

setSheetItem(characterId, "hp", 10);
setSheetItem(characterId, "hp", 20, "max");

Aktualisierung der Würfelauswertung

Eine weitere Funktion, die in vielen 5e-Skripten vorkommt und aktualisiert werden muss, ist die Auswertung von Würfelergebnissen. Würfe, die an den Chat gesendet werden, sind anders formatiert und müssen anders ausgewertet werden, um Ergebnisse oder Details zum Inhalt zu erhalten. Das Entwicklerteam hat dem HTML-Code einige Datenattribute hinzugefügt, die den Aufwand für eine umfangreiche HTML-Auswertung verringern. Wenn du komplexere Daten benötigst, musst du diese möglicherweise trotzdem aus der an den Chat gesendeten Nachricht auswerten. Hier sind ein paar typische Anforderungen.

So erhältst du das Ergebnis eines Wurfs in der Standard-Würfel-Vorlage:

const rollResultMatch = msg.content.match(/data-result="(.+?)"/);

So kannst du anhand des Titels feststellen, um welche Art von Wurf es sich handelt:

const deathSaveMatch = msgContent.match(/header__title">Gib hier die Überschrift ein<\/div>/);

So überprüfst du den Untertitel des Würfelwurfs und findest Informationen wie Zauberstufe oder Schadensart:

const spellLevelMatch = msgContent.match(/header__subtitle">Level (.+?) /);

Da sich der Bogen für 2024 noch in aktiver Entwicklung befindet, können sich die Würfel-Vorlagen ändern und weitere Skript-Aktualisierungen erfordern. Wir können nicht garantieren, dass das String-Parsing des HTML-Codes auf Dauer stabil bleibt, aber wir arbeiten daran, im Zuge der Weiterentwicklung des Bogens standardisiertere Vorlagen zu schaffen. Die obigen Beispiele sind der Einfachheit halber in ihren regulären Ausdrücken etwas starr; wir empfehlen lockereres Matching und Platzhalter, um dein Matching robuster zu machen, solange sich die Vorlagen noch im Wandel befinden.

Häufige Probleme

Fehler: Kein Attribut oder Bogenfeld für character_id (DEINE ID HIER) namens (DEIN ATTRIBUT HIER) gefunden

Mögliche Ursache: Du verwendest Mod-Script-Sandkasten v1.0 statt v1.5 und versuchst, auf eine berechnete Eigenschaft von Beacon zuzugreifen. Bestätige, dass Campaign().sandboxVersion "1.5" ist. Wenn ein Sandkasten-Dropdown-Menü immer noch mit „Standard“ statt „Experimentell“ beschriftet ist, kann die Bezeichnung veraltet sein; starte neu und prüfe sandboxVersion (sowie das Neustartprotokoll), anstatt dich allein auf das Dropdown-Menü zu verlassen.

Ergebnis von getSheetItem protokolliert ein leeres Objekt anstelle eines Wertes

Mögliche Ursache: Bei der Funktion getSheetItem wird nicht abgewartet oder .then nicht verwendet. Du musst warten, bis der Wert zurückkommt, bevor du mit dem Code weitermachst.

War dieser Beitrag hilfreich?
10 von 14 fanden dies hilfreich