Skyrim:Hinweise zum Save

Aus Skript-Wiki
Wechseln zu: Navigation, Suche

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