Oblivion:Häufige Fehler

Aus Skript-Wiki
Wechseln zu: Navigation, Suche

Einleitung

All diese Sachen sollten von einem Modder vermieden werden:

AddTopic-Problem

Obwohl er eigentlich recht bekannt und gut dokumentiert ist, ist der "AddTopic-Bug" ein sehr häufiger Fehler bei Moddern. Wenn zwei oder mehr Mods versuchen, das selbe Topic zu verändern, wird nur das Topic des zuletzt geladenen geändert. Das kann zu schwerwiegenden Problemen führen, da das GREETING von mehreren NPCs verwendet wird. Das Problem tritt auch auf, wenn unerwünschte GREETING-Dialoge von einem NPC entfernt wurden. Motub hat eine ausführliche Anleitung zur Lösung des AddTopic-Problems geschrieben.

Außerdem sollte es vermieden werden, ein Topic durch ein Script und zusätzlich über die AddTopic-Box hinzuzufügen. Das kann dazu führen, dass NPCs plötzlich aus großer Entfernung, durch Objekte etc. mit dem Spieler reden, als wenn sie zum Beispiel mit StartConversation dazu gebracht worden wären. Das AddTopic aus dem Script des NPCs zu entfernen und in die Result-Box einzufügen, wird den Fehler verhindern.


Türen

Vanilla-Türen sollten nicht bewegt werden, da ihre Position im Savegame gespeichert wird, sobald der Spieler in ihre Nähe kommt. Modder sollten es deshalb vermeiden die originalen Türen zu verschieben.


Ändern von Script-Variablen

Dieses Problem ist am besten beschrieben in Wryes Thread Overriding Scripts and CTDs basierend auf einer Diskussion von MentalElf mit dem Titel In desparate need of a save game editor. Trotzdem ist ein kurzer Überblick an dieser Stelle wohl sinnvoll. Das Problem beim Ändern von Script-Variablen ist nicht, welche Mod dabei in bestimmten Konfigurationen gewinnt, sondern dass sich dies mit der Zeit ändern kann. Mann stelle sich vor, jemand nutzt eine BaseModA.esm, welche MyScript mit den Variablen VarA, VarB und VarC definiert.Diese Variablen bekommen die Indexe 1, 2 und 3. Das Savegame wird nur folgende Information enthalten:

<tesscript> script FormID = xxxxxx

 value for variable index 1 = x
 value for variable index 2 = y
 value for variable index 3 = z</tesscript>

Mit anderen Worten: Nur die Position der Variable wird gespeichert.

Wenn der Spieler also nun nach einiger Zeit entscheidet die AddOnB.esp hinzuzufügen und diese kleine Änderungen an MyScript vornimmt, hat es zwar immer noch die Variablen VarA, VarB und VarC, aber sie haben nun die Indexe 3, 2, 1. Wenn das Savegame also nun geladen wird, erkennt es, dass sich die FormID des Scripts nicht geändert hat und lädt also 1 für VarC, 2 für VarB, und 3 für VarA. Je nach Bedeutung der Variablen können nun ernsthafte Probleme auftreten.

Schlimmer wird es noch, wenn VarA eine ref-Variable und VarC eine float-Variable ist. Du hast also nun das Binäre der float-Variable in der ref-Variable und den Inhalt der ref-Variable in der float-Variable. Absolutes Chaos!

Der einzige Weg, das zu ändern, ist das Savegame ohne jegliche Mods zu laden, die etwas an dieser FormID ändern, zu speichern, die Dateien in korrekter Reihenfolge hinzuzufügen und neu zu starten. Leider funktioniert dies nicht für Scripts aus der originalen Oblivion.esm.

Obwohl dies ein schwerwiegender Fehler ist, der einige CTDs verursachen kann, scheinen viele Leute nicht darüber informiert zu sein.


Überfüllen von Savegames

