Gedächtnis bewahren
Im Rahmen der Initiative „EVE Evolved“ arbeiten wir weiterhin daran, Client und Server von EVE Online von Python 2 auf Python 3 umzustellen. Diese Arbeit ist wichtig, um eine solide Grundlage zu schaffen und uns für viele weitere Jahre zukünftiger Entwicklung zu rüsten.
Archiv der Aufzeichnungen
Diese Ausgabe von EVE Evolved untersucht das Gedächtnis von NPC-Agenten, wie es die Bürokratie der Nachverfolgung der ~100.000 täglich vergebenen Missionen verwaltet und welche interessanten Herausforderungen es mit sich bringt, die Spieler künftig betreffen könnten.
In diesem Blog bezieht sich „Agent“ auf die NPC-Agenten, die EVE bevölkern: jene liebenswerten Charaktere, die euch (manchmal recht unhöflich) im Austausch gegen eine Belohnung darum bitten, ihren Müll zu einer anderen Station zu transportieren, die neueste Piratenbedrohung zu beseitigen oder wieder mal eine Jungfrau in Nöten zu retten.

Ein einfacher Anfang
Da ihr es alle liebt, tief in die technischen Details einzutauchen, wird es bald ziemlich detailliert. Doch für alle, die nur die Kurzfassung möchten, hier die wichtigsten Erkenntnisse:
Im Rahmen der Modernisierung von EVE Online durch die Umstellung auf Python 3 müssen Änderungen an der Speicherung von Daten für NPC-Agenten vorgenommen werden. Im Hintergrund werden Verbesserungen an der Nachverfolgung von Missionen und anderen Interaktionen mit Agenten vorgenommen. Dafür müssen einige alte Daten gelöscht und die verbleibenden in eine zukunftssicherere Form umgewandelt werden.
Dieser Vorgang wird größtenteils unsichtbar sein. Die einzige spürbare Auswirkung sollte alte Missionsfortschritte betreffen, die vor dem 29. September 2026 gespeichert wurden.
Euer NPC-Ansehen ist sicher, und alle Agenten, die ihr freigeschaltet habt, bleiben weiterhin verfügbar, selbst wenn ihr euch nicht anmeldet oder derzeit keine Omega-Piloten seid. Ihr verliert keinen Fortschritt.
Wenn ihr ab heute eine neue Agentenmission anfordert (oder eine bestehende Mission abschließt bzw. daran scheitert), wird der Fortschritt dieser Mission automatisch in das neue Gedächtnis übernommen.
Wenn ihr VOR heute mit einem Agenten interagiert habt und NACH heute nicht mit dem Agenten interagiert, um diesen Fortschritt zu aktualisieren, werden Aufträge dieses Agenten entfernt und gelöscht, sobald die Umstellung auf Python 3 vollständig abgeschlossen ist.
Wir haben noch keinen festen Zeitplan dafür, wann diese Bereinigung stattfinden wird, da sie nur ein Teil der umfangreichen Migration zu Python 3 ist. Dieser Vorgang wird Monate dauern, keine Tage. Wenn wir diesem Zeitpunkt näher kommen, werden wir euch daran erinnern, bevor wir das Gedächtnis löschen.
Wenn ihr eine VOR dem heutigen Tag angebotene/angenommene Mission habt und nach heute nicht mit dem Agenten interagiert, um diese Mission abzuschließen, wird es in Zukunft einen Zeitpunkt geben, an dem der Fortschritt einer solchen Mission gelöscht wird.
Wenn ihr vor heute einen Forschungsagenten mit der Generierung von Forschungspunkten beauftragt habt, müsst ihr nach heute mindestens eine Mission mit diesem Agenten abschließen, um ihn aktiv zu halten. (Dies muss nur einmal pro Agent und Charakter erfolgen.) Zu gegebener Zeit werden wir alle alten Forschungsaufträge entfernen, mit denen seit heute nicht interagiert wurde.
Kurz gesagt: Wenn ihr aktiv Agentenmissionen durchführt, könnt ihr wie gewohnt weiterspielen und es wird sich nichts ändern. Wenn euch bestimmte Agenten wichtig sind (insbesondere Forschungsagenten), solltet ihr ihnen einen Besuch abstatten und eine Mission für sie durchführen, damit sie euch nicht vergessen.
Nachdem ihr nun die Grundlagen kennt, solltet ihr weiterlesen, wenn ihr mehr über die Hortungsangewohnheiten von Agenten und einige Geheimnisse aus der Vergangenheit erfahren möchtet …
Welten prallen aufeinander

