Hallöle. Let's have a talk.
Bereits einige Monate lang und im Rahmen mehrerer (sowohl eigener als auch fremder) Projekte, hat sich bei mir eine gewisse Unzufriedenheit breitgemacht was die so called "Entwicklung" von Minecraft Plugins angeht.
Ich bin ein Mensch der offen entwickelte Standards favorisiert und sich für durchdachte und saubere Planung sowie intensive Dokumentation von Projekten einsetzt.
Mit dieser Einstellung überfordere und nerve ich sowohl einige Arbeitskollegen als auch den Großteil der Minecraft "Devs" or whatsoever.
Ich meine nicht, dass wir losrennen sollten und für jedes Minecraft-Plugin ein RFC-Dokument aufsetzen müssen.
Nein, es handelt sich nach wie vor um ein Spiel und hat bei real-world Standards nichts zu suchen.
Zahlreiche Kinder und Jugendliche haben in den vergangenen Jahren durch Minecraft die Freude am Programmieren gefunden und sich auf die Fahne geschrieben Java zu lernen und haufenweise Minecraft-Plugins zu fabrizieren.
Nun gibt es einige Gruppen von Leuten die man beschreiben könnte - ich nehme eine als Beispiel, beschreibe die Gedankengänge und zeige auch dessen Konsequenzen auf.
Eine kleine Situation die sicherlich jedem Serverbetreiber, sei es damals oder heute, schon mal in einer ähnlichen Form entstanden ist.
Der über alles erhabene Einsteiger
"Essentials ist ein Krampf, bäh GriefPrevention is ja auch irgendwie doof und WorldEdit ist ja total langsam und laggy und auch Schrott. Das schreib ich viel besser selber."
Dies ist die tägliche Einstellung eines jungen Programmiereranfängers, der die ersten Erfolge seiner Lernfortschritte erntet, indem im Chat tolle bunte Nachrichten erscheinen und man einen Kontostand aus einerYAML Datei... pardon - "Bukkit Configdatei" auslesen und überschreiben kann. Alles selbst gemacht und mittlerweile komplett fehlerfrei* und fancy**.
Getrübt von den schnellen Erfolgen die das Spiel und die ausgiebige Dokumentation sowie diverse YouTube-Kasper ermöglicht haben, fängt der Programmieranfänger nun rasch an die eingebürgerten und jahrelang existenten Plugins wie Essentials und co. in Frage zu stellen.
(An dieser Stelle sei gesagt, dass ich Essentials oder sonstige Plugins nicht zwangsläufig mag, empfehle oder sonst irgendwie werte - diese dienen bloß als Beispiele.)
Man legt ein neues Projekt in Eclipse an und coded auch gleich los!
/spawn
/bal
/home
/tp
/tpa
bla bla.
Alles läuft und schaut toll aus - die Chatnachrichten sind farbig und ansprechend für den Benutzer (aus Sicht des Programmierers).
Hier und da kommen auch tolle Scoreboards zum Einsatz, die man eigentlich gar nicht braucht, aber da man mittlerweile auch gelernt hat wie man diese geklauten Codeschnipsel "richtig" nutzt, baut mans mal mit ein - ist ja cool shit.
Danach lädt man sein stolzes Werk zusammen mit ein paar schalen Sätzen in der Beschreibung auf Bukkit, Spigot und co. hoch und erfreut sich an den ersten 100 Downloads.
Ein weiteres All-In-One Plugin ist geboren.
Es folgt ganz und gar der Nase des Programmierers und sofern man doch eine Spur Dynamik in Form von Konfigurationsmöglichkeiten aufbringt, beschränkt sich dies meist auf ein paar Startwerte, Nachrichten und vermutlich auch direkt der Speicherung von Nutzdaten, weil die Configs dafür ja super herhalten.
Der Server Besitzer freut sich anfangs sehr über das Plugin, bis er feststellt, dass Warps doch was feines wären und fragt dies sogar bei dem Programmierer an.
Der Programmierer des All-In-One Plugins hat kein Plan was Warps sind und meint, dass das eh keiner braucht.
Daraufhin sucht der Server Besitzer einfach ein anderes Plugin mit dem gewünschten Funktionsumfang.
Er findet UltimateBukkitEssentialsOneXS von einem anderen Programmierer, der bereits auf mehreren Servern war und meint, dass Warps schon mit rein sollten.
Der Serverbesitzer merkt aber nun, dass UltimateBukkitEssentialsOneXS eine ganz eine Config hat und im Ordner noch so eine komische database.sqlite Datei auftaucht.
Wie soll er jetzt die Daten seiner 70 aktiven Stammspieler alle übertragen? Er wendet sich hoffnungsvoll an beide Programmierer.
Diese konzentrieren sich erstmal auf einen digitalen Schwanzvergleich - schließlich ist man selbst ja der bessere Dev und hat das coolere Plugin.
Einer von beiden weiß nicht was SQL ist und soll und der andere meint, dass YAML Dateien ein Rotz sind.
Der Andere meint, dass ........
Und an dieser Stelle ein Cut um die Ereignisse zusammenzufassen:
Zwei Programmierer haben jeweils ein Plugin programmiert um das Gleiche zu tun: Spawns setzen, Teleportieren, Economy etc.
Beide bauen auf die Möglichkeiten die sie kennen und persönlich favorisieren. Die Umsetzung erfolgt nach Augenmaß des Programmierers.
Es ist keine nennenswerte Architektur weit und breit zu sehen.
Ein Serverbetreiber, der nun eins dieser Plugins für seine Spieler bereitstellt, bindet sich an den einen Entwickler und darf hoffen, dass dieser nicht schlagartig den Kurs ändert.
Sollte der Serverbetreiber sich nun von diesem einen Produkt trennen wollen, entwertet er seine Daten, sofern das andere Produkt nicht in der Lage ist, die genaue Datenstruktur der genutzten Version des anderen Plugins zu interpretieren und zu konvertieren.
Ein gewiefter Serverbetreiber ist in den meisten Fällen auch in der Lage, mit etwas Zeit und Mühe selbst ein kleines Skript zu entwerfen, dass ggf. eine YAML Datei ausliest und in die passenden Tabellen umformt.
Das erfordert allerdings, dass der Serverbetreiber Erfahrung mit beiden Technologien hat und bereit ist diese Prozedur bei jedem Wechsel durchzuspielen.
Sowas ist weder spaßig noch wirtschaftlich noch sonst irgendwie toll und ein Zustand der solche Patchwork-Maßnahmen erzwingt sollte tunlichst vermieden werden.
Sollte der Serverbetreiber nicht über das nötige Know-How zum basteln verfügen, dann steht es nun schlecht um die Daten unserer aktuellen Spieler.
Und sollte der Wechsel z.B. aufgrund eines Sicherheitslecks unausweichlich sein, opfert man die Spielfortschritte seiner Spieler und vergrault einen Großteil davon sehr schnell - besonders, wenn das öfters passiert.
Wir haben also zwei Programmierer, die zwar lernen mit Java zu programmieren in Form von Minecraft Plugins - sich jedoch auf ihre Eigeninnovation konzentrieren ohne Rücksicht auf Verluste und dabei auch gelegentlich eine Arroganz aufbauen, die sie sich gar nicht leisten könnten, statistisch betrachtet.
Dies kriegen Serverbetreiber zu spüren, indem sie in die oben genannte Situation geraten und damit ihrer Community erheblichen schaden zufügen können.
Und dabei ist das erst der Anfang... wir sprachen bisher von einem Plugin, dass alles kann.
Was ist, wenn ich zwei Plugins habe, die aber zusammenarbeiten sollen? Oh nose.
Die Liste der Fettnäpfchen ist lang.
Keiner Partei kann man nun so wirklich die Schuld geben.
Die Programmierer sind in der Regel Anfänger und wollen lernen und ihre Erfolge mit anderen teilen - ohne Garantie für irgendwas - it's all fun and game.
Der Serverbetreiber ist nicht automatisch immer ein Technik-Crack sondern meist eher jemand der sozial begabt ist und eine Vision hat, die er gerne mit anderen umsetzen möchte.
Nun, jetzt wird es langsam Zeit von dem negativen Gelaber abzuweichen und auch mal einen Lichtblick zu präsentieren.
Ein Plugin namens Vault.
Vault selbst ist nicht der heilige Gral, um den es geht, sondern viel eher das einzige wirklich bekannte Beispiel.
Es nutzt nämlich einen Teil der Bukkit-API, der niemals sein volles Potenzial erreichen konnte, da er schlicht von 99,99% der Programmierer ignoriert wird.
Was der Bauer nicht kennt, isst er nicht. Basta.
Ich spreche von der Service-API.
Für die Programmierer hier eine kurze (englische) Einleitung dazu aus dem Jahre 2011 (wie schon gesagt.... es wird ignoriert, also gibts auch kaum aktuelle Hilfestellungen): Bukkit Services API Intro
Die Service-API ist grob formuliert eine Ansammlung von Definitionen und Implementierungen - hier als Service und Provider bezeichnet.
Was bedeuten diese zwei Begriffe im Zusammenhang mit Bukkit & Minecraft bzw. Java und wie sollte ich sie behandeln?
Zuerst sei dazu gesagt: Behandelt sie getrennt voneinander.
Die Definition wird in Java durch ein Interface realisiert.
Übersetzen wir diesen Begriff mal: Interface -> Schnittstelle.
Was definiere ich denn in einer Schnittstelle? (Achtung: Java-spezifische Begriffe könnten auftauchen)
Mit meiner Schnittstelle gebe ich die gewünschte Struktur und erwartete Verhalten von JEDER Implementierung vor.
- Ich bestimme die Methoden die existieren müssen
- Ich bestimmte die Parameter und Rückgabe-Typen dieser Methoden
- Ggf. beziehe ich weitere als notwendig für die Implementierungen erachtete Schnittstellen mit ein (z.B. Serializable, Cloneable)
- Rein auf den Code bezogen: Allerhand In-Code-Documentation a la JavaDocs um gewisse Regeln an Ort und Stelle nochmal schriftlich festzuhalten
Kurzum lege ich jegliches Aussehen und Verhalten fest, dass ich von einer Implementierung erwarte.
Jedoch wird dort keine Zeile irgendeine Logik enthalten, geschweige denn welche, die sich mit der tatsächlichen Lösung befasst.
Die Schnittstelle dient der Beschreibung (Definition) wie eine Lösung auszusehen hat.
Vault zum Beispiel liefert ein paar solcher Schnittstellen, nehmen wir hier mal das bekannteste Beispiel: Economy.
Vault Economy Schnittstelle
Hier werden haufenweise Methoden mit entsprechenden Beschreibungen definiert, für diverse Eigenschaften die ein gutes (virtual-) Economy-Plugin bieten sollte.
Sowohl zum Auslesen als auch zum Bearbeiten.
Dazu gehören unter Anderem:
- Name der Währung
- Name der "Unterwährung" (Cent z.B.)
- Entsprechende Namen in der Pluralform
- Die Möglichkeit eine Zahl inkl. Nachkommastellen zu formatieren
- Den einen Spieler Geld auf das Konto des anderen Spielers zu überweisen, mit der Möglichkeit das Ergebnis der Transaktion auszuwerten (EconomyResponse)
Und zahlreiche Weitere Features...
Dazu überall Java-Doc Kommentare mit Hinweisen an das
Seht ihr dort irgendwo eine Zeile, welche die beschriebene Funktionalität umsetzt?
Ich auch nicht!
Das ist auch nicht Aufgabe der Schnittstelle.
Nun - jetzt da wir definiert haben wie ein Economy Service auszusehen und sich zu verhalten hat, kann man hingehen und eine Implementierung erschaffen.
Im Falle von Vaults Economy Service haben das auch einige Leute getan.
15 Economy Plugins sind bereits auf der Pluginseite von Vault offiziell aufgelistet, welche allesamt die Economy Schnittstelle implementieren und hoffentlich gemäß der definierten Regeln die gewünschte Logik bereitstellen.
Wenn nun ein anderes Plugin daherkommt und über die Economy-Schnittstelle von Vault mit welchem Economy-Plugin auch immer kommunizieren will, dann geht er zur Bukkit Services-API und fragt einen Provider an.
Provider = Implementierung
Jedes Economy-Plugin registriert seine eigene Implementierung für die Economy-Schnittstelle bei Bukkit.
Und jedes Plugin, dass mit einem Economy-Plugin reden will, geht zu Bukkit.
Es läuft alles bei Bukkit zusammen - bzw. in der Service-API von Bukkit.
Wenn ein Provider angefragt wird, wird Bukkit, falls ein oder mehrere Provider vorhanden sind, ein dem Plugin unbekanntes Objekt zurückgeben, welches aber zuverlässig die Regeln der Schnittstelle befolgen sollte.
Die Vorteile die sich daraus ergeben sind folgende:
- Ich muss als Pluginentwickler mich nicht darum kümmern jedes Eco-Plugin auf Erden zu unterstützen und gesondert anzusprechen, wenn die bekannte Economy-Schnittstelle ansprechen kann und einfach sage "Das Plugin erfordert ein Economy-Plugin, dass Vaults Economy-Schnittstelle implementiert hat."
- Ich als Serverbetreiber kann bequem zwischen diversen Plugins hin und her wechseln, solange diese allesamt die Economy-Schnittstellen richtig implementieren, ohne dass das den Betrieb der anderen Plugins beeinflusst.
Das ganz ganz oben genannte Problem mit den unterschiedlichen Datenformaten ist zwar noch nicht gelöst damit, jedoch schonmal das Problem der Zusammenarbeit der Plugins.
Was wäre wenn man sich hinsetzen täte und z.B. Import- und Export-Methoden in der Schnittstelle definieren würde und dazu ein erforderliches Datenformat dokumentiert?
Jedes Plugin wäre noch immer frei wie ein Vogel seine Daten in jedem gewünschten Format zu speichern - jedoch muss es eine Möglichkeit bieten seine Daten in ein unabhängiges Format zu konvertieren und auch Daten aus diesem unabhängigen Format heraus zu interpretieren.
Dies ist nur einer von vielen Ansätzen womit man auch solche Probleme behandeln könnte.
Nun aber mal langsam genug der Rederei.
Ich hätte ziemlich Lust darauf, mit ein paar interessierten Personen aus diesem Forum ein kleines Gremium aufzubauen um ein paar solcher Schnittstellen zu diskutieren und letztlich zu definieren.
Dazu sollte dann jeweils eine Referenz-Implementierung folgen - zu Lern-, Demonstrations- und Testzwecken für Endbenutzer und Entwickler.
Dies möchte ich in einem offenen Rahmen tun, wo jeder dazu beitragen kann.
Dieses "Gremium" soll dann die Integrität der Schnittstellen bewahren und die vorgeschlagenen Ideen gemeinsam bewerten, bevor diese veröffentlicht werden.
Rückwärtskompatibilität und Versionierung sind essentiell für diese Schnittstellen, da man das ganze vergessen kann - wenn jeden Tag neue Methoden definiert werden und der Standard nicht statisch genug ist. Zu dieser Problemstellung habe ich übrigens auch bereits funktionierende Lösungen - jedoch würde das allmählich den Rahmen sprengen.
Stellt euch das ganze ungefähr in diesem Stil vor: https://github.com/DefinitelyTyped/DefinitelyTyped
Eine Ansammlung zahlreicher Definitionen für verschiedenste Minecraft-bezogene Aufgaben, wie z.B. Verwaltung von Welten, Homes, Spawnpoints, Economy, Permissions oder ferner auch Konfigurationsverwaltung, zentralisierte Datenbankbereitstellung etc. pp.
Jeder kann weitere Definitionen schreiben und vorhandene abändern, während eine gewisse Gruppe darüber entscheidet ob diese Änderungen im Sinne der Allgemeinheit sind und ggf. Änderungen an eingereichten Ideen vorschlagen, bis diese ins Konzept passen.
Auf diese Art und Weise könnte man tausende Plugins nahtlos miteinander kommunizieren und zusammenarbeiten lassen und den Aufwand eines einzelnen Plugins drastisch senken.
Kurzbeispiel:
Ein Logging-Plugin könnte seine Loginformationen schlicht über eine Schnittstelle für Statistik abgreifen.
Dann muss sich das Logging-Plugin nicht darum kümmern, wie es all die auftretenden Ereignisse sammelt, sondern greift sie durch die Schnittstelle von einem Plugin ab, dass nichts anderes als genau das tun soll.
Durch die Definition der Schnittstelle kann auch schnell festgestellt, ob auch alle gewünschten Daten in der gewünschten Art und Weise zur gewünschten Zeit (z.B. real-time) zur Verfügung stehen.
Das Logging-Plugin greift sich vom Datenbank-Service die nächstbeste Verbindung zu einer z.B. MySQL-Datenbank und führt seine Queries aus.
Ohne, dass es selbst extra aus einer Config Zugangsdaten, Adressen etc. auslesen, einen DB Treiber laden, die Verbindung aufbauen und bereitstellen muss.
Man könnte die Dinge um einiges modularer gestalten, man müsste nicht ständig wiederholenden Code schreiben oder diesen irgendwann in seine eigene "Tools-Lib" stecken, sondern man nutzt das vorhandene Ecosystem und kann sich darauf konzentrieren das eigentliche Problem zu lösen, dass das Plugin lösen soll anstatt tonnenweise Boilerplate zu bauen. Das führt dementsprechend zu höherer Qualität und Wartbarkeit der Plugins.
Dafür braucht es aber eben ein gesundes Ecosystem.
Und jetzt ist genug.
Nun will ich Feedback.
Viel Spaß beim Lesen!
- Felix
PS:
-> Änderungen können noch folgen
-> Rechtschreibfehler, fehlende Wörter etc. sind aufgrund von Müdigkeit, Hastigkeit und Hunger (will seit 2 Stunden essen machen eigentlich) durchaus möglich. Hinweise sind sehr willkommen, damit ich das beheben kann.
-> Bei Fragen: Schreibt unter den Thread, schickt mir ne PN, wie auch immer - ich bin für alle Fragen offen und gebe gerne meinen Senf dazu. Argumente, Diskussionen etc. und besonders Verbesserungsvorschläge sind ausdrücklich Willkommen!
PPS:
@SirYwell @BlackHole @JOO200 @SasukeKawaii
@JTK222 @Matthias @diese_nervigen_chinesischen_Schriftzeichen
Eure Meinungen dazu fände ich besonders interessant in diesem Fall.
Ihr alle helft ebenfalls regelmäßig jungen Programmierern in diesem Forum weiter und ihr alle(?) habt oder hattet schonmal eigene Serverprojekte am laufen oder wart ein Teil von welchen.
Wie steht ihr dazu?
Bereits einige Monate lang und im Rahmen mehrerer (sowohl eigener als auch fremder) Projekte, hat sich bei mir eine gewisse Unzufriedenheit breitgemacht was die so called "Entwicklung" von Minecraft Plugins angeht.
Ich bin ein Mensch der offen entwickelte Standards favorisiert und sich für durchdachte und saubere Planung sowie intensive Dokumentation von Projekten einsetzt.
Mit dieser Einstellung überfordere und nerve ich sowohl einige Arbeitskollegen als auch den Großteil der Minecraft "Devs" or whatsoever.
Ich meine nicht, dass wir losrennen sollten und für jedes Minecraft-Plugin ein RFC-Dokument aufsetzen müssen.
Nein, es handelt sich nach wie vor um ein Spiel und hat bei real-world Standards nichts zu suchen.
Zahlreiche Kinder und Jugendliche haben in den vergangenen Jahren durch Minecraft die Freude am Programmieren gefunden und sich auf die Fahne geschrieben Java zu lernen und haufenweise Minecraft-Plugins zu fabrizieren.
Nun gibt es einige Gruppen von Leuten die man beschreiben könnte - ich nehme eine als Beispiel, beschreibe die Gedankengänge und zeige auch dessen Konsequenzen auf.
Eine kleine Situation die sicherlich jedem Serverbetreiber, sei es damals oder heute, schon mal in einer ähnlichen Form entstanden ist.
Der über alles erhabene Einsteiger
"Essentials ist ein Krampf, bäh GriefPrevention is ja auch irgendwie doof und WorldEdit ist ja total langsam und laggy und auch Schrott. Das schreib ich viel besser selber."
Dies ist die tägliche Einstellung eines jungen Programmiereranfängers, der die ersten Erfolge seiner Lernfortschritte erntet, indem im Chat tolle bunte Nachrichten erscheinen und man einen Kontostand aus einer
Getrübt von den schnellen Erfolgen die das Spiel und die ausgiebige Dokumentation sowie diverse YouTube-Kasper ermöglicht haben, fängt der Programmieranfänger nun rasch an die eingebürgerten und jahrelang existenten Plugins wie Essentials und co. in Frage zu stellen.
(An dieser Stelle sei gesagt, dass ich Essentials oder sonstige Plugins nicht zwangsläufig mag, empfehle oder sonst irgendwie werte - diese dienen bloß als Beispiele.)
Man legt ein neues Projekt in Eclipse an und coded auch gleich los!
/spawn
/bal
/home
/tp
/tpa
bla bla.
Alles läuft und schaut toll aus - die Chatnachrichten sind farbig und ansprechend für den Benutzer (aus Sicht des Programmierers).
Hier und da kommen auch tolle Scoreboards zum Einsatz, die man eigentlich gar nicht braucht, aber da man mittlerweile auch gelernt hat wie man diese geklauten Codeschnipsel "richtig" nutzt, baut mans mal mit ein - ist ja cool shit.
Danach lädt man sein stolzes Werk zusammen mit ein paar schalen Sätzen in der Beschreibung auf Bukkit, Spigot und co. hoch und erfreut sich an den ersten 100 Downloads.
Ein weiteres All-In-One Plugin ist geboren.
Es folgt ganz und gar der Nase des Programmierers und sofern man doch eine Spur Dynamik in Form von Konfigurationsmöglichkeiten aufbringt, beschränkt sich dies meist auf ein paar Startwerte, Nachrichten und vermutlich auch direkt der Speicherung von Nutzdaten, weil die Configs dafür ja super herhalten.
Der Server Besitzer freut sich anfangs sehr über das Plugin, bis er feststellt, dass Warps doch was feines wären und fragt dies sogar bei dem Programmierer an.
Der Programmierer des All-In-One Plugins hat kein Plan was Warps sind und meint, dass das eh keiner braucht.
Daraufhin sucht der Server Besitzer einfach ein anderes Plugin mit dem gewünschten Funktionsumfang.
Er findet UltimateBukkitEssentialsOneXS von einem anderen Programmierer, der bereits auf mehreren Servern war und meint, dass Warps schon mit rein sollten.
Der Serverbesitzer merkt aber nun, dass UltimateBukkitEssentialsOneXS eine ganz eine Config hat und im Ordner noch so eine komische database.sqlite Datei auftaucht.
Wie soll er jetzt die Daten seiner 70 aktiven Stammspieler alle übertragen? Er wendet sich hoffnungsvoll an beide Programmierer.
Diese konzentrieren sich erstmal auf einen digitalen Schwanzvergleich - schließlich ist man selbst ja der bessere Dev und hat das coolere Plugin.
Einer von beiden weiß nicht was SQL ist und soll und der andere meint, dass YAML Dateien ein Rotz sind.
Der Andere meint, dass ........
Und an dieser Stelle ein Cut um die Ereignisse zusammenzufassen:
Zwei Programmierer haben jeweils ein Plugin programmiert um das Gleiche zu tun: Spawns setzen, Teleportieren, Economy etc.
Beide bauen auf die Möglichkeiten die sie kennen und persönlich favorisieren. Die Umsetzung erfolgt nach Augenmaß des Programmierers.
Es ist keine nennenswerte Architektur weit und breit zu sehen.
Ein Serverbetreiber, der nun eins dieser Plugins für seine Spieler bereitstellt, bindet sich an den einen Entwickler und darf hoffen, dass dieser nicht schlagartig den Kurs ändert.
Sollte der Serverbetreiber sich nun von diesem einen Produkt trennen wollen, entwertet er seine Daten, sofern das andere Produkt nicht in der Lage ist, die genaue Datenstruktur der genutzten Version des anderen Plugins zu interpretieren und zu konvertieren.
Ein gewiefter Serverbetreiber ist in den meisten Fällen auch in der Lage, mit etwas Zeit und Mühe selbst ein kleines Skript zu entwerfen, dass ggf. eine YAML Datei ausliest und in die passenden Tabellen umformt.
Das erfordert allerdings, dass der Serverbetreiber Erfahrung mit beiden Technologien hat und bereit ist diese Prozedur bei jedem Wechsel durchzuspielen.
Sowas ist weder spaßig noch wirtschaftlich noch sonst irgendwie toll und ein Zustand der solche Patchwork-Maßnahmen erzwingt sollte tunlichst vermieden werden.
Sollte der Serverbetreiber nicht über das nötige Know-How zum basteln verfügen, dann steht es nun schlecht um die Daten unserer aktuellen Spieler.
Und sollte der Wechsel z.B. aufgrund eines Sicherheitslecks unausweichlich sein, opfert man die Spielfortschritte seiner Spieler und vergrault einen Großteil davon sehr schnell - besonders, wenn das öfters passiert.
Wir haben also zwei Programmierer, die zwar lernen mit Java zu programmieren in Form von Minecraft Plugins - sich jedoch auf ihre Eigeninnovation konzentrieren ohne Rücksicht auf Verluste und dabei auch gelegentlich eine Arroganz aufbauen, die sie sich gar nicht leisten könnten, statistisch betrachtet.
Dies kriegen Serverbetreiber zu spüren, indem sie in die oben genannte Situation geraten und damit ihrer Community erheblichen schaden zufügen können.
Und dabei ist das erst der Anfang... wir sprachen bisher von einem Plugin, dass alles kann.
Was ist, wenn ich zwei Plugins habe, die aber zusammenarbeiten sollen? Oh nose.
Die Liste der Fettnäpfchen ist lang.
Keiner Partei kann man nun so wirklich die Schuld geben.
Die Programmierer sind in der Regel Anfänger und wollen lernen und ihre Erfolge mit anderen teilen - ohne Garantie für irgendwas - it's all fun and game.
Der Serverbetreiber ist nicht automatisch immer ein Technik-Crack sondern meist eher jemand der sozial begabt ist und eine Vision hat, die er gerne mit anderen umsetzen möchte.
Nun, jetzt wird es langsam Zeit von dem negativen Gelaber abzuweichen und auch mal einen Lichtblick zu präsentieren.
Ein Plugin namens Vault.
Vault selbst ist nicht der heilige Gral, um den es geht, sondern viel eher das einzige wirklich bekannte Beispiel.
Es nutzt nämlich einen Teil der Bukkit-API, der niemals sein volles Potenzial erreichen konnte, da er schlicht von 99,99% der Programmierer ignoriert wird.
Was der Bauer nicht kennt, isst er nicht. Basta.
Ich spreche von der Service-API.
Für die Programmierer hier eine kurze (englische) Einleitung dazu aus dem Jahre 2011 (wie schon gesagt.... es wird ignoriert, also gibts auch kaum aktuelle Hilfestellungen): Bukkit Services API Intro
Die Service-API ist grob formuliert eine Ansammlung von Definitionen und Implementierungen - hier als Service und Provider bezeichnet.
Was bedeuten diese zwei Begriffe im Zusammenhang mit Bukkit & Minecraft bzw. Java und wie sollte ich sie behandeln?
Zuerst sei dazu gesagt: Behandelt sie getrennt voneinander.
Die Definition wird in Java durch ein Interface realisiert.
Übersetzen wir diesen Begriff mal: Interface -> Schnittstelle.
Was definiere ich denn in einer Schnittstelle? (Achtung: Java-spezifische Begriffe könnten auftauchen)
Mit meiner Schnittstelle gebe ich die gewünschte Struktur und erwartete Verhalten von JEDER Implementierung vor.
- Ich bestimme die Methoden die existieren müssen
- Ich bestimmte die Parameter und Rückgabe-Typen dieser Methoden
- Ggf. beziehe ich weitere als notwendig für die Implementierungen erachtete Schnittstellen mit ein (z.B. Serializable, Cloneable)
- Rein auf den Code bezogen: Allerhand In-Code-Documentation a la JavaDocs um gewisse Regeln an Ort und Stelle nochmal schriftlich festzuhalten
Kurzum lege ich jegliches Aussehen und Verhalten fest, dass ich von einer Implementierung erwarte.
Jedoch wird dort keine Zeile irgendeine Logik enthalten, geschweige denn welche, die sich mit der tatsächlichen Lösung befasst.
Die Schnittstelle dient der Beschreibung (Definition) wie eine Lösung auszusehen hat.
Vault zum Beispiel liefert ein paar solcher Schnittstellen, nehmen wir hier mal das bekannteste Beispiel: Economy.
Vault Economy Schnittstelle
Hier werden haufenweise Methoden mit entsprechenden Beschreibungen definiert, für diverse Eigenschaften die ein gutes (virtual-) Economy-Plugin bieten sollte.
Sowohl zum Auslesen als auch zum Bearbeiten.
Dazu gehören unter Anderem:
- Name der Währung
- Name der "Unterwährung" (Cent z.B.)
- Entsprechende Namen in der Pluralform
- Die Möglichkeit eine Zahl inkl. Nachkommastellen zu formatieren
- Den einen Spieler Geld auf das Konto des anderen Spielers zu überweisen, mit der Möglichkeit das Ergebnis der Transaktion auszuwerten (EconomyResponse)
Und zahlreiche Weitere Features...
Dazu überall Java-Doc Kommentare mit Hinweisen an das
Seht ihr dort irgendwo eine Zeile, welche die beschriebene Funktionalität umsetzt?
Ich auch nicht!
Das ist auch nicht Aufgabe der Schnittstelle.
Nun - jetzt da wir definiert haben wie ein Economy Service auszusehen und sich zu verhalten hat, kann man hingehen und eine Implementierung erschaffen.
Im Falle von Vaults Economy Service haben das auch einige Leute getan.
15 Economy Plugins sind bereits auf der Pluginseite von Vault offiziell aufgelistet, welche allesamt die Economy Schnittstelle implementieren und hoffentlich gemäß der definierten Regeln die gewünschte Logik bereitstellen.
Wenn nun ein anderes Plugin daherkommt und über die Economy-Schnittstelle von Vault mit welchem Economy-Plugin auch immer kommunizieren will, dann geht er zur Bukkit Services-API und fragt einen Provider an.
Provider = Implementierung
Jedes Economy-Plugin registriert seine eigene Implementierung für die Economy-Schnittstelle bei Bukkit.
Und jedes Plugin, dass mit einem Economy-Plugin reden will, geht zu Bukkit.
Es läuft alles bei Bukkit zusammen - bzw. in der Service-API von Bukkit.
Wenn ein Provider angefragt wird, wird Bukkit, falls ein oder mehrere Provider vorhanden sind, ein dem Plugin unbekanntes Objekt zurückgeben, welches aber zuverlässig die Regeln der Schnittstelle befolgen sollte.
Die Vorteile die sich daraus ergeben sind folgende:
- Ich muss als Pluginentwickler mich nicht darum kümmern jedes Eco-Plugin auf Erden zu unterstützen und gesondert anzusprechen, wenn die bekannte Economy-Schnittstelle ansprechen kann und einfach sage "Das Plugin erfordert ein Economy-Plugin, dass Vaults Economy-Schnittstelle implementiert hat."
- Ich als Serverbetreiber kann bequem zwischen diversen Plugins hin und her wechseln, solange diese allesamt die Economy-Schnittstellen richtig implementieren, ohne dass das den Betrieb der anderen Plugins beeinflusst.
Das ganz ganz oben genannte Problem mit den unterschiedlichen Datenformaten ist zwar noch nicht gelöst damit, jedoch schonmal das Problem der Zusammenarbeit der Plugins.
Was wäre wenn man sich hinsetzen täte und z.B. Import- und Export-Methoden in der Schnittstelle definieren würde und dazu ein erforderliches Datenformat dokumentiert?
Jedes Plugin wäre noch immer frei wie ein Vogel seine Daten in jedem gewünschten Format zu speichern - jedoch muss es eine Möglichkeit bieten seine Daten in ein unabhängiges Format zu konvertieren und auch Daten aus diesem unabhängigen Format heraus zu interpretieren.
Dies ist nur einer von vielen Ansätzen womit man auch solche Probleme behandeln könnte.
Nun aber mal langsam genug der Rederei.
Ich hätte ziemlich Lust darauf, mit ein paar interessierten Personen aus diesem Forum ein kleines Gremium aufzubauen um ein paar solcher Schnittstellen zu diskutieren und letztlich zu definieren.
Dazu sollte dann jeweils eine Referenz-Implementierung folgen - zu Lern-, Demonstrations- und Testzwecken für Endbenutzer und Entwickler.
Dies möchte ich in einem offenen Rahmen tun, wo jeder dazu beitragen kann.
Dieses "Gremium" soll dann die Integrität der Schnittstellen bewahren und die vorgeschlagenen Ideen gemeinsam bewerten, bevor diese veröffentlicht werden.
Rückwärtskompatibilität und Versionierung sind essentiell für diese Schnittstellen, da man das ganze vergessen kann - wenn jeden Tag neue Methoden definiert werden und der Standard nicht statisch genug ist. Zu dieser Problemstellung habe ich übrigens auch bereits funktionierende Lösungen - jedoch würde das allmählich den Rahmen sprengen.
Stellt euch das ganze ungefähr in diesem Stil vor: https://github.com/DefinitelyTyped/DefinitelyTyped
Eine Ansammlung zahlreicher Definitionen für verschiedenste Minecraft-bezogene Aufgaben, wie z.B. Verwaltung von Welten, Homes, Spawnpoints, Economy, Permissions oder ferner auch Konfigurationsverwaltung, zentralisierte Datenbankbereitstellung etc. pp.
Jeder kann weitere Definitionen schreiben und vorhandene abändern, während eine gewisse Gruppe darüber entscheidet ob diese Änderungen im Sinne der Allgemeinheit sind und ggf. Änderungen an eingereichten Ideen vorschlagen, bis diese ins Konzept passen.
Auf diese Art und Weise könnte man tausende Plugins nahtlos miteinander kommunizieren und zusammenarbeiten lassen und den Aufwand eines einzelnen Plugins drastisch senken.
Kurzbeispiel:
Ein Logging-Plugin könnte seine Loginformationen schlicht über eine Schnittstelle für Statistik abgreifen.
Dann muss sich das Logging-Plugin nicht darum kümmern, wie es all die auftretenden Ereignisse sammelt, sondern greift sie durch die Schnittstelle von einem Plugin ab, dass nichts anderes als genau das tun soll.
Durch die Definition der Schnittstelle kann auch schnell festgestellt, ob auch alle gewünschten Daten in der gewünschten Art und Weise zur gewünschten Zeit (z.B. real-time) zur Verfügung stehen.
Das Logging-Plugin greift sich vom Datenbank-Service die nächstbeste Verbindung zu einer z.B. MySQL-Datenbank und führt seine Queries aus.
Ohne, dass es selbst extra aus einer Config Zugangsdaten, Adressen etc. auslesen, einen DB Treiber laden, die Verbindung aufbauen und bereitstellen muss.
Man könnte die Dinge um einiges modularer gestalten, man müsste nicht ständig wiederholenden Code schreiben oder diesen irgendwann in seine eigene "Tools-Lib" stecken, sondern man nutzt das vorhandene Ecosystem und kann sich darauf konzentrieren das eigentliche Problem zu lösen, dass das Plugin lösen soll anstatt tonnenweise Boilerplate zu bauen. Das führt dementsprechend zu höherer Qualität und Wartbarkeit der Plugins.
Dafür braucht es aber eben ein gesundes Ecosystem.
Und jetzt ist genug.
Nun will ich Feedback.
Viel Spaß beim Lesen!
- Felix
PS:
-> Änderungen können noch folgen
-> Rechtschreibfehler, fehlende Wörter etc. sind aufgrund von Müdigkeit, Hastigkeit und Hunger (will seit 2 Stunden essen machen eigentlich) durchaus möglich. Hinweise sind sehr willkommen, damit ich das beheben kann.
-> Bei Fragen: Schreibt unter den Thread, schickt mir ne PN, wie auch immer - ich bin für alle Fragen offen und gebe gerne meinen Senf dazu. Argumente, Diskussionen etc. und besonders Verbesserungsvorschläge sind ausdrücklich Willkommen!
PPS:
@SirYwell @BlackHole @JOO200 @SasukeKawaii
@JTK222 @Matthias @diese_nervigen_chinesischen_Schriftzeichen
Eure Meinungen dazu fände ich besonders interessant in diesem Fall.
Ihr alle helft ebenfalls regelmäßig jungen Programmierern in diesem Forum weiter und ihr alle(?) habt oder hattet schonmal eigene Serverprojekte am laufen oder wart ein Teil von welchen.
Wie steht ihr dazu?