Hallo Brotfische,
oft sehe ich hier ein großes Missverständnis von Includes und Code-Trennungen.
Deshalb möchte ich hier noch einmal versuchen ein wenig mit diesen Fehlern aufzuräumen.
Was ist eigentlich ein Include?
Viele wissen dies nicht. Viele denken, das ist etwas ganz anderes als eine .pwn Datei, schließlich steht da ja .inc.
Allerdings ist das ein großes Missverständnis, denn im Endeffekt ist es identisch.
Die Endung soll nur symbolisieren, dass es sich um ein Include handelt und kein eigenständiges Skript.
Was ist der Unterschied?
Ein eigenständiges Skript wird kompiliert. Ein Include wird nicht kompiliert.
Wieso muss ein Include nicht kompiliert werden?
Ganz einfach, stellen wir uns mal folgende Situation vor:
//Im Gamemode
#include <a_samp>
#include <meinInclude>
main() {
print("%d",GetMyFunction());
}
//In der Datei - meinInclude.inc
stock GetMyFunction()
{
return 1;
}
Alles anzeigen
Kompilieren wir jetzt den Gamemode, sieht das nach dem pre-compile Prozess so aus:
//Hier würde alles stehen, was in a_samp steht.
stock GetMyFunction()
{
return 1;
}
main() {
print("%d",GetMyFunction());
}
Wir sehen also, es wird "einfach nur" (soo leicht ist das auch nicht, aber dazu später mehr) in die Datei kopiert.
Deshalb müssen wir Includes nicht kompilieren, da sie vom Gamemode kompiliert werden.
Und deshalb müssen wir in den Includes z.B. auch nicht mehr #include <a_samp> schreiben, da ja das schon im Gamemode steht und das somit auch für das Include gilt.
Was bringt das jetzt?
Das wurde ja schon oft gesagt, man kann nun viele Sachen auslagern.
Okay, aber was genau bedeutet das?
Logikfehler
Viele machen hier einen großen Logikfehler.
Da viele sich die Struktur ihres Gamemodes bei einem Godfather abschauen, verstehen sie oft nicht, wieso diese so schlecht ist.
Auf den Ersten Blick sieht das ja auch gut aus, ich meine, alle defines Oben, alle Variablen oben, alle Commands und publics in der Mitte und ganz unten alle "stock - Funktionen".
Ja cool, jetzt wo wir also Includes nutzen können, packen wir alle Variablen in ein Include, alle Commands, alle publics und alle "stock - Funktionen" und voila. Skript aufgeräumt xD
(No Joke, das machen sehr viele und sind fest von dieser Struktur überzeugt).
Wieso ist das aber schlecht?
Genau das versuche ich jetzt hiermit zu vermitteln, das ist NICHT der Sinn oder Vorteil eines Includes.
Da könnte man sich diesen ganzen Prozess gleich schenken.
Denn denken wir das weiter und es entsteht jetzt ein Fehler beim Haussystem.
Wie finden wir in so einem System den Fehler?
Ja Herzlichen Glückwunsch, jetzt sogar noch schlechter, da wir in 4 Dateien Suchen, alle Variablen dafür finden müssen, alle Funktionen, alle Befehle und überall in jedem public steht mal ein fitzelchen Code von dem System xD
Kein Wunder also, dass soviele Skripte verbuggt sind, wie will man da auch irgendwas finden.
Deshalb posten hier auch so viele Menschen 500 Zeilen Code und sagen, ja wo ist denn da der Fehler, bla bla funktioniert nicht.
Was wäre ein besserer Ansatz?
So, hier kommt jetzt das Wichtige.
Man packt ein einzelnes System in ein Include.
Und damit meine ich nicht nur den Hauptteil des Systems, sondern ALLES.
Und um noch einen drauf zu setzen, macht sowas:
//Include
static alleMeineVariablen;
static stock FunktionNurHier() { }
stock SetVar(x)
{
alleMeineVariablen = x;
}
CMD:fürDasInclude(playerid) {
}
Alles anzeigen
Hier sehen wir sehr viel static.
Das hat mehrere Gründe:
-
static ist nur im Include verfügbar. Das heißt es ist sichergestellt, dass diese Variable NUR dort verändert wird.
Sprich, gibt es ein Fehler mit dem System, MUSS er dort zu finden sein. - Ein weiterer Vorteil ist, dass man einfache Namen verwenden kann und sich nicht darum kümmern muss, dass diese in anderen Include auch nochmal verwendet werden.
Da die Variablen ja immer für jedes Include abgegrenzt sind. Selbiges gilt für Funktionen, die man als static deklariert.
PS: Nur globale Variablen im Include static machen, nicht Lokale!! Das wäre etwas völlig Anderes. - Es sollte nur mit Callbacks und Hooks gearbeitet werden, die alle in dem Include landen und dort ALLES gesteuert wird, jede Logik.
Denn wenn man dann einen Fehler hat, weiß man genau, wo man suchen muss.
Zusammenfassung
Weg von der Trennung von Bezeichnungen, wie new, public, stock...
Diese Trennung bringt rein gar nichts, man muss die LOGIK in einem Gamemode trennen.
Dafür eigenen sich Includes ideal.
Es sind im Endeffekt auch nur .pwn Dateien, die ihr mit Pawno schreiben könnt.
Und kompiliert, wird nur das Gamemode.
Zusätzliche Informationen:
Schneller & strukturierter skripten
Es ist auch nicht notwendig, dass ihr ein Selfmade anfangt und das dann konsequent macht (obwohl das ser sinnig wäre).
Ihr könnt auch anfangen neue Systeme, die ihr in ein GF implementiert, versucht so umzusetzen.
In diesem Sinne, ich hoffe ich sehe bald mehr Leute die das nutzen und schönere Fragen in der Scripting Base.
Mit freundlichen Grüßen
Euer Kalle