SWG hat, nach allem was man so hört und liest, seine Wurzeln in der Programmierung von EverQuest. Vieles ist identisch und darum will ich für diejenigen, die noch nie MMORPGs gespielt haben oder sich nie Gedanken darüber gemacht haben wie sowas eigentlich funktioniert mal versuchen einige grundsätzliche Dinge über MMORPGs zu erklären. Daraus lassen sich Antworten auf viele Fragen herleiten.Der Kern eines MMORPGs ist der Heartbeat, Spieler nennen es meist “Ticks”, das ist tatsächlich sowas wie ein “Herzschlag”. Bei EQ schlägt der Heartbeat alle 3 Sekunden (wenn ich mich richtig erinnere). Ein “Tick” ist also 3 Sekunden.

Dieser Herzschlag löst alle Events im Spiel aus. Z.B. wird man bei jedem Tick ein wenig regenerieren. Ist man vergiftet wird man mit jedem Tick Schaden nehmen. Ein leichtes Gift könnte definiert sein 20 Ticks lang zu wirken.

Ebenso tauschen Server und Client mit jedem Tick Positionsmeldungen aus. Der Client meldet dem Server wo der Spieler gerade steht, in welche Richtung er schaut und mit welcher Geschwindigkeit er in welche Richtung wie schnell läuft. Ändert sich daran etwas weil der Spieler z.B. plötzlich stehen bleibt geht wieder eine neue Nachricht an den Server.

Der Server erhält diese Meldungen von allen Spielern und berechnet selber solche Daten von allen Objekten im Spiel die er kontrolliert (z.B. NPCs, mobs oder Vehikel). Dann erhält jeder Client alle Informationen die er braucht um die Umgebung für den Spieler darstellen zu können.

Dieses System hat sowohl Vor- als auch Nachteile. Der größte Vorteil ist das der Client komplett frei in seinen Bewegungen ist und somit unabhängig vom Ping jeder Spieler die gleiche Bewegungsfreiheit hat. Der Nachteil wird in der Darstellung deutlich. Kommt etwa ein Spieler auf mich zugerannt und bleibt dann plötzlich stehen, so sehe ich erst das er stehen bleibt wenn diese Information meinen Client erreicht. In der Zwischenzeit sehe ich ihn weiter laufen weil das die letzte Information ist, die mein Client zur Berechnung meiner Umgebung hat. Das führt bei einem Lag dazu das mich der Spieler erst über den Haufen rennt um dann abrupt wieder vor mir auf zu tauchen. Nämlich dann wenn das Lag vorbei ist und seine tatsächliche Position meinem Client gemeldet wird.

Ein zweites grundlegendes Prinzip sind die Objekte. Wirklich alles was in irgendeiner Form interagieren kann ist ein Objekt. Ein Ganzer Planet ist ein Objekt und ein Sandkorn das ich in mein Inventar nehmen kann ist ebenfalls ein Objekt. Ein Spieler ist ein Objekt, ein NPC ist ein Objekt, eine Cantina ist ein Objekt und auch ein ganzer POI ist ein Objekt voll mit anderen Objekten. Die Eigenschaften eines Objektes definieren sich über viele Tabellen mit Informationen wie die Größe des Objektes, das Gewicht, ist es Essbar?, ist es vergiftet?, mit welchem Gift? was soll passieren wenn es gegessen wird? usw.

(Wer sich mit objektorientierter Programmierung etwas auskennt - Ja, genau das haben wir hier. Eine Hauptfunktion eines MMORPG-Kerns ist es eine objektorientierte Script-Sprache bereit zu stellen. Eine Zweite ist der Heartbeat.)

Wenn es ein vergiftetes Objekt ist und ich esse es so ist das Gift selber auch wieder ein Objekt. Das Objekt das ich gegessen habe ist nun vermutlich aus meinem Inventar verschwunden oder ein “Teller Gemüsesuppe” durch das Objekt “schmutziger Teller” ersetzt worden. Gleichzeitig habe ich in einem unsichtbaren Inventar das Objekt “Gift” erhalten das mich nun mit jedem Tick vergiftet bis es sich selbst löscht oder dadurch das ich das Objekt Gegengift trinke von diesem gelöscht wird.

Mit diesem Wissen lassen sich sehr viele “Fehler” in einem MMORPG erklären. Etwa warum man einen Muffin nicht essen kann (der Programmierer hat versehentlich die Eigenschaft “Essbar” vergessen).

Auch das Crafting System lässt sich einfacher verstehen. Wenn man 5 Objekte in ein sechstes Objekt legt und dann “Kombinieren” klickt entscheidet das sechste Objekt ob diese 5 Objekte kombiniert werden können, in welcher Form und was mit diesen 5 Objekten dann geschieht und welches neue Objekt dann erscheint.

