[Deutsch] Werte speichern

  • Hallo! Als Teil meiner "Ausbildungsmaßnahme" werde ich in nächster Zeit eine Reihe kurzer, teils sehr spezifischer Tutorials veröffentlichen, vornehmlich,
    damit mein Mod-Team was dabei lernt, aber natürlich kann jeder Modder davon profitieren ;)


    Heutiges Thema: Wie speichere ich bestimmte Werte?


    Vorweg, grundsätzlich kann man meines Wissens nach nur Strings und Integer speichern, und in gewisserweise auch Boleans. Ob man bswp. Kommazahlen speichern kann, weiß ich nicht ... Grundsätzlich habe ich derartiges aber auch noch nie gebraucht.


    Je nachdem, was ich erreichen will, empfiehlt sich eine andere Speicherweise. Grundsätzlich gilt natürlich, je weniger (langfristig) gespeichert wird, desto besser, aufgrund des Memory-Leaks, bzw. der sinkenden Performance bei längeren Spielen durch immer mehr Elemente und Werte. Glücklicherweise sind die meisten Werte ohnehin nur temporär gespeichert.


    1. Variablen

    Die einfachste und am meisten verbreitetste Art, einen Wert zu speichern, ist es, in Scripten Variablen zu setzen. Das geht wie in den meisten anderen Programmiersprachen auch, darüber, sie vorher zu deklarieren und später abzurufen oder zu modifizieren. In Lua geht dies, indem man vorher ein local vor den Variablennamen setzt. Der Name selbst ist absolut frei wählbar, ich empfehle aber leserliche Variablen, die zugleich nicht zu lang sind und am besten englisch sind. Persönlich mag ich den Upper Camel Case lieber, bzw. finde ihn leserlicher, aber das ist euch überlassen. Wichtig ist aber: Groß- und Kleinschreibung müssen beachtet werden, wenn ihr eure Variable hinterher wieder abrufen wollt.



    Beim Deklarieren macht es übrigens keinen Unterschied, ob ihr einen Standardwert sofort oder erst hinterher setzt. Wenn ihr also local VarName setzt, wird dieser automatisch true gesetzt. Ihr könnt aber genausogut sofort einen Wert setzen, wenn ihr ihn braucht:


    Lua
    local VarName = GetNobilityTitle("")
    
    
    if VarName == 4 then 
    
    
    [...]


    Wichtig ist jedoch die Stelle, an der ihr die Variable deklariert. Wollt ihr, dass die Variable zur gesamten Zeit innerhalb einer Funktion verfügbar ist, muss sie irgendwo oben deklariert werden, in jedem Falle aber außerhalb von Klammern. Deklariert ihr innerhalb einer Klammer (damit meine ich if-Bedingungen oder Schleifen), wird der Wert zusammen mit dem end wieder gelöscht. D.h. wollt ihr einen Wert innerhalb einer Klammer modifizieren, muss die Variable vorher außerhalb deklariert worden sein. Nach Ende der Schleife bleibt der modifizierte Wert bestehen.




    Spätestens wenn die Funktion endet, wird der Wert wieder gelöscht.




    2. SetData

    Wollt ihr eine Variable gern in einer anderen Funktion übernehmen, könnt ihr den Wert entweder direkt über die Funktion übergeben





    Code
    function Run()
    	local VarName = GetNobilityTitle("")
    	scriptname_MeineFunktion(VarName)
    end


    oder ihr speichert den Wert für später via SetData("DataName",VarName) und ruft ihn bei Bedarf wieder auf:


    local MyData = GetData("DataName"). Vorsicht aber hierbei, es gibt einen Fehler, wenn die Data nicht existiert. Ihr könnt euch aber absichern:




    Lua
    local MyData = 0
    if HasData("DataName") then
    	MyData = GetData("DataName")
    end


    In SetData können sowohl Strings als auch Integer gespeichert werden - es eignet sich auch, um einen Alias zu speichern. (Ist manchmal nötig, normalerweise können Aliasse auch über Funktionen hinweg verwendet werden, aber manchmal gehen sie "verloren", Gilde ist da ein bisschen launisch)


    Auch Data-Werte werden wieder gelöscht, aber erst bei Beendigung des Scripts, oder via RemoveData("DataName"). Ihr könnt eine Data aber auch global verfügbar machen indem ihr sie mit einem # verseht: SetData("#DataName",VarName). Dann könnt ihr sie auch in anderen Scripten abrufen.


    3. Impacts

    Mit Impacts verlasst ihr die Scriptebene, denn nun könnt ihr einem Objekt einen Wert zuweisen. Impacts sind allerdings immer Zahlen, Komma-Zahlen sind möglich (ich habe oben also nicht ganz die Wahrheit gesagt :/ )




    Impacts sind aber sehr beschränkt, denn ihr müsst für sie vorher einen Eintrag in der Impacts.dbt anlegen, wo unter anderem auch festgelegt wird, für welchen Objekt-Typ ein Impact gelten kann. Dafür haben Impacts einen entscheidenden Vorteil: Sie laufen, falls gewünscht, nach einer bestimmten Stundenzahl ab. Deswegen sind alle Item-Effekte über Impacts geregelt.


    Achtung: Impacts des selben Typs werden gestapelt und der Gesamtwert wird über GetImpactValue("Objekt","ImpactName" oder ID) abgerufen. Wenn ihr einen Impact vorzeitig entfernt, bzw. einen ewigen (-1) Impact entfernen wollt, bedenkt, dass dabei der gesamte Impactstapel entfernt wird. Dieser Fehler wurde einst in den Medikus-Scripten gemacht. Krankheiten senken bekanntlich die Attribute (Impactgesteuert), bei der Heilung wurde jedoch der gesamte Stapel entfernt (sogar das Sternzeichen).


    4. (Im weitesten Sinne) States


    Eigentlich sind states nicht wirklich zur Datenspeicherung gedacht, sondern sie lassen für eine bestimmte Zeit lang ein Script im Hintergrund mitlaufen. States sind dadurch sehr mächtig, allerdings könnt ihr keine neuen States anlegen, denn das logische Maximum, das das Spiel handeln kann ist bereits erreicht. Ihr könnt also höchstens vorhandene States löschen (besser nicht) oder euren Wünschen anpassen.




    5. Properties

    Properties sind der way-to-go wenn ihr einem Objekt viele Variablen zuordnen wollt. Sie werden solange gespeichert, bis das Objekt gelöscht wird, oder falls ihr via RemoveProperty("Objekt","PropName") eingreift. Ihr könnt fast alles, was ihr brauchen könntet, über Properties regeln, ihr müsst halt immer nur überlegen, an welchem Objekt es Sinn macht.




    SetProperty("Objekt", "PropName", Wert).


    GetProperty("Objekt", "PropName")


    HasProperty("Objekt", "PropName")

  • Das ist schon ein guter Überblick, danke sehr!


    Kannst Du noch etwas zum Thema "Alias" sagen? Ich fand das Konzept anfangs wenig intuitiv. Spricht z.B. etwas dagegen, den Alias-Namen als lokalen String zu speichern, um Tippfehler zu vermeiden bzw. besser zu erkennen? Warum wird das in vorhandenen Skripten nur selten gemacht?

  • Ich bin nicht ganz sicher, ob ich verstehe, was du meinst.


    Für was willst/ musst du den Alias auf welche Art speichern?


    Generell brauchst du einen Alias ja nur innerhalb eines bestimmten Scriptes für die Dauer des Scriptes. Der Alias hilft eigentlich nur fürs Scripten selbst, weil er beliebig ist (naja, fast, einige sind fest belegt, wie z.B. "dynasty", "Destination" oder "SIM") Brauchst du die Identifizierung später nochmal, ist es immer besser, die ID zu speichern und bei Bedarf einen Alias im Script zu holen/zu erschaffen.