Arma 3
Not enough ratings
SQF Skripts als Datei verwenden
By Joshua9797💾
SQF-Skripts als Datei anlegen und aufrufen.
  • Vorteile und Nachteile,
  • SQF-Skripts im Multiplayer,
  • Event Skripts
   
Award
Favorite
Favorited
Unfavorite
Inhalt
❗[Disclaimer] Es ist keinesfalls meine Absicht Falschinformationen zu verbreiten. Es kann allerdings dennoch sehr leicht vorkommen, dass ich mit meinen Erklärungen nicht komplett oder sogar ganz falsch liege. Ich lerne selbst noch SQF und kann dementsprechend nicht für eine 100% Korrektheit garantieren.

Die Abschnitte sind nach Komplexität sortiert.

Inhalt:
  1. Warum SQF-Skripts als Datei?
  2. Funktionsweise
  3. Event Scripts (Besondere .SQF Dateien)
  4. Warten auf SQF-Skript (Script Handle)
  5. SQF-Skripts im Multiplayer (Lokales & Globales ausführen)

1. Warum SQF-Skripts als Datei?:
Die meisten die schon ein wenig mit dem Eden-Editor gespielt haben, wissen das es in Arma 3 eine Skriptsprache nahmen Status-Quo-Function[community.bistudio.com] (SQF) gibt.

Der am Anfang wohl häufigste Berührungspunkt ist ein "Init-Feld" an einem Objekt, NPC oder diversen anderen Dingen:
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀Init-Feld

Auch sehr häufig begegnet einem die SQF-Sprache in einem Trigger[community.bistudio.com]:

⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀Trigger

Probleme ohne SQF-Datei:
  • Ein Problem, welches sehr schnell auftreten kann, ist der geringe Platz, welcher in einem Init-Feld oder Trigger vorhanden bzw. nicht vorhanden ist. Dadurch werden komplexere Skripts sehr schnell unübersichtlich.

  • Ein weiteres Problem ist die Verteilung der Code-Schnipsel auf eventuell duzende Objekte oder Trigger auf der gesamten Karte im Editor. Dadurch wird es schwer, eine bestimmte Zeile Skriptcode zu suchen.

Lösung:
Skripts jeglicher Art können als .sqf Datei angelegt und aus dem Spiel heraus aufgerufen werden. Das Skript wird also aus dem Spiel ausgelagert.

Vorteile:
  • In SQF-Dateien hat man sehr viel mehr Platz und das Skript wird sehr viel übersichtlicher. Außerdem befinden sich alle Skripts in derselben Datei oder in demselben Ordner, wodurch die Suche nach einem bestimmten Teil eines Skripts erheblich verkürzt wird.

  • Eine gute SQF-Datei kann ohne zusätzlichen Aufwand in eine beliebige Mission eingebaut werden und erfüllt eine für sich abgeschlossene Aufgabe oder Teilaufgabe. Der Missionsbauer sollte sich also keine oder nur wenige Gedanken über das Innere der SQF-Datei machen müssen und kann diese mit maximal ein paar wenigen Modifikationen schnell in seine Mission mit einbauen.

  • In einem SQF-Skript kann man die Funktion "Sleep"[community.bistudio.com] verwenden, welche das Skript für eine angegebene Anzahl Sekunden anhält.

  • Darüber hinaus ist die Gefahr einer versehentlichen Löschung eines Skripts unwahrscheinlich, da man eine SQF-Datei nicht so unachtsam löscht wie ein Objekt oder Trigger im Editor.

  • Ein weiterer nicht sofort ersichtlicher Vorteil ist die Tatsache, dass man die SQF-Datei jederzeit einsehen kann. Wenn man also z.B. die Mission testet und einen Fehler bemerkt, muss man nicht zuerst wieder zurück in den Editor, um sich das Skript genauer anzuschauen.