Das Savegame enthält Informationen über Änderungen an der Spielwelt. Umso mehr verändert wird, desto mehr muss im Savegame gespeichert werden und desto größer wird dies. Ein großer Faktor dafür ist die PlaceAtMe-Funktion. Neue Objekte, die mit PlaceAtMe erschaffen wurden, verschwinden nie. Dieses Problem tritt auf, wenn unsichtbare Activators zum Beispiel Zauber auf den Spieler werfen - das Resultat sind unzählige ungenutzte Activators, die dennoch weiterhin im Savgame gespeichert bleiben.

Auch Gegenstände im Inventar können zu Problemen werden, zum Beispiel durch den Bug der negativen Gegenstandsanzahl (siehe unten).


Vermeiden von PlaceAtMe

Frühe Versionen des bekannten Tutorials Casting Spells From An Activator benutzten PlaceAtMe sehr häufig, was einen großen Fehler darstellte, da die Script-Beispiele viel Müll im Savegame hinterließen. Als das Tutorial geschrieben wurde, ging man noch davon aus, dass PlaceAtMe ordnungsgemäß funktionieren würde. Mittlerweile wurde es aktualisiert und nutzt nun MoveTo, allerdings wurden dennoch sehr viele Mods mit PlaceAtMe erstellt.

Leider entfernt disable nicht den Eintrag im Savegame. Dieses Problem wird zwar angesprochen, allerdings ist die Warnung sehr schwach ausgefallen:

avoid using PlaceAtMe to create new copies of an object 
when you could simply use MoveTo on an existing object.

(deutsche Übersetzung: ... vermeide PlaceAtMe , um Kopien eines Objektes zu erstellen, wenn du auch MoveTo verwenden könntest)

Die PlaceAtMe-Seite enthält zwar Hinweise und die Diskussions-Seite enthält zusätzliche Informationen, allerdings wird es nicht dort erwähnt, wo Modder normalerweise nachsehen (z.B. Tutorials), also bin ich nicht davon überzeugt, dass es so nützlich ist.

Viele Mods verwenden trotz allem noch immer die veraltete Methode und platzieren unsichtbare Activators nahe dem Spieler, obwohl MoveTo ebenso funktionieren würde.

Der Grund, warum das Thema nicht so weit verbreitet ist, ist vielleicht die Tatsache, dass sich MoveTo nicht so einfach verwenden lässt wie PlaceAtMe. Es wird zwar auf der Diskussions-Seite behandelt, dort ist es aber nicht sehr ausführlich beschrieben.

Es wird deswegen dringend ein gutes Tutorial diesbezüglich benötigt!

Eines der Hauptprobleme mit MoveTo ist, dass die Collision nicht immer mit bewegt wird. Disable nach MoveTo zu verwenden und dann Enable einen Frame später, könnte dieses Problem lösen.

Das Überfüllen des Savegames durch PlaceAtMe ist zwar vielleicht nicht so schwerwiegend wie einige andere Fehler, aber eine einzige Mod, die diese veraltete Methode nutzt, kann einem Savegame schnell mehrere Megabyte hinzufügen. Wenn es nun mehr als nur eine Mod sind, wächst das Savegame doch recht gut an.

Vermeiden von DuplicateAllItems auf einem Begleiter

DuplicateAllItems scheint für das Überfüllen der Savegames bei Weitem am Schwerwiegendsten verantwortlich zu sein.

Einige Begleiter-Mods haben die Savegames unglaublich vergrößert, indem häufig DuplicateAllItems verwendet wurde. Das gewöhnlichste Beispiel ist eine Mod, die DuplicateAllItems verwendet, (um sie auf ein Duplikat des NPCs zu duplizieren) um die Belastung zu berechnen und anzuzeigen. Falls einige der Gegenstände des NPCs gescriptete Objekte sind, werden sie permanent dupliziert (und unmöglich zu entfernen), jedes Mal, wenn das DuplicateAllItems ausgeführt wird. Da dies jeden Frame geschieht, so lange das Inventar des Begleiters geöffnet ist, wird das Savegame ziemlich schnell überfüllt (dutzende Megabyte in wenigen Sekunden).