Leichte Nachlässigkeiten in der Programmierung führen dann dazu das man sich aus “a egg” und anderen Zutaten ein Omlette kochen kann. “An egg” (Schreibweise beachten!) dazu aber nicht verwendet werden kann. Ein Programmierer hat halt eine bestimmte, wichtige Eigenschaft bei “an egg” vergessen.

Das Crafting System soll ja dynamisch sein. Das wird vermutlich bedeuten jedes Objekt hat noch eine Tabelle mit Haufenweise “Crafting Eigenschaften”. Blei könnte etwa die Information beinhalten sich mit Zink als Energiequelle zu eignen. Jeweils mit einer Information darüber wie Hochwertig eine solche Kombination mit diesem Objekt werden kann.

Das Objekt “Energiequelle” könnte sich dann, vorausgesetzt die Qualität und die Größe stimmen mit Objekten die etwa die Ausprägungen “Waffengehäuse” und “Lasergenerator” besitzen zu einer Laser Pistole kombinieren lassen. Wie diese Aussieht, welche Farbe die Teile haben, wie gut man damit Zielen kann und wie schwer die Treffer sind definiert sich in dem neuen Objekt durch die Eigenschaften der Objekte aus dem es entstanden ist.

Ein MMORPG läßt sich grob in 4 Teile zerlegen:

Der Server-Core. Programmiert in C/C++ bringt er, wie schon beschrieben, einen Interpreter für eine objektorientierte Programmiersprache mit und sorgt für den HeartBeat.

Die Library. Das ist das Juwel eines jeden MMORPG, die Bibliothek von Objekten und Funktionen auf denen das Spiel basiert. Sie ist die größte Investition bei der Erschaffung eines neuen MMORPGs und wird in der Script-Sprache erstellt.

Die Objekte. Das eigentliche Spiel, ebenfalls in der Script-Sprache.

Der Client. Sorgt für die visuelle Darstellung des Spiels. In etwa programmiert wie ein Shooter auch. Ist der einzige Teil der beim Spieler liegt.

Der Punkt der das eigentliche Spiel ausmacht sind die Objekte. Die grundlegenden Struktur eines Objektes wird in der Library definiert. Ein Programmierer “holt” sich aus der Library ein Ausgangsobjekt und modelliert es nach seinen Wünschen um das zu erhalten was er möchte.

Als Beispiel könnten wir mal einen einfachen Gegenstand produzieren, sagen wir eine Flasche mit Wasser:

Als erstes holen wir uns dazu aus der Bibliothek das Objekt “eatable”. Darauf basieren alle “Gegenstände” die irgendwie essbar oder trinkbar sind, also z.B. Fleisch, Zucker oder halt auch eine Flasche Wasser. Jetzt Modellieren wir diesen einfachsten aller Gegenstände zu einer Flasche. Zunächst nennen wir das “eatable” mal in “Flasche” um. Wir weisen dem Gegenstand eine 3D Grafik für die Spielwelt zu und eine 2D Grafik die ihn im Inventory repräsentiert. Dann legen wir verschiedene Objekteigenschaften fest:

Flasche.Gewicht = 100 g
Flasche.Breite = 6 cm
Flasche.Tiefe = 6 cm
Flasche.Höhe = 15 cm
Flasche.Farbe = transparent
Flasche.Material = Glas
Flasche.Verkäuflich = Ja
Flasche.Tauschbar = Ja
Flasche.Ablegbar = Ja
Flasche.Qualität = 50
Flasche.Decay = 10000
Flasche.Inhalt = Wasser
Flasche.Essbar = Ja

Wir haben also festgelegt wie Groß und Schwer unsere Flasche ist, aus welchem Material und Farbe, dass man sie an NPCs verkaufen kann, sie mit anderen Spielern tauschen kann und auch einfach ablegen kann. Die Qualität ist 50 und alle 10.000 Ticks wird von der Qualität eins abgezogen bis sie bei 0 unbrauchbar wird. Zuletzt haben wir der Flasche einen noch Wasser als Inhalt gegeben und sie als Essbar bzw. Trinkbar definiert. Jetzt muss tatsächlich ein wenig programmiert werden. Jedes Objekt “eatable” hat bestimmte Grundfunktionen. Versucht ein Spieler ein solches Objekt zu essen wird in dem Objekt eine Funktion “Spieler_will_es_essen()” aufgerufen. Ist diese Funktion nicht da wird das Objekt ganz einfach gegessen und ist dann weg. In unserem Fall möchten wir aber nicht das die Flasche gegessen wird sondern nur das Wasser in ihr getrunken wird. Also müssen wir an dieser Stelle eingreifen um unsere Flasche zu retten Ich versuche es mal so gut es geht mit einer Pseudo-Programmiersprache damit es für jeden verständlich bleibt.