Nachteile:
  • Das Anlegen einer SQF-Datei kann bei kleinen Skripts mehr Aufwand sein als diese einfach im Editor z.B. in einen Trigger zu packen.

  • Ein weiterer Nachteil ist der, dass bei einem kopieren der Mission die Skript-Dateien nicht mit kopiert werden (z.B. bei einem erneuten abspeichern der Mission unter einem anderen Namen).
    Hierbei muss man von Hand in die alte Missionsdatei gehen und die Skripte in die neue Missionsdatei kopieren.

  • Des Weiteren steht einem das "this"[community.bistudio.com] nicht zur Verfügung, mit welchem man normalerweise in einem Init-Feld auf das aktuelle Objekt referenzieren kann.
2. Funktionsweise:
Eine SQF-Datei befindet sich immer in dem dazugehörigen Missions-Ordner:

⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀Beispiel

Ansonsten würde die Skript-Datei bei einem Export der Mission nicht mit exportiert werden und während der Mission würde das Spiel die Datei nicht finden.

Ausgeführt werden kann eine Skript-Datei mit dem Befehl "execVM"[community.bistudio.com] gefolgt von dem Namen der SQF-Datei in Anführungszeichen (Die Dateiendung .sqf muss auch angegeben werden)
Z.B.:
execVM "test.sqf";

Dieser Befehl führt alles was sich in dem Skript befindet aus und kann z.B. in einem Trigger oder einem anderen SQF-Skript verwendet werden.

Die Skript-Datei kann sich auch in einem Ordner befinden. In diesem Fall muss der Pfad ebenfalls bei dem execVM Befehl angegeben werden. Jeder Ordner wird dabei mit einem Backslash "\" getrennt. (nicht zu verwechseln mit einem normalen Slash "/" !).
Z.B.:
execVM "Ordner\test.sqf";
3. Event Scripts (Besondere .SQF Dateien):
Event Skripts[community.bistudio.com] sind Skripte, die zu einem bestimmten Event ausgeführt werden.

Zum Beispiel gibt es das "initServer.sqf"[community.bistudio.com] Skript welches automatisch aufgerufen wird, wenn der Server startet.
(Mit dem Server ist eigentlich eine Multiplayer Mission gemeint. Also wird das Skript nicht aufgerufen, wenn der tatsächliche physische Server startet, sondern wenn eine Mission ausgewählt wurde und alle einen Slot ausgewählt haben).

Ein weiters Beispiel wäre das "onPlayerRespawn.sqf"[community.bistudio.com] Skript welches automatisch aufgerufen wird, wenn ein Spieler im Multiplayer "Respawned".

Aufgerufen werden Event Scripts dabei nicht wie gewöhnliche Skripts, sondern werden anhand des Namens ganz automatisch vom Spiel erkannt und entsprechend ausgeführt.
Abgelegt werden die Skripts dabei in dem Missionsordner.
Damit das Spiel das jeweilige Skript auch erkennt, muss genau auf den Namen der Datei geachtet werden. Ein "initSerFer.sqf" würde als Beispiel also vom Spiel nicht erkannt werden!
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀Beispiel für initServer.sqf
4. Warten auf SQF-Skript (Script Handle):
Oftmals möchte man warten, bis ein aufgerufenes Skript fertig ist, bevor weiteres geschehen soll. Z.B. wenn man "Sleep"[community.bistudio.com] Befehle in das Skript eingebaut hat.

Hierzu werden zwei Dinge benötigt. Ein "Script Handle"[community.bistudio.com] sowie eine Kombination aus den Befehlen "waitUntil"[community.bistudio.com] und "scriptDone"[community.bistudio.com].

Ein Script Handle identifiziert ein laufendes Skript. Es ist also eine Art ID oder einfacher eine Art Hausnummer für das Skript. Jeder Script Handle ist einzigartig und bezieht sich zu einem bestimmten Zeitpunkt immer nur auf ein Skript.