Um zu verstehen, was wir mit Agent-Gedächtnis meinen, benötigen wir zunächst etwas Kontext. Eine Aufschlüsselung des gesamten Python-3-Projekts ergibt diese groben Bereiche:
Laufzeit – Die Client- und Serverprogramme, die das Spiel am Laufen halten.
Daten – Die Informationen, die das einzigartige Erlebnis von EVE Online definieren. Diese können weiter unterteilt werden:
Inhaltsdaten – Die Modelle, Texturen, Wörter, Werte und alles andere, was unsere Künstler, Designer und Texter erstellen. Einige dieser Daten werden euch als Teil des Clients bereitgestellt, andere befinden sich nur auf unseren Servern.
Netzwerkdaten – Die Informationspakete, die über das Internet zwischen eurem Client und unserem Server sowie zwischen den über 200 Knoten in unserem Server-Cluster im Datenzentrum übertragen werden.
Persistente Daten – Die ständig wachsende „Speicherdatei“, die über 20+ Jahre an Fortschritt dokumentiert, die im Spiel stattgefunden haben. In erster Linie ist dies die riesige SQL-Datenbank im Herzen von EVE.
Hier befindet sich das Agentengedächtnis.
Entwickler-Ökosystem – Die Tools und Prozesse, die wir Entwickler bei unserer täglichen Arbeit nutzen, um euch das Spiel bereitzustellen.
Agentenanfrage
Jetzt, da wir wissen, wo das Agentengedächtnis gespeichert ist, können wir darüber sprechen, was es eigentlich ist. Jedes Mal, wenn euer Charakter mit einem der NPC-Agenten interagiert, erfassen wir diese Tatsache in der Datenbank. Die Interaktion kann darin bestehen, eine neue Mission anzufordern, eine zuvor angebotene Mission abzuschließen (oder dabei zu scheitern), eine Forschungsaufgabe oder einen Suchauftrag zu beginnen oder eine Empfehlung für einen der besonderen Storyline-Agenten zu erhalten.
Jeder Agent kennt den Stand der letzten Interaktion mit jedem einzelnen Charakter, mit dem er je gesprochen hat. Wenn ihr vor 20 Jahren zu einem Agenten gegangen sind und eine Mission begonnen habt, einige fragwürdige Holoreels zu bergen, erinnert sich dieser Agent an euch und wartet noch immer darauf, euch mitzuteilen, dass ihr die Aufgabe nicht innerhalb einer angemessenen Zeitspanne erledigt habt!
Zu den Dingen, die ein Agent über euren Charakter im Gedächtnis behalten könnte, zählen folgende Punkte:
Welche Mission er euch angeboten hat sowie den Status dieser Mission (z. B. ob ein NPC-Ziel bereits eliminiert wurde)
Ob der Agent gerade eine Forschungsaufgabe durchführt und wie sie voranschreitet
Ob der Agent beauftragt wurde, einen anderen Charakter für euch zu finden
Wie weit ihr innerhalb einer Storyline-Kette vorangeschritten seid
Welche Epic Arc- oder Karriere-Missionen ihr abgeschlossen habt
Beachtet dabei, dass die Ansehensbeziehung zwischen NPC-Charakteren/Corporations und eurem Charakter NICHT Teil dieses Agentengedächtnisses ist. Ansehen ist eine eigene, separate Mechanik mit eigener Art der Zustandsverfolgung.
Abrufen von Daten
Zu guter Letzt können wir einen Blick darauf werfen, wie diese Daten gespeichert und abgerufen werden, und uns dem Grund für diesen Blog zuwenden.
Anfang der 2000er-Jahre, als EVE Online kurz vor der Veröffentlichung stand, wurde die Datenbank für das Agentengedächtnis konzipiert. Wir brauchten eine Lösung, um den komplexen Zustand zu speichern, der die Interaktionen zwischen einem Agent-Charakter-Paar abbildet. Normalerweise versuchen wir beim Datenbankdesign, sehr formale Modelle von Tabellen und Beziehungen für solche Daten zu erstellen. Doch die Anforderungen an das Agentengedächtnis waren unübersichtlich und dynamisch – jede Interaktion hatte sehr unterschiedliche Variablensätze (denkt nur beispielsweise an die Beschreibung einer Kuriermission im Vergleich zu einer Storyline-Empfehlung), und außerdem änderten sich die Entwürfe schnell, während sich das Spiel weiterentwickelte.
Zu diesem Zeitpunkt hatte die moderne NoSQL-Bewegung noch nicht begonnen. EVE setzte für seine Persistenzebene konsequent MSSQL ein. Ein kluger Programmierer erkannte, dass er das Python-Objekt, das das Gedächtnis eines Agenten speicherte, in einen Binärblob serialisieren und diesen Blob als Textstück in einer Datenbanktabelle speichern konnte.
Beim nächsten Aufwecken des Agenten durch eine Charakterinteraktion geschieht dann das Gegenteil. Der Binärblob dieses Agenten wird aus der Datenbank abgerufen und deserialisiert, um ihn wieder in ein Python-Objekt zu verwandeln, das dann in den laufenden Agenten eingefügt wird und so dessen Gedächtnis wiederherstellt. (In Python wird dieser Prozess auch als „Pickling“ und „Unpickling“ bezeichnet.)
Dies löste zwar das unmittelbare Problem, verursachte jedoch zwei zukünftige Probleme:
Die Gedächtnisblobs waren nicht einfach durchsuchbar
. Die Stärke einer Datenbank liegt in der Suche: alle Einträge finden, bei denen ein Parameter einen bestimmten Wert hat. Aber weil jedes Gedächtnis in eine Python-Hülle verpackt war, konnten die internen Daten nicht effizient abgefragt werden. Um beispielsweise das gesamte Gedächtnis bezüglich der zuvor erwähnten Jungfrau in Nöten zu finden, müsste jedes Gedächtnis einzeln in Python geladen werden, um es überprüfen zu können. Nicht gerade ideal.
Das Datenformat war an die verwendete Python-Version gekoppelt
. Mit der Weiterentwicklung der Programmiersprache Python wurden
neue Funktionen hinzugefügt und andere als veraltet eingestuft und schließlich entfernt
. Das bedeutete, dass diese Gedächtnisse irgendwann in der Zukunft unlesbar würden – verloren wie Tränen im Regen. Mit dem Wechsel von Python 2 zu 3 wird diese Zukunft bald eintreten.
Das versteckte Lager
Um dieses Problem anhand einer nichttechnischen Analogie zu erklären, stellt euch vor, ihr müsstet eure Sachen während eines Umzugs einlagern. Eine Möglichkeit wäre, alles in einen riesigen, versiegelten Versandcontainer zu packen und ihn an das Lagerhaus zu schicken (das ist die „Serialisierung“ eurer Daten). Das ist flexibel (dem LKW, der euren Container transportiert, ist es egal, ob eure Musiksammlung darin aus Schallplatten oder CDs besteht), schnell erledigt, und der Containertransport ist zu einem standardisierten Prozess geworden.
Später, wenn ihr in euer neues Haus einzieht, lasst ihr euch den Container liefern und könnt eure wertvollen Besitztümer auspacken. Dies hat jedoch einen Nachteil: Wenn das Lager einer Sicherheitsprüfung unterzogen werden muss, um sicherzustellen, dass keine illegalen Materialien gelagert werden, gibt es keine andere Möglichkeit, als jeden einzelnen Container von Hand zu öffnen und zu durchsuchen. Kein besonders effizienter Prozess.
Für die Aufgabe gerüstet
Trotz der langfristigen Nachteile des Ansatzes hat er funktioniert. EVE Online schaffte es bis zur Veröffentlichung und darüber hinaus. Die Lösung für das Agentengedächtnis überlebte und hielt sich alles in allem bemerkenswert gut. Aber nichts hält ewig.
Datenbereinigung
Die Migration zu Python 3 bietet uns eine einmalige Gelegenheit (die wir buchstäblich nicht ignorieren können), die Sünden unserer Vergangenheit anzugehen. Wir müssen uns von der Inflexibilität und der eingebauten Veralterung lösen, die mit der Speicherung von Python-Blobs in einer SQL-Datenbank einhergehen. Gleichzeitig nutzen wir diese Gelegenheit, um aufzuräumen und viele gehortete Daten zu bereinigen. (Die Agentengedächtnis-Tabelle ist eine der größten in unserer Datenbank und eine der wenigen, die nur wächst und nie schrumpft.)
Tödliches Duo
Diese Arbeit hat bereits hinter den Kulissen begonnen. Wir haben kürzlich aktualisiert, wie wir Agentengedächtnisse laden und speichern. Wann immer ein neues Gedächtnis gespeichert werden muss, geschieht dies nun in zwei parallelen Formaten:
Das traditionelle undurchsichtige Python-Blob-Format, genau wie bisher.
Ein neues, zukunftssicheres, transparentes Format, das nicht auf einem bestimmten Python-Format basiert und bessere Durchsuchbarkeit sowie zukünftige Anpassungsfähigkeit ermöglicht.
Alle neuen/aktualisierten Gedächtnisse werden vorerst in beiden Formaten existieren. Wenn ihr heute eine Mission von einem Agenten anfordert, wird dieses Gedächtnis in beiden gespeichert. Dadurch können wir auswählen, welches Format beim Laden eines Agentengedächtnisses priorisiert werden soll. Außerdem verringert es das Risiko, da wir prüfen können, ob beide Formate dieselbe Geschichte erzählen, bevor wir die alte Methode abschalten.
Wenn wir das Gedächtnis eines Agenten wieder aus der Datenbank laden müssen, stehen uns jetzt mehrere Optionen zur Verfügung, welche Quelle vorrangig behandelt wird. Dies werden wir in drei Phasen ändern:
Phase 1: Zunächst werden wir weiterhin nur aus dem alten Speicher laden, bis wir überzeugt sind, dass das neue Format korrekt funktioniert.
Phase 2: Dann werden wir die Priorität ändern, sodass wir zuerst im neuen Format nach einem Gedächtnis suchen und es dann aus dem alten Format laden, falls nichts gefunden wird.
Phase 3: Letztendlich (wenn wir alles andere vollständig auf Python 3 migriert haben) werden wir das alte Format überhaupt nicht mehr auslesen. Nur Gedächtnisse, die im neuen Format gespeichert wurden, werden den Agenten zur Verfügung stehen. Anschließend können wir die alten, veralteten Gedächtnisse, die in der Datenbank nie aktualisiert wurden, endlich entfernen und damit unsere Datenbank-Admins glücklich machen.
Ab heute wird jedes neue Gedächtnis bei der Migration auf Python 3 mit übernommen. Diese Migration wird ein langer Prozess sein, daher werdet ihr ausreichend Zeit haben, mit euren Agenten zu interagieren, neue Missionen zu erhalten oder bestehende abzuschließen. Wir sprechen hier von Monaten, nicht von Tagen. Wenn Phase 3 näher rückt, werden wir euch darüber informieren.
Materialien für Kriegsvorbereitungen
Einige Gedächtnisinhalte MÜSSEN wir unabhängig von ihrem Alter übernehmen, selbst wenn sich der zugehörige Charakter nicht anmeldet oder bei jedem Agenten ein aktualisiertes Gedächtnis erzeugt. Bestimmte Tutorial- oder Epic Arc-Missionen sind beispielsweise nur einmal verfügbar, daher müssen wir das nachverfolgen. In diesen begrenzten Fällen migrieren wir die Daten im Hintergrund automatisch in ein neues Format.
Ein wichtiger Teil der Beziehung zwischen Charakteren und Agenten ist ihr Ansehen. Daran arbeitet ihr, wenn ihr euch von Agenten der Stufe 1 zu Stufe 4 oder sogar Stufe 5 hocharbeitet. Jegliches Ansehen zwischen Charakteren und NPC-Agenten/Corporations/Fraktionen bleibt erhalten und wird von diesen Änderungen nicht beeinflusst. Wir werden dieses Ansehen weder zurücksetzen noch verlieren.
In Arbeit
Die Arbeiten an der Migration zu Python 3 gehen weiter. Zusätzlich zum „einfachen“ Teil der Umwandlung des Client-/Server-Codes erfordert auch die Aktualisierung aller Komponenten rund um den Code mindestens ebenso viel, wenn nicht sogar mehr Arbeit. Dazu gehören die vielen Tools, die unsere Entwickler täglich verwenden. Die zahlreichen Schnittstellen, bei denen ein Python-Prozess in einem Netzwerk mit einer anderen Komponente kommuniziert. Die Bereitstellungsprozesse, dank denen wir per Tastendruck eine Erweiterung live schalten können.
Und wie wir hier gesehen haben, müssen selbst die in einer Datenbank gespeicherten Daten manchmal etwas aufgefrischt werden.
Guten Flug, und wir sehen uns bald in einem weiteren Blog o7