Function Spieler_will_es_essen() {
Flasche.Inhalt = leer
Flasche.Essbar = nein
Flasche.2D-Bild = leere_flasche.jpg
Spieler.Durst += 100
return (NICHT_ZERSTÖREN)
}

Der Inhalt der Flasche ist also nun leer. Es ist nicht mehr Essbar und bekommt ein neues 2D Bild das eine leere Flasche zeigt. Der Spieler bekommt 100 Punkte auf seinen Durst gut geschrieben weil er etwas getrunken hat und schließlich geben wir an das Objekt die Information zurück das es jetzt nicht zerstört werden soll. Die Flasche bleibt also nach dem trinken noch erhalten.In dieser Art gibt es noch viele weitere Funktionen bei denen wir eingreifen könnten. Etwa könnte aus der Flasche ein “Haufen Glas” werden wenn ihre Qualität 0 wird. Dazu könnten wir eine Funktion “Gegenstand_Qualität_abgelaufen()” schreiben die in jedem Objekt immer aufgerufen wird wenn die Qualität auf 0 sinkt. Wenn es sie nicht gibt geht das Objekt halt kaputt und verliert jegliche Funktion. Wenn wir eine eigene schreiben könnten wir damit das Objekt durch ein Objekt “Haufen Glas” ersetzen.

In dieser Art funktionieren alle Objekte in einem MMORPG. Hier mal eine paar interessante Funktionen die ein Objekt haben KANN (es muss nicht, aber wir könnten dort halt eingreifen und etwas “passieren lassen”):

heartbeat() wird im Objekt mit jedem HeartBeat, also alle 3 Sekunden, aufgerufen. Ein Gift-Objekt könnte das nutzen um dem Spieler alle 3 Sekunden Schaden zuzufügen und sich nach 20 Ticks selbst zu löschen.

Objekt_wird_angegriffen() wird aufgerufen wenn das Objekt von einem Anderen angegriffen wird. Ein NPC Objekt würde hier reagieren aber auch ein Objekt wie Sprengstoff könnte “angreifbar” sein.

Objekt_stirbt() in einem NPC wird das aufgerufen wenn seine Gesundheit auf 0 sinkt. Normalerweise wird ein NPC einfach durch ein default Objekt “Leiche” ersetzt die dann mit dem im Objekt definierten Loot ausgestattet sein kann. Es wäre aber vorher z.B. noch ein besonderer Todesschrei möglich.

Objekt_halb_tod() wird aufgerufen wenn ein NPC nur noch die hälfte seiner Energie hat. Evtl. möchte er dann seine Kampftaktik ändern?

Objekt_fast_tod() wird aufgerufen wenn ein NPC nur noch 20% seiner Energie hat. Vielleicht flüchtet er dann oder er ruft um Hilfe.

Spieler_will_es_anziehen() wird aufgerufen wenn ein Spieler versucht sich das Objekt anzuziehen. Evtl. ist es ja gefährlich dieses Objekt anzuziehen und der Spieler bekommt einen elektrischen schlag. Oder das Objekt hat besondere Fähigkeiten und erzeugt z.B. ein Energiefeld um den Spieler herum.

Man sieht, es gibt nahezu unendlich viele Möglichkeiten wie Objekte auf ihre Umgebung und auf die Spieler reagieren könnten. Und zum MOB des Grauens Naja, in Objekt_stirbt() kann ich natürlich auch das MOB einfach “verschwinden” lassen und durch eine Version des gleichen Mobs ersetzen, die es als Geist repräsentiert und weiter kämpft. Für den Spieler stellt es sich so dar als wäre das MOB nun zum Geist geworden.

Es wurde auch mal gefragt wie es möglich ist das man Darth Vader nicht töten kann. In Objekt_halb_tod() könnte eine Horde Wachen aus einem Nachbarraum kommen und Vader Helfen. In Objekt_fast_tod() könnte Vader die Flucht antreten und durch eine Türe verschwinden die er hinter sich zusperrt.

So gibt es noch viele weitere Objektarten im Spiel. Offensichtliche, wie einzelne Gegenstände oder mobs, und weniger offensichtliche wie etwa einzelne Missionen oder Buffs.

P.S.: In Wahrheit funktioniert es natürlich doch noch etwas anders aber das Prinzip ist schon sehr ähnlich.

von “Papillon”