Der Befehl execVM gibt glücklicherweise einen Script Handle von dem aufgerufenen Skript zurück. Dieser kann entgegengenommen werden und in einer Variable abgespeichert werden.
Z.B.:
meinScriptHandle = execVM "test.sqf";
Der Script Handle wird anschließend verwendet, um mit der Funktion "scriptDone" zu prüfen, ob das Skript fertig durchlaufen ist.
Die Funktion scriptDone gibt dabei ein "Wahr" oder "Falsch" (true, false) zurück, je nachdem ob die Frage "ist das Skript fertig?" zutrifft.
Z.B.:
meinScriptHandle = execVM "test.sqf"; scriptDone meinScriptHandle;
Als letztes brauchen wir noch die Funktion "waitUntil" welche das aktuelle Skript anhält, bis die Bedingung in den geschweiften Klammern "{ }" erfüllt ist.
In diesem Fall wollen wir erst weiter machen, wenn die Funktion scriptDone ein "Wahr" zurückgibt.
Z.B.:
meinScriptHandle = execVM "test.sqf"; waitUntil {scriptDone meinScriptHandle}; Hint "ich werde erst nach dem Skript test.sqf ausgeführt";
5. SQF-Skripts im Multiplayer (Lokales & Globales ausführen):
❗Dieser Abschnitt setzt Kenntnisse über "Multiplayer Scripting" voraus. Einen Guide über dieses Thema gibt es hier.

Der Befehl execVM führt das angegebene Skript nur Lokal aus. Um ein Skript auch Global bei jedem Spieler auszuführen, muss der "remoteExec"[community.bistudio.com] Befehl verwendet werden.

Bei dem remoteExec Befehl wird auf der ganz rechten Seite mit einer Zahl angegeben, wo das Skript ausgeführt werden soll.

⠀0 = Das Skript wird auf dem Server und bei jedem Spieler ausgeführt.
⠀2 = Das Skript wird nur auf dem Server ausgeführt
-2 = Das Skript wird nur bei den Spielern aber nicht auf dem Server ausgeführt.

Z.B.:
"test.sqf" remoteExec ["execVM",0];


Übergabeparameter:
Übergabeparameter so wie sie in dem Guide "Parameter (Übergabe-Werte) in SQF Skripts" beschrieben sind, können folgendermaßen übergeben werden:
[[VariableParameter, "TextParameter"], "test.sqf"] remoteExec ["execVM", 0];


Script Handle mit remoteExec:
Leider ist es nicht möglich den Script Handle eines Skripts zu erhalten, welches mit remoteExec ausgeführt wurde. Der Grund dafür ist eigentlich ziemlich logisch.

Der Inhalt des Skripts ist vollkommen frei definierbar und kann alles Mögliche beinhalten. Außerdem sendet der remoteExec das Skript in den meisten Fällen an mehrere Spieler.

Dabei kann es sehr gut sein, dass das Skript bei dem Spieler Nr1 schneller fertig ist als bei Spieler Nr2. Z.B. könnte das Skript abhängig von der Position des jeweiligen Spielers unterschiedlich lange dauern.

Aus diesem Grund würde ein Script Handle keinen Sinn machen, da dieser in Arma nicht wüsste, wann "Das" Skript fertig ist. Es gibt ganz einfach mehrere Identische Kopien des Skripts die gleichzeitig bei mehreren Spielern laufen.

Das bedeutet aber nicht, dass man keine Möglichkeit hat, herauszufinden, ob sich eine der Kopien des Skripts an einer bestimmten Stelle im Code befindet.
Dazu könnte man z.B. den "publicVariable"[community.bistudio.com] Befehl verwenden welcher ebenfalls in dem "Multiplayer Scripting" Dokument erklärt wird.

Eine weitere Möglichkeit ist es, aus einem großen Skript 2 kleinere zu machen. Dabei würde das erste Skript mit remoteExec zu den Spielern gesendet werden und erst beim Spieler das zweite Skript mit execVM aufgerufen werden. Bei diesem Aufruf des zweiten Skripts wäre es dann auch möglich, einen Script Handle verwenden zu können.

❗Hierbei MUSS man vorsichtig sein und daran denken, dass das zweite Skript bei jedem einzelnen Spieler ausgeführt wird!! Also bei 5 Spielern auf dem Server, wird das Skript dann insgesamt auch 5 mal aufgerufen!
Hier könnte man auch den publicVariable Befehl verwenden, um in einem Trigger auf eine Variable zu reagieren, welche bei dem jeweiligen Spieler auf "Wahr" gesetzt wird. Wenn der besagte Trigger dann nur 1 mal aufgerufen wird, kann man zumindest auf das durchlaufen des Skripts bei dem ersten Spielers reagieren.