Statt die Items zu duplizieren, kann besser RemoveAllItems verwendet werden, um die Gegenstände auf den Begleitern zu übertragen und danach wieder zurück. Das behebt zwar den ursprünglichen Fehler (gescriptete Objekte überfüllen das Savegame nicht mehr), aber führt zum Fehler der negativen Gegenstandsanzahl(siehe unten) .


Vermeiden von RemoveAllItems auf einem Begleiter

Dies kann zwar auch zu Überfüllungen des Savegames führen, es lässt sich aber leichter vermeiden als DuplicateAllItems.

Das Benutzen von RemoveAllItems auf einem Actor oder Container mit einer negativen Gegenstandsanzahl bei einem oder mehreren Gegenständen wird diese duplizieren. Eine negative Anzahl bedeutet, dass ein Gegenstand aufgestockt wird, sobald er entfernt wird.

Dieses Problem lässt sich vermeiden, indem man dem Begleiter keine negativen Gegenstände gibt. Also sollte vermieden werden

<tesscript>NPC.RemoveAllItems NewContainer</tesscript>

dann

<tesscript>Newcontainer.RemoveAllItems NPC</tesscript>

auf einem NPC mit negativer Gegenstandszahl. Das wird nämlich die Items jedes Mal duplizieren, wenn du etwas mit deinem Begleiter teilst. Das bedeutet der NPC hat 65536 Gegenstände nach dem 16. Mal, 16777216 Gegenstände nach dem 24. Mal und 4.2 Milliarden nach dem 32. Mal.

Beträchtliches Savegame-Wachstum!


Vermeide diese Punkte

Hier ist eine Liste der Punkte, die sonst noch zu vermeiden sind:

  • Klicke niemals den Button "Recompile All"
  • Aktiviere niemals "Generate All" für Pathgrids oder "Generate Entire World"
  • Versuche niemals Items einer ESP in eine andere ESP zu kopieren, wenn sie nicht aus der Oblivion.esm stammen
  • Verändere keine Zellen der Oblivion.esm mit einer anderen Master-Datei.
  • Verändere Zellen nicht aus Versehen. Zellen, die nicht direkt von deiner Mod verändert werden, haben auch kein Sternchen (benutze TES4Gecko, um deine Mod vor dem Release zu säubern). Besser wäre aber Tes4Edit (Tes4View) (TES4Gecko hat hier Fehler!).
  • Benutze keine Unterstriche in primären Ressourcen-Dateinamen. Unterstriche sind vom Spiel genutzt, um diverse Dateitypen, wie Normal Maps (xxx_n.dds), Glow Maps (xxx_g.dds) etc. zu finden.
  • Benutze keine vollständigen Pfade für Retexturierungen. Texturpfade müssen relativ zum Data-Ordner sein, nicht höher (nicht C:\Programme\...). Du kannst NIBlE's "Strip Texture paths"-Funktion nutzen, um dies zu umgehen.
  • Verändere nicht den Besitzer eines Items im CS. Falls du einen Besitzer ändern musst, mache das Item persistent und verändere ihn per Script. Das verhindert einen Bug, bei dem Gegenstände nicht korrekt entfernt werden. Ignoriere dies, wenn du viele Besitzer von Gegenständen ändern musst - der Frame-Verlust, der dadurch entstehen würde, ist es nicht wert.


Tipps

  • Packe Mods so, dass sie direkt ohne Unterordner in den Data-Ordner entzippt werden können.
  • Die README sollte ModName-README.txt genannt werden, um keine bestehenden READMEs zu überschreiben.
  • .7z (7-zip) ist das gängigste Format zum Packen von Mods.


Vermeide gewöhnliche IDs zu nutzen

