Hallöchen liebe Community,
Ich dachte mir, dass es in Zeiten von Stardew Valley oder anderen Games dieser Art mal ein kleines Farmsystem vorzustellen, welches ich mal ein bisschen durch-evented habe und welches Prinzipiell ohne Script in der Erstellung auskommt, aber durchaus in andere Plugins (z.B. Tag-Nacht-System) problemlos eingebunden werden kann. Ich weiß, dass es auch schon genug, gut laufende Ansätze mit Plugins gibt, trotzdem wollte ich einmal eine Alternative geben.
Vorweg ein paar Informationen:
Schwierigkeitsgrad: Mittel bis Fortgeschritten-> Ich setze für dieses Tutorial grundlegendes Verständnis über das Verwenden von Variablen als Arrays voraus (Hier ein wunderbarer Einstieg), aber auch WIssen über Script Calls (Hier eine gute Sammlung)
Benötigte Plugins: Keine
Desweiteren wird in diesem Tutorial davon ausgegangen, dass das Farming nur auf EINER einzigen Map stattfindet, bei weiteren Maps, bräuchte man einfach eine entsprechende weitere Map-Variable.
Jetzt aber ans Eingemachte:
Schritt 1 - die Arrays:
Wir brauchen im Allgemeinen 4 Variablen, die wir dann gleich zu Spielbeginn als Arrays initialisieren.
- Pflanzenart: Hier merken wir uns, WAS für Pflanzen anbaubar sind, z.B. 0=Nichts, 1=Monster, 2=Bösewicht, 3=Ralph (natürlich gehen auch andere, bessere Pflanzenarten, für die natürlich auch die entsprechenden Grafiken benötigen, welche in diesem Tutorial NICHT geliefert werden)
- Pflanzenstatus: Hier wird der aktuelle Status der Pflanze gespeichert, also 0=keine Pflanze; 1=Setzling (trockenes Land); 2=Setzling (bewässert); ...; X=erntbar (X steht für die letzte Stufe, dazwischen sind im Prinzip noch weitere Schritte ergänzt werden)
- Pflanzenänderng: Dieses Array brauchen wir, um eine Änderung in unserem einzigen parallelen Prozess anzusprechen; 0=nichts muss getan werden; 1=es muss was getan werden vom Event; wenn nichts getan werden muss, wird der parallele Prozess auch schnell beendet
- PflanzenEventId: Unsere einzige normale Variable; das ist die EventID, mit der unser paralleler Prozess gecallt wird bzw. für dieses Event wird die Änderung vorgenommen
- (PflanzenStartTag: Das könnte unser Array werden, wo dann für ein Tag-Nacht-Zeit-System der aktuelle Tag gespeichert wird, über den dann später geprüft werden kann, ob die Pflanze z.B. von alleine ein Stück gewachsen ist; diess Array ist aber nur Bonus und wird in diesem Tutorial nicht weiter verarbeitet)
- (maxAnzPflanzenEvents: Es kann Sinn machen gleich im Setup festzulegen, wie viele Pflanzen maximal möglich sind, sodass unser paralleler Prozess auch entsprechend arbeitet, dies ist aber eher Feinschliff.)
In diesem Tutorial sind die entsprechenden Variablen (welche als Arrays dienen werden, die Nummern 25-29, wobei 29 nur als Ansatz gezeigt wird, aber nicht weiter ausgeführt.
Schritt 2 - Das Setup:
Wir machen unser Setup. Dazu müssen wir unbedingt wenigstens unsere Variablen alls Arrays deklarieren, denn sonst können wir sie nicht als solche verwenden. Dies sollte zu Spielbeginn geschehen und sieht dann so aus:
Zur Erläuterung: der eigentliche Variablen-Inhalt steht in den eckigen Klammern, also im Beispiel der Variablen 25 die [,,0,0,0,0,0,0]. Bei der Variablen 27 geben wir mit, dass jedes Pflanzen-Event "geändert" und damit geprüft werden muss (für das Bild, welches auf der Map gezeigt wird).
Tipp/Hinweis: Macht all eure Pflanzen Events hintereinander. Es ist kein Problem, vorher und nachher etwas Anderes zu haben, aber die Events, wo gepflanzt werden soll, sollten alle hintereinander stehen, da es sonst zu Problemen mit dem Parallelen Prozess (weiter unten) kommt.
Frage: Dizzy? Warum die 2 Kommas?
Dizzy: Ganz einfach! ein Array beginnt immer mit dem Index 0 (also die erste Stelle ist Position 0). In meinem Beispiel ist aber die erste EventID, wo eine Pflanze ist, auf Position 2, also ist vor dem ersten Komma die Position 0, dann kommt 1 und dort wo die erste Zahl steht ist Position 2. Die davor brauche ich ja nicht weiter. Wenn z.B. die Farm bereits bepflanzt sein soll beim Betreten der Map, können statt der 0 auch andere Zahlen eingetragen werden.
Anmerkung: Dieser Array kann beliebig erweitert werden, je nachdem, wie viele Pflanzen-Events auf der Map existieren sollen, je mehr, desto mehr schreiben.
Frage: Warum ist bei Array 26 nichts in den eckigen Klammern?
Dizzy: Weil ich dafür noch keine Daten brauche (für dieses Tutorial), ich aber den Array deklarieren muss, sonst kann er nicht verwendet werden.
Frage: Variable 28...?
Dizzy: ...ist die einzige normale Variable, die kein Array ist. die 2 ist die Position des ersten Pflanzenevents in Array 25. Dies muss geändert werden, sofern das erste PflanzenEvent erst später oder früher kommt.
Was wir nun noch beachten müssen: bei einem Spieler-Transfer auf die Map, wo alle Pflanzen sind, müssen wir unseren Änderungs-Array (hier: 27) mit 1en bestücken wie oben, damit die EventBilder geupdatet werden beim erneuten Betreten der Map.
Schritt 3 - Unsere kleine Farm
Dies ist also nun unsere Map, wo gefarmt werden soll. Wie oben schon beschrieben, ist es durchaus möglich, weitere Maps zum Anbauen zu haben, dafür bräuchten wir aber Minimum noch eine weitere Map-Variable.
Es werden 2 Dinge aus dem Screenshot ersichtlich:
· Es gibt mehr Events als nur unsere Pflanzen-Events. Das Event ganz unten ist z.B. unser Helfer oder jemand, der uns zu einer anderen Map bringt. Das Event oben rechts ist unser Paralleler Prozess, der das Aussehen unserer Pflanzen updatet (und sollte wenn möglich nicht für den Spieler zugänglich sein). Beide Events sind 1 und 9 (deshalb im Setup die leeren Stellen 0 und 1 in den Arrays)
· Es sind nicht alle möglichen Tiles belegt mit möglichen Pflanzen. Eine Erweiterung ist einfach, wenn wir dafür die Arrays erweitern.
Schauen wir uns nun unseren Parallelen Prozess in der Ecke an:
Zur Erläuterung: Dieser Prozess geht ALLE möglichen Pflanzen-Events durch und updatet das Aussehen im Gew. Ereignis „Pflanzen-Wachstum“. Wie macht er das?
Zuerst wird Variable 28 (unsere PflanzenEventID) auf den kleinstmöglichen Wert (also das kleinste Event, welches eine Pflanze darstellt auf dieser Map) gestellt. Event 2 ist eine Pflanze. Passt.
Alles Nächstes wird eine Schleife vorbereitet, d.h. es wird das Gew. Ereignis "Pflanzenwachstum" (siehe unten) aufgerufen. Anschließend folgen 2 Prüfungen. 1) Wenn die PflanzenEventID größer-gleich 8 ist, soll die Schleife unterbrochen werden und der Parallele Prozess wäre beendet. 8 deshalb, weil dies in diesem Tutorial die größtmögliche Event-Nummer ist, welches eine Pflanze sein könnte. Wie im Setup beschrieben, sollte hier vielleicht eine extra Variable deklariert werden, welche hier einfach abgefragt wird, anstatt der 8, aber diesen Schritt überlasse ich mal dem schlauen Developer von heute. Als Zweites gibt es die Abfrage, dass, wenn die PflanzenEventID kleiner als die max. EventID einer Pflanze (in diesem Tutorial 8 ) ist, die jetzige PflanzenEventID um 1 erhöht und wieder am Beginn der Schleife anfängt, das Gew. Ereignis aufruft usw.. (Prinzipiell ist dies eine einfache for-Schleife mit Abbruch-Bedingung)
Jetzt sollten wir uns unser ersten gew. Ereignis ansehen, das Pflanzenwachstum:
Zunächst werden wir erschlagen von sehr vielen Script Calls.
(Anmerkung: Man hätte auch ein sehr großes Script machen können mit all den abfragen, aber im Rahmen dieses Tutorials wollte ich zumindest ein paar gängige Funktionen beibehalten)
Die erste Abfrage, die alle weiteren Argumente einkreist, ist die Abfrage, ob überhaupt irgendetwas geändert werden muss (Array 27 ist unsere Änderung, die 28 unsere EventID der Pflanze). Wenn nichts passieren muss, warum dann unnötig oft das Gew. Ereignis ausführen? Und vielleicht ändert sich auch nur eine einzige Pflanze z.B. wenn wir nur sie bewässern, dann wird auch nur einmal dieses Ereignis aufgerufen.
Die weiteren folgenden Abfragen sind alle fast gleich bis auf den „setImage“-Befehl, der das Aussehen unserer Pflanze ändert/anpasst. In Hochkommas steht der File, wo das Bild ist und die Zahl stellt die Position des Bildes dar. Ansonsten wird für jede Pflanzenart geprüft, um welche es sich handelt, danach wir geprüft, in welchem Stadium sie ist (Setzling, Blühen, gewässert, …), dann wird das Bild entsprechend gesetzt und danach wird der Änderungsarray für das entsprechende Pflanzen-Event wieder auf 0 gesetzt. Dies wiederholt sich für alle Pflanzenarten und für jedes Stadium.
Als kleines Rechenbeispiel: Bei 5 Pflanzenarten und 6 verschiedenen Stadien der Pflanzen macht dies eine Anzahl von 6x6x6x6x6 Möglichkeiten, also 7776. Es wäre natürlich möglich, für jede Pflanzenart ein separates Gew. Ereignis zu machen, der dann die Bilder für jeden Pflanzen-Status ändert.
Weiter geht es mit dem Event, wenn mit einer Pflanze oder einem „Ernte-Tile“ interagiert wird:
Das ist auch schon alles. In jedem Event, mit welchem wir etwas anbauen/abbauen/ernten/bewässern wollen, wird nur das gew. Ereignis „Pflanzeninteraktion“ aufgerufen. Diese hat es allerdings etwas in sich und soll nun etwas genauer erläutert werden.
Was passiert? Als erstes wird mit dem Array 26 überprüft, ob überhaupt schon etwas gepflanzt wurde oder nicht (0). Wenn nicht, dann kommt die Abfrage, ob gepflanzt werden will, wenn „Ja“ gewählt wird, dann kommt die Auswahl der Pflanzenart. Entsprechend der Auswahl werden dann alle Variablen und Arrays entsprechend gesetzt heißt:
· Array 25 an der Position des Pflanzen-Events auf die entsprechende Sorte gesetzt (siehe Setup-Beschreibung)
· Array 26 wird an gleicher Stelle auf 1 gesetzt (also das erste Stadium
· Array 27 wird eine 1 mitgegeben, sodass wir wissen, dass sich etwas geändert hat
· Variable 28 wird auf DIESE Event-ID gesetzt (da gew. Ereignisse quasi in das Event eingebettet werden, in dem sie aufgerufen werden, bleibt die Event-ID des Pflanzen-Events erhalten)
· Das gewöhnliche Ereignis „Pflanzenwachstum“ aufgerufen, welches wieder das Bild des Events anpasst
Es handelt sich hier nur um einen groben Aufbau. Abfragen für Items, ob entsprechende vorhanden sind und dass diese dann abgezogen werden müsste ebenfalls hier geschehen.
Weiter würde es gehen mit dem Bewässern. Spricht der Spieler erneut das gleiche Event an, ist der Status bereits hochgesetzt worden. Hier könnte nun abgefragt werden, ob die Pflanze bewässert werden soll. Es werden wieder die entsprechenden Arrays gesetzt (die Pflanzensorte muss nicht erneut gesetzt werden, da diese beim erstmaligen Einpflanzen ausgewählt und gesetzt wird) und wieder unser Wachstumsereignis aufgerufen.
Den einzigen wirklichen Unterschied bildet das Ernten, denn hier wird Array 25 auch wieder auf 0 gesetzt und ggf. die Items verteilt.
Frage: Kann ich auch so etwas wie einen Killer-Ralph-Angriff simulieren, der alle Ralph-Pflanzen tötet?
Dizzy: Klar! Setze einfach die Variablen alle zurück oder auch nur ein paar, setze den Änderungs-Array auf 1 und betrete die Map und alles ist vielleicht weg.
Frage: Können die Pflanzen auch Wachstumsperioden haben, also eine Pflanze wächst an einem Tag, eine andere aber vielleicht einen Tag mehr?
Dizzy: Mit etwas mehr Aufwand ist dies machbar. Im Setup oben habe ich bereits einen Beispiel-Array für den Tag des Einpflanzens beschrieben. Diesen müsste man beim Einpflanzen einmal setzen und dann in einem parallelen Prozess bzw. beim Map-Transfer auf unsere Farm-Map prüfen und mit der Tag-Variable, die uns unser Zeit-System liefert, vergleichen und dann die Arrays entsprechend setzen. Dies würde aber dieses Tutorial sprengen.
Frage: Wenn es gerade auf meinen Maps und der Farm regnet, kann ich dann das bewässern überspringen?
Dizzy: Dies ist möglich, sofern dem Wetter eine variable zugeordnet ist. Dann einfach beim Setzen der Variable ebenso die entsprechenden Arrays wieder setzen.
Schlussworte
Dieses Tutorial erfordert doch recht vertieftes Basiswissen und ist sicherlich nicht für jeden etwas. Trotzdem wollte ich zeigen, dass vieles auch ohne großen Ressourcen-Aufwand möglich ist mit dem RPG Maker (MV, aber es ist auch ähnlich mit anderen Makern machbar, nur die Script-Befehle müssten angepasst werden). Ich kenne viele, die geschrieben haben, dass sie unzählige Schalter brauchten und auch viele Variablen oder Schalter nutzen müssten. Dieses Tutorial bietet eine grundlegende Herangehensweise, die in ihrem Grundgerüst gerade einmal 4 Variablen (Arrays) benötigt, 2 gew. Ereignisse und prinzipiell für eine große Anzahl an verschiedenen Pflanzenarten und unterschiedlichen Entwicklungsstadien möglich ist.
Die Grundlagen sind gelegt, ich hoffe, es gab einige AHA-Momente und Inspirationen und nun: Viel Spaß beim Anbauen und Makern!
Oh nein! So viele Ralphs tun der Welt nicht gut!
Der einzigwahre-one-and-only-in-dritter-Person-von-sich-redende Dizzy
P.S. Sollte ein tutorial-Projekt gewünscht werden, kann ich vielleicht etwas kleines zaubern.
Edit: Natürlich sollten Danksagungen für die Unterstützung von anderen nicht fehlen. Also Danke an die tolle Community! Ok...zu allgemein. Besten Dank an Meliodas und Nico für ihre Zeit, in der sie mir armen Vogel geholfen haben. Aber natürlich Jitsu , Kirimoar und waynee95 soll hier gedankt werden. Ihr seid toll.