Skyrim:Hinweise zum Save
Inhaltsverzeichnis
Wann kann das Game sichern?
Das Game kann zu jeder Zeit sichern. Dies kann zwischen Zeilen im Script sein oder sogar in der Mitte der Ausführung einer einzelnen Zeile. Meistens braucht man sich deswegen keine Sorgen zu machen, da das Spiel das Script wieder erfolgreich zum Laufen bringt, wenn das Spiel geladen wird, vorausgesetzt, man hat nichts geändert. Aber was ist, wenn man etwas geändert hat?. Nun, hierfür bietet diese Seite Hilfe an.
Scripts
Hinzufügen zu einem Object
Wenn man, nachdem ein Save gemacht wurde, einem Object ein Script in der Masterdatei hinzufügt, wird das Script auf dem Object existieren, wenn das Save geladen wird. Es wird aber komplett unberührt sein (alle Properties werden auf die Werte der Masterdatei gesetzt sein und der OnInit-Block wird durchlaufen, sobald das Save fertig geladen ist)
Entfernen von einem Object
Wenn man, nachdem ein Save gemacht wurde, von einem Object ein Script in der Masterdatei entfernt, ist das Script immer noch auf dem Object vorhanden, wenn das Save geladen ist. Wenn das Script gänzlich gelöscht ist, können Merkwürdigkeiten auftreten.
Properties und Scriptvariablen
Hinzufügen
- Variable mit einem voreingestellten Wert: Die Variable wird ihren voreingestellten Wert haben, wenn das Save geladen wird. (Das ist die Syntax von "int myVar = 5")
- Variable ohne einen voreingestellten Wert: : Die Variable wird keine voreingestellten Wert haben, wenn das Save geladen wird (0, empty string, None oder false)
- Auto Property: Die Property wird den entsprechenden Wert von der Masterdatei erhalten, sofern einer vorhanden ist. (Dies sind Properties, die mit dem Schlüsselwort "auto" enden, wie z.B.: "ObjectReference Property MyObject Auto")
- Non-auto Property: Die Property wird den entsprechenden Wert von der Masterdatei nicht erhalten, sofern einer vorhanden ist. Es bleibt leer.
Beachte: Wenn das OnInit-Event des Objects schon gelaufen ist, wenn das Save gemacht wird, wird es aus offensichtlichen Gründen nicht noch einmal laufen. Deshalb kann man nicht garantieren, dass eine im OnInit-Block neu gesetzte Variable richtige Werte hat, es sei denn, man ist sicher, dass das Object vorher nie in dem Save-Game vorhanden war.
Entfernen
Wenn man, nachdem ein Save gemacht wurde, eine Property oder eine Variable entfernt, wird die Property oder Variable gestrichen und eine detaillierte Warnung über das, was passiert ist, wird im Script-Log ausgegeben.
Ändern
Wenn man den Namen einer Property oder Variablen ändert, wird verfahren, als wäre sie gelöscht worden und eine neue hinzugefügt. Wenn man den Typ (aber nicht den Namen) ändert, wird jeder Wert, den sie im Save-Game hatte, gestrichen und eine detaillierte Warnung über das, was passiert ist, wird im Script-Log ausgegeben.
Ändern eines Masterdatei-Wertes
Wenn man eine existierende Property hat und ihren Wert in der Masterdatei ändert, empfängt das Script diesen neuen Wert nur, wenn er nicht im Save existiert. Mit anderen Worten überschreibt das Ändern eines Wertes nicht den im Savegame.
Property-Beispiele
<papyrusscript>
- Version 1
Scriptname MyScript Extends ObjectReference
int Property MyAutoValue Auto
int internalValue int Property MyNonAutoValue
Function Set(int value) internalValue = value EndFunction int Function Get() return internalValue EndFunction
EndProperty
int MyVariableWithInit = 1 int MyVariableWithoutInit
Event OnInit()
MyVariableWithoutInit = 1
EndEvent
Event OnActivate(ObjectReference akActivator)
Debug.Trace("MyAutoValue = " + MyAutoValue) Debug.Trace("MyNonAutoValue = " + MyNonAutoValue) Debug.Trace("MyVariableWithInit = " + MyVariableWithInit) Debug.Trace("MyVariableWithoutInit = " + MyVariableWithoutInit)
EndEvent </papyrusscript>
In der Masterdatei:
- MyAutoValue = 1
- MyNonAutoValue = 1
Im Log nach der Aktivierung:
MyAutoValue = 1 MyNonAutoValue = 1 MyVariableWithInit = 1 MyVariableWithoutInit = 1 <Das Save ist hier gemacht worden>
<papyrusscript>
- Version 2
Scriptname MyScript Extends ObjectReference
int Property MyAutoValue Auto int Property MyAutoValue2 Auto
int internalValue int Property MyNonAutoValue
Function Set(int value) internalValue = value EndFunction int Function Get() return internalValue EndFunction
EndProperty
int internalValue2 int Property MyNonAutoValue2
Function Set(int value) internalValue2 = value EndFunction int Function Get() return internalValue2 EndFunction
EndProperty
int MyVariableWithInit = 2 int MyVariableWithoutInit
int MyVariableWithInit2 = 2 int MyVariableWithoutInit2
Event OnInit()
MyVariableWithoutInit = 2 MyVariableWithoutInit2 = 2
EndEvent
Event OnActivate(ObjectReference akActivator)
Debug.Trace("MyAutoValue = " + MyAutoValue) Debug.Trace("MyNonAutoValue = " + MyNonAutoValue) Debug.Trace("MyVariableWithInit = " + MyVariableWithInit) Debug.Trace("MyVariableWithoutInit = " + MyVariableWithoutInit) Debug.Trace("MyAutoValue2 = " + MyAutoValue2) Debug.Trace("MyNonAutoValue2 = " + MyNonAutoValue2) Debug.Trace("MyVariableWithInit2 = " + MyVariableWithInit2) Debug.Trace("MyVariableWithoutInit2 = " + MyVariableWithoutInit2)
EndEvent </papyrusscript>
In der Masterdatei:
- MyAutoValue = 2
- MyNonAutoValue = 2
- MyAutoValue2 = 2
- MyNonAutoValue2 = 2
Im Log nach der Aktivierung und Laden des vorigen Saves: I <Das Save ist hier geladen worden>
MyAutoValue = 1 MyNonAutoValue = 1 MyVariableWithInit = 1 MyVariableWithoutInit = 1 MyAutoValue2 = 2 MyNonAutoValue2 = 0 MyVariableWithInit2 = 2 MyVariableWithoutInit2 = 0
Funktionen
Anmerkungen
Änderungen an Funktionen spielen nur eine Rolle, wenn das Save gemacht wurde, während so eine Funktion läuft. Da jedoch ein Save jederzeit gemacht werden kann, müssen die folgenden Punkte beachtet werden. Weiter setzen die folgenden Informationen eine Struktur und ein Save voraus, das nach dem 29.11.2010 gemacht wurden. Frühere Strukturen und Saves (selbst wenn sie mit späteren Bauarten geladen werden) werden laufende Stacks wegwerfen, falls Funktionen im Thread geändert sind.
Hinzufügen
Beim Hinzufügen neuer Funktionen gibt es keine Probleme
Entfernen
Wenn man eine Funktion entfernt, die bei der Erstellung eines Saves mitten in der Ausführung war, wird die alte Funktion vom Save geladen und ihr wird das Beenden erlaubt. Es wird eine Warnung auf dem Scriptlog ausgegeben. Weitere Aufrufen an die entfernte Funktion (üblicherweise weil andere geänderte oder entfernte Funktionen sie aufrufen) schlagen fehl.
Ändern
Ändern von Parametern oder Return-Typen
Die Funktion wird als unterschiedlich erkannt und die alte Version der Funktion wird vom Savegame geladen und ihre Beendigung wird gestattet. Weitere Aufrufe dieser Funktion werden die Version aus den Archiven bzw. den verlassenen Dateien nutzen, was möglicherweise Fehler ausgibt, wenn es Parameter- oder Rückgabewert-Unverträglichkeiten gibt (üblicherweise weil andere geänderte oder entfernte Funktionen sie aufrufen).
Zufügen/Entfernen/Ändern von Funktions-Variablen
Die Funktion wird als unterschiedlich erkannt und die alte Version der Funktion wird vom Savegame geladen und ihre Beendigung wird gestattet. Weitere Aufrufe dieser Funktion werden die Version aus den Archiven bzw. den verlassenen Dateien nutzen.
Ändern von Code
Die Funktion wird als unterschiedlich erkannt und die alte Version der Funktion wird vom Savegame geladen und ihre Beendigung wird gestattet. Weitere Aufrufe dieser Funktion werden die Version aus den Archiven bzw. den verlassenen Dateien nutzen. . Ausnahme: Wenn eine Funktion native ist und nun gescriptet wird, wird der Stack ausgeworfen statt fortgesetzt.
FunctionsBeispiele
<papyrusscript>
- Version 1
Scriptname MyScript extends ObjectReference
Event OnActivate(ObjectReference akActivator)
MyFunction(1) MyFunction(2)
EndEvent
Function MyFunction(int aiMyValue)
Debug.Trace("Entered my function version 1: aiMyValue = " + aiMyValue) ; das Save ist *hier* gemacht Debug.Trace("Left my function version 1: aiMyValue = " + aiMyValue)
EndFunction </papyrusscript>
<papyrusscript>
- Version 2 – identisch zu Version 1 außer den Trace-Anweisungen
Scriptname MyScript extends ObjectReference
Event OnActivate(ObjectReference akActivator)
MyFunction(1) MyFunction(2)
EndEvent
Function MyFunction(int aiMyValue)
Debug.Trace("Entered my function version 2: aiMyValue = " + aiMyValue)
- das Save ist *hier* gemacht
Debug.Trace("Left my function version 2: aiMyValue = " + aiMyValue)
EndFunction </papyrusscript>
<papyrusscript>
- Version 3
Scriptname MyScript extends ObjectReference
Event OnActivate(ObjectReference akActivator)
Debug.Trace("OnActivate received!")
EndEvent </papyrusscript>
Das Save wurde gemacht während der Ausführung von MyFunction(1), aufgerufen von OnActivate in Version 1 des Scripts.
Scriptlog vor dem Save:
Entered my function version 1: aiMyValue = 1
Scriptlog nach Laden mit Version 2:
warning: Function MyScript..MyFunction in stack frame 2 in stack 457 differs from the in-game resource files - using version from save ... Left my function version 1: aiMyValue = 1 Entered my function version 2: aiMyValue = 2 Left my function version 2: aiMyValue = 2
Scriptlog nach Laden mit Version 3:
warning: Function Myscript..MyFunction in stack frame 2 in stack 457 doesn't exist in the in-game resource files - using version from save warning: Function MyScript..OnActivate in stack frame 1 in stack 457 differs from the in-game resource files - using version from save ... Left my function version 1: aiMyValue = 1 error: Method MyFunction not found on MyScript. Aborting call and returning None ... <later, after another activation> OnActivate received!
Links
- Save_File_Notes_(Papyrus) (das englische Original des obigen Artikels)