Que vivan los recuerdos
Como parte de la iniciativa EVE Evolved, seguimos trabajando para actualizar el cliente y el servidor de EVE Online de Python 2 a Python 3. Este trabajo es importante para garantizar que construimos sobre unos cimientos sólidos y sentar las bases para muchos más años de desarrollo.
Oficina de Registro
Esta nueva entrega de EVE Evolved analiza la memoria de los agentes PNJ: cómo gestiona el registro de las ~100 000 misiones que se asignan cada día y algunos de los desafíos interesantes que plantea, que podrían afectar a los jugadores en el futuro.
En este blog, «agente» se refiere a los agentes PNJ que habitan EVE: esos entrañables personajes que (a veces con bastante mala educación) te piden que lleves su basura a otra estación, elimines la última amenaza pirata o vuelvas a salvar a esa pobre Damisela a cambio de una retribución.

Empezando por lo sencillo
Como sabemos que os encantan los análisis técnicos en profundidad, pronto entraremos bastante en detalle. Pero, para quienes solo quieran el resumen, estos son los puntos clave:
Como parte de la modernización de EVE Online mediante la actualización a Python 3, es necesario cambiar la forma en que se almacenan los datos de los agentes PNJ. Se realizarán mejoras entre bastidores en el modo de registrar las misiones y otras interacciones con los agentes. Para ello, será necesario eliminar algunos datos antiguos y convertir los restantes a un formato mejor preparado para el futuro.
Este proceso pasará casi desapercibido. El único efecto perceptible debería afectar al progreso de misiones antiguas guardado antes del
29 de septiembre de 2026.
Tu prestigio con los PNJ está a salvo, y todos los agentes que hayas desbloqueado seguirán estando disponibles, aunque no inicies sesión o no tengas Omega en ese momento. No perderás ningún progreso.
Si a partir de hoy solicitas una nueva misión a un agente (o completas o fracasas en una que ya tengas), el progreso de esa misión se transferirá automáticamente a la nueva memoria.
Si has interactuado con un agente ANTES de hoy y no vuelves a interactuar con él DESPUÉS de hoy para actualizar ese progreso, las tareas de ese agente se eliminarán cuando se complete la migración a Python 3.
Aún no tenemos un calendario definitivo para esta limpieza, ya que es solo una parte de la enorme migración a Python 3. Este proceso llevará meses, no días. Cuando se acerque el momento, os lo recordaremos antes de borrar la memoria.
Si tienes una misión que te ofrecieron o que aceptaste ANTES de hoy y no vuelves a interactuar con el agente para completarla, llegará un momento en que se eliminará el progreso de esa misión.
Si contrataste a un agente de investigación para generar puntos de investigación ANTES de hoy, tendrás que completar al menos una misión con ese agente después de hoy para mantenerlo activo. (Solo tendrás que hacerlo una vez por agente y personaje). Con el tiempo, eliminaremos todas las tareas de investigación antiguas que no hayan tenido actividad desde hoy.
En resumen, si realizas misiones de agentes de forma habitual, puedes seguir jugando con normalidad y nada cambiará. Si hay algunos agentes que te interesan (sobre todo agentes de investigación), deberías hacerles una visita y completar una misión para ellos, así no se olvidarán de ti.
Ahora que ya conoces lo básico, si aún quieres saber más sobre la manía de los agentes de acumular datos y descubrir algunos secretos del pasado, sigue leyendo…
Colisión de mundos

Para entender qué queremos decir con la memoria de los agentes, primero necesitamos algo de contexto. A grandes rasgos, el proyecto de Python 3 se divide en las siguientes áreas:
Entorno de ejecución: los ejecutables del cliente y del servidor que hacen funcionar el juego.
Datos: la información que define la experiencia única de EVE Online. Esta categoría puede subdividirse a su vez en:
Datos de contenido: los modelos, las texturas, los textos, las estadísticas y todo lo demás que crean nuestros artistas, diseñadores y escritores. Algunos de estos datos se incluyen en el cliente, mientras que otros solo se encuentran en nuestros servidores.
Datos de red: los paquetes de información que viajan por Internet entre tu cliente y nuestro servidor, así como entre los más de 200 nodos de nuestro clúster de servidores en el centro de datos.
Datos persistentes: el «archivo de guardado» en constante crecimiento que registra los más de 20 años de progreso en el juego. Se trata principalmente de la enorme base de datos SQL que constituye el núcleo de EVE. Aquí es donde reside la memoria de los agentes.
Ecosistema de desarrollo: las herramientas y los procesos que utilizamos los desarrolladores en nuestro trabajo diario para haceros llegar el juego.
Pregunta al agente
Ahora que sabemos dónde reside la memoria de los agentes, podemos hablar de qué es exactamente. Cada vez que tu personaje interactúa con uno de los agentes PNJ, registramos esa interacción en la base de datos. Puede tratarse de solicitar una nueva misión, completar (o fracasar en) una misión ofrecida anteriormente, iniciar una tarea de investigación o de localización, o recibir una recomendación para uno de los agentes especiales de la trama.
Cada agente conoce el estado de la última interacción que tuvo con todos y cada uno de los personajes con los que ha hablado. Si acudiste a un agente hace 20 años e iniciaste una misión para recuperar unas transmisiones holográficas de dudosa procedencia, ese agente aún te recuerda y sigue esperando para decirte que no hiciste el trabajo en un plazo razonable.
Entre los recuerdos que un agente puede conservar sobre tu personaje se incluyen:
Qué misión te ha ofrecido y cuál es su estado (p. ej., ¿se ha eliminado ya al PNJ objetivo?).
Si el agente está realizando una tarea de investigación y cómo está progresando.
Si el agente tiene la tarea de localizar a otro personaje por ti.
Hasta qué punto has avanzado en una cadena de misiones de la trama.
Qué misiones de arcos épicos o de trayectoria profesional has completado.
Ten en cuenta que el prestigio entre los personajes o corporaciones PNJ y tu personaje NO forma parte de esta memoria de los agentes. El prestigio es una mecánica independiente, con su propio sistema para registrar su estado.
Recuperación de datos
Por último, podemos centrarnos en cómo se almacenan y recuperan estos datos, y en el motivo de este blog.
A principios de la década de 2000, cuando EVE Online se encontraba en la recta final antes de su lanzamiento, se concibió la base de datos de la memoria de los agentes. El objetivo era almacenar el complejo estado que representaba las interacciones entre cada pareja de agente y personaje. Normalmente, al diseñar una base de datos, intentamos crear modelos muy formales de tablas y relaciones para este tipo de datos. Sin embargo, los requisitos de la memoria de los agentes eran complejos y dinámicos: cada interacción tenía conjuntos de variables muy diferentes (piensa, por ejemplo, en lo distinto que es describir una misión de reparto y una recomendación para una misión de la trama) y, además, los diseños cambiaban rápidamente a medida que evolucionaba el juego.
En aquella época, el movimiento NoSQL moderno aún no había comenzado. EVE utilizaba MSSQL como sistema de persistencia. Un ingenioso programador se dio cuenta de que podía tomar el objeto de Python que almacenaba la memoria de un agente, serializarlo en un bloque de datos binarios y guardar dicho bloque como texto en una tabla de la base de datos.
Después, la siguiente vez que el agente se activa al interactuar con un personaje, se produce el proceso inverso. El bloque de datos binarios de ese agente se recupera de la base de datos y se deserializa para volver a convertirlo en un objeto de Python, que se incorpora al agente en ejecución para restaurar así su memoria. (En Python, estos procesos también se conocen como «pickling» y «unpickling»).
Aunque esto resolvía muy bien el problema inmediato, acabó generando dos problemas de cara al futuro:
Los bloques de memoria no se podían consultar con facilidad. La potencia de una base de datos reside en las búsquedas: encontrar todas las entradas en las que un parámetro tenga un valor determinado. Sin embargo, al estar cada memoria encapsulada en Python, era imposible consultar su contenido interno de forma eficiente. Para encontrar, por ejemplo, todos los recuerdos relacionados con la Damisela antes mencionada, habría que cargar uno por uno todos los recuerdos en Python para poder comprobarlos. No es lo ideal.
El formato de los datos estaba vinculado a la versión de Python utilizada. A medida que el lenguaje Python evolucionaba, se añadían nuevas funciones, mientras que otras quedaban obsoletas y acababan eliminándose. Esto significaba que, en algún momento, esos recuerdos dejarían de ser legibles y se perderían como lágrimas en la lluvia. Con la migración de Python 2 a Python 3, ese momento no tardará en llegar.
El alijo oculto
Para explicar este problema con una analogía menos técnica, imagina que necesitas guardar tus pertenencias en un almacén durante una mudanza. Una opción sería meterlo todo en un enorme contenedor de transporte sellado y enviarlo al almacén (esto equivale a «serializar» tus datos). Es un método flexible (al camión que transporta el contenedor le da igual que tu colección de música sea de vinilos o CD), rápido y, además, el transporte en contenedores se ha convertido en un proceso estandarizado.
Más adelante, cuando te mudes a tu nueva casa, puedes pedir que te entreguen el contenedor y desempaquetar tus preciadas pertenencias. Sin embargo, este sistema tiene un inconveniente: si el almacén necesita realizar una inspección de seguridad para asegurarse de que no guarda ningún material ilegal, la única forma de hacerlo sería abrir y registrar manualmente todos y cada uno de los contenedores. No es un proceso muy eficiente.
Equipado para el trabajo
A pesar de los inconvenientes a largo plazo de este enfoque, funcionó. EVE Online consiguió lanzarse y siguió adelante. La solución para la memoria de los agentes sobrevivió y, teniendo en cuenta las circunstancias, funcionó sorprendentemente bien. Pero nada dura para siempre.
Limpieza de registros
La migración a Python 3 nos ofrece una oportunidad de oro (que no podemos dejar pasar... literalmente, no podemos) para enmendar los pecados del pasado. Tenemos que dejar atrás la rigidez y la obsolescencia inherente al almacenamiento de bloques de datos de Python en una base de datos SQL. Al mismo tiempo, estamos aprovechando la ocasión para hacer un poco de limpieza y eliminar gran parte de los datos acumulados. (La tabla de memoria de los agentes es una de las más grandes de nuestra base de datos y una de las pocas que no deja de crecer y nunca disminuye).
El dúo de la muerte
Este trabajo ya ha comenzado entre bastidores. Hace poco actualizamos la forma en que cargamos y guardamos la memoria de los agentes. Ahora, cada vez que es necesario guardar un nuevo recuerdo, lo hacemos de dos formas en paralelo:
El formato antiguo de bloques de datos opacos de Python, exactamente como hemos hecho siempre.
Un nuevo formato transparente y preparado para el futuro, que no depende de un formato concreto de Python y que, además, facilita las búsquedas y permite una mayor capacidad de adaptación en el futuro.
Por ahora, todos los recuerdos nuevos o actualizados existirán en ambos formatos. Si hoy solicitas una misión a un agente, ese recuerdo se guarda en los dos. Esto nos permite elegir qué formato priorizar al cargar la memoria de un agente. También reduce el riesgo, ya que podemos comprobar que ambos formatos contienen la misma información antes de dejar de utilizar el método antiguo.
Cuando necesitamos volver a cargar la memoria de un agente desde la base de datos, ahora tenemos varias opciones para decidir qué fuente tendrá prioridad. Esta prioridad irá cambiando a lo largo de tres fases:
Fase 1:
al principio, seguiremos cargando los datos únicamente desde el almacenamiento antiguo, hasta que estemos seguros de que el nuevo formato funciona correctamente.
Fase 2:
después cambiaremos la prioridad, de modo que primero buscaremos la memoria en el nuevo formato y, si no encontramos nada, recurriremos al formato antiguo para cargarla.
Fase 3:
con el tiempo (cuando hayamos migrado por completo todo lo demás a Python 3), dejaremos de leer el formato antiguo. Los agentes solo podrán acceder a los recuerdos que se hayan guardado en el nuevo formato. Entonces podremos eliminar por fin de la base de datos los recuerdos antiguos que nunca se actualizaron, para alegría de nuestros administradores de bases de datos.
A partir de hoy, cualquier recuerdo nuevo nos acompañará durante la migración a Python 3. Esta migración será un proceso largo, así que tendrás tiempo de sobra para interactuar con tus agentes, solicitar nuevas misiones o completar las que ya tengas. Hablamos de meses, no de días. Cuando se acerque la fase 3, nos aseguraremos de avisaros.
Materiales de preparación de guerra
Hay algunos recuerdos que SÍ necesitamos conservar, por antiguos que sean, aunque el personaje correspondiente no inicie sesión ni genere un recuerdo actualizado con cada agente. Por ejemplo, algunas misiones del tutorial o de arcos épicos solo se pueden completar una vez, por lo que necesitamos llevar un registro de ellas. En esos casos concretos, migraremos automáticamente los datos al nuevo formato en segundo plano.
Una parte importante de la relación entre los personajes y los agentes es su prestigio. Es lo que vas aumentando a medida que progresas desde los agentes de nivel 1 hasta los de nivel 4 o incluso 5. Todo el prestigio entre los personajes y los agentes, corporaciones y facciones PNJ se conservará y no se verá afectado por estos cambios. No restableceremos ni perderemos ese prestigio.
En construcción
Continúa el trabajo en la migración a Python 3. Además de la parte «sencilla» de convertir el código del cliente y el servidor, actualizar todo lo que rodea al código requiere tanto trabajo o incluso más. Están las numerosas herramientas que nuestros desarrolladores utilizan a diario. Los numerosos puntos de conexión en los que un proceso de Python se comunica con algún otro componente a través de una red. Los procesos de despliegue que nos permiten pulsar un botón y poner en marcha una expansión.
Y, como hemos visto aquí, incluso los datos almacenados en una base de datos necesitan renovarse un poco de vez en cuando.
Buen vuelo y nos vemos pronto en otro blog. o7