Obwohl dies in Oblivion weniger ein Problem ist als in Morrowind, sollte es erwähnt werden.

Erstelle keine Objekte oder Variablen mit gewöhnlichen Namen wie "GEHEIMEREINGANG". Benutze ein einzigartiges Prä- oder Suffix, um deine IDs zu kennzeichnen, wie zum Beispiel: "IchininGEHEIMEREINGANG".

Dies wird deine Mod nicht so schnell mit anderen Mods in Konflikt kommen lassen.


Verschwindende Landschaft in Tamriel

Dieses Problem ist auch unter den Häufigen Fehlern gelistet, weil es entstehen kann, wenn der aktuelle Modindex sich vom Modindex während der Erstellung des Plugins unterscheidet. Es tritt in diesem Fall auf, wenn du mit einer Master-Datei einen anderen Master (wie die Oblivion.esm) veränderst.

Die einfachste Lösung?. Nutze niemals eine Master-Datei, um eine andere Master-Datei zu verändern. Die Lösung ist in einem alten Tutorial zur Erstellung sauberer Mater-Dateien näher erläutert.

Glücklicherweise lässt sich das nun einfach erledigen, indem man mit TES4Gecko ein Plugin in seine esm- und esp-Komponenten aufteilt.


Spieleinstellungen

Einstellungen sind nicht wie die globalen Variablen. Falls du

<tesscript>set SomeVar to fiSomeGameSetting</tesscript>

benutzt, wird dein Script gespeichert, aber nicht im Spiel ausgeführt. Du musst die Funktion GetGameSetting nutzen:

<tesscript>set SomeVar to (GetGameSetting fiSomeGameSetting)</tesscript>

Häufige MessageBox-Fehler

  1. Das Script muss jeden Frame ausgeführt werden, um das Klicken des Buttons mitzubekommen. Für persistente Objekte (Activator, Container etc.) bedeutet das, dass sie erst in den Speicher geladen werden müssen (z.B. in die selbe Zelle wie der Spieler). Für Quests heißt das, dass fQuestDelayTime auf einen niedrigen Wert, wie .001 gesetzt werden muss. Für alle gültig ist, dass der Code in einen Block gesetzt wird, der jeden Frame ausgeführt wird (z.B. GameMode, MenuMode)
  2. Falls mehrere Menüs dargestellt werden sollen, wird eine Variable benötigt, die angibt in welchem Menü der Spieler sich grade befindet. Mache zum Beispiel eine short MenuShowing-Variable und setze den Wert auf 1 für das erste Menü, 2 für das zweite Menü und so weiter.
  3. Falls du einen gescripteten Magie-Effekt für deine MessageBox verwendest, stelle sicher, dass er (mindestens) einige Sekunden anhält. Es wird allerdings dringend empfohlen, eine andere Methode zu nutzen. Du kannst den Effekt mit einer Quest starten lassen oder mittels eines Activators oder füge dem Spieler einfach ein Token hinzu und lasse die Messagebox darüber laufen.
  4. Falls irgendwelcher Code nach dem Button-Teil (also nach if (Button > -1)) jeden Frame ausgeführt werden muss, musst du deinen Code so gestalten, dass die Button-Variable jeden Frame gesetzt wird:

<tesscript>... if (MenuShowing == -1)

 MessageBox ...
 set MenuShowing to 1

elseif (MenuShowing == 1)

 set Button to GetButtonPressed
 if (Button > -1)

if (Button == 0) ...</tesscript>

dann musst du es so ändern, dass der Button nach dem Anzeigen des Menüs zurückgesetzt wird:

<tesscript>... if (MenuShowing == -1)

 MessageBox ...
 set MenuShowing to 1
 set Button to GetButtonPressed

elseif (MenuShowing == 1)

 if (Button == -1)

set Button to GetButtonPressed return

 elseif (Button == 0)

...</tesscript>