[Java] Argentum Online y una prueba de concepto.

guidON.-

Newbie Lvl 2
#1
Todos nos preguntamos si es posible un cambio de tecnología para este hermoso juego, y si este cambio tiene sentido...

Personalmente creo que si, de hecho lo que hicieron algunos chicos de la comunidad con el AO Web creo que fue excelente. Pero esta vez quiero ir un poco más allá.
Quiero mostrarles un poco lo que estuve haciendo y quiero continuar.

AO-java (repo)
No me parece un buen nombre, pero creo que tengo cosas más importantes en las cuales me quiero ocupar.

ECS
Para empezar, estoy usando ECS (entity-component-system) como patron de diseño. Luego de leer sobre esto por algunos lados, encontré un framework llamado Artemis, el cual sorpresivamente en su documentación, se encuentra un ejemplo de uso y es este, un cliente de AO. Si... alguien hace unos años ya había pensado en esto, así que tome lo que había hecho, actualicé y modifiqué a gusto.
  1. En que consiste?
    Un mundo que tiene entidades y sistemas:
    Cada entidad esta identificada en este mundo, naturalmente con un ID (supongamos, un numero entero), y posee componentes.
    Estos componentes, suelen ser datos, nativos (strings, booleanos, enteros, etc) y no poseen ningún tipo de lógica.
    A su vez, estos sistemas, van a estar interesados en entidades que contengan ciertos componentes específicos.
    El mundo procesa cambios en entidades, y sus sistemas:
    Como todos sabemos, un juego consiste en un loop. El mundo se procesa varias veces por segundo, escuchando cambios de componentes en las entidades, para así notificar a los sistemas, si una entidad tiene que ser tenida en cuenta en su procesamiento. El mundo, también, manda a procesar estos sistemas. Cada sistema, tendrá una lógica acotada y sabra que hacer con dicha entidad y sus componentes específicos, y así modificar, agregar o quitar componentes.
    Si quieren introducirse más recomiendo leer esto.

  2. En que nos facilita usar ECS para el AO?
    Un punto muy fuerte que le veo es la simpleza con la que se puede desarrollar. Imaginensé que todo puede ser considerado una entidad: un jugador, un npc, un arbol, una piedra, un objeto en el piso, etc; y no nos importaría si queremos agregar en un futuro, algún tipo de entidad o cualidad (componente), solo lo agregamos, y algun sistema se encargara de hacer lo necesario.
    También nos facilita a tener una sola fuente de verdad: El servidor tendrá al mundo real, y los clientes tendrán replicas parciales del mismo. Por qué parciales? A un jugador no le interesa lo que hay en la otra esquina del mapa, así fue, es y será siempre el AO. El servidor como no distinguimos entre entidades, solo se encargara de enviar las mismas con sus correspondientes componentes a los clientes interesados, es decir, no importa si la entidad es un objeto en el piso, o un personaje, el servidor enviara una entidad con componentes, el cliente sabra que hacer con esto.

  3. Algo interesante...

    Fluid Entities API: Los invito a ver un poco de código:
Sitema de renderizado de "barritas" de vida, mana, exp...:
...  
    @Override
    protected void process(int entity) {
        cameraSystem.guiCamera.update();
        batch.setProjectionMatrix(cameraSystem.guiCamera.combined);
        batch.begin();
        OFFSET_X = (cameraSystem.guiCamera.viewportWidth / 2) - BAR_WIDTH / 2;
        drawExp(E(entity));
        drawHealth(E(entity));
        drawMana(E(entity));
        batch.end();
    }

    private void drawExp(E player) {
        int maxExp = player.getExp().exp;
        int minExp = player.getElv().elv;
        drawBar(maxExp, minExp, (int) OFFSET_X, 0, Colors.EXP.cpy(), OFFSET_Y);
    }

    private void drawMana(E player) {
        int maxMana = player.getMana().max;
        int minMana = player.getMana().min;
        drawBar(maxMana, minMana, (int) OFFSET_X, OFFSET_Y + BAR_HEIGHT + 1, Colors.MANA.cpy(), BAR_HEIGHT);
        drawText(maxMana, minMana, (int) OFFSET_X, OFFSET_Y + BAR_HEIGHT + 1);
    }

    private void drawHealth(E player) {
        int maxHealth = player.getHealth().max;
        int health = player.getHealth().min;
        drawBar(maxHealth, health, (int) OFFSET_X, OFFSET_Y, Colors.HEALTH.cpy(), BAR_HEIGHT);
        drawText(maxHealth, health, (int) OFFSET_X, OFFSET_Y);
    }
...
Como pueden ver, recibimos un int 'entity', que representa a nuestro jugador, con esta API, podemos acceder a cualquier componente que este tenga, agregar, modificar o quitar de una forma muy sencilla (simil setters y getters). Como funciona? Nosotros vamos a tener una serie de componentes definidos, al compilar, va a recopilar todos estos, y va a crear una interfaz con todos nuestros métodos. Fácil.

KryoNet
Va a ser nuestro encargado enviar y recibir paquetes. Con una API amigable y utilitarios de Artemis se hace más simple aun.
Kryo is a fast and efficient binary object graph serialization framework for Java
Es decir, Kryo en el cliente, Kryo en el servidor, serializa, envia, recibe y deserializa. Usa java.nio (channels en lugar de threads), principalmente nuestro caso de uso es todo por TCP, aunque soporta UDP en simultáneo.
Todavía estoy jugando con esto, pero parecería cumplir con todas mis necesidades.

LibGDX
ibGDX is a cross-platform Java game development framework based on OpenGL (ES)
Me enfoco en lo que seria desktop, lo que incluye Mac, Windows y Linux, aunque soporta otros ambientes.
No hay mucho que aclarar, con éste armamos la aplicación, y delegamos cualquier tipo de rendering, tanto GUI como vision de juego.

Problemáticas
Al empezar de "cero", te encontrás con problemáticas ya resueltas en la historia del AO. Lo que no quiere decir que se hayan resuelto de la mejor manera (aunque realmente no se como están resueltas hoy en día). Leyendo me topé con el siguiente blog. Habla de casos muy puntuales y aplicables al AO, tales como el movimiento de un personaje, colisiones, compensación de lag, reconciliación (cliente-servidor), interpolación, y algunas cuestiones de arquitectura de más bajo nivel. Recomiendo leerlo, pero básicamente justifica que es posible jugar de manera más fluida y con menos problemas cuando tenemos ping elevado. Cosa que hoy en día por como esta hecho es bastante complicado.

Siguientes pasos...
Antes de tener feature parity con AO (mismas funcionalidades), lo que me llevaria mucho tiempo, me gustaria hacer una prueba de concepto y achicar el scope, para esto mi idea es hacer algunos mini juegos, se me ocurria algo de agite al estilo battle royale, dota, y otras pavadas.
Por el momento están las bases: comunicación cliente-servidor, gran parte del renderizado de juego (usando mismos recursos que AO; graficos, mapas, etc, gran parte en formato JSON), logica de movimiento (tanto cliente como servidor), y estoy terminando el sistema de combate.
Me gustaría que comenten, pregunten, critiquen y por ultimo saber si alguno quiere aportar a la causa.

Por último me pregunto...
 
Última edición:

^[GS]^

GS-Zone Admin
Administrador
#5
Esta muy bueno el proyecto :D
En cuanto al servidor, como lo vienes haciendo? Se ve muy bien encaminado lo que estás haciendo ;)
 

guidON.-

Newbie Lvl 2
#6
Como comente en el post, el servidor tiene el mundo "real", el cual va a recibir request de los clientes, los va a procesar, y luego responder o notificar a quien corresponda, ejemplo:
Cliente 1 ataca (apreta Ctrl o lo que sea):
- Eso envia un request de ataque, indicando posicion y hacia donde esta apuntando.
El servidor procesa esta request:
- Procesar la request es simple, no hace falta tener que usar ids de paquetes ni tener guardado un mapa con funciones.
- Usando un visitor (patron de diseño), por cada clase de request tiene un metodo que responde por tal.
- En caso de golpear, se disminuye la vida de la victima, es decir, se modifica la componente "vida", y lo unico que hariamos en este caso, es enviar un "EntityUpdate". Que quiere decir esto? dado un ID de la entidad y la componente vida, se envia a todos los clientes que estan en el area.
Clientes cercanos:
- Procesan el "EntityUpdate", lo unico que hay que hacer es actualizar la componente, tan simple como decir entidad.add(componente). Es decir que este procesamiento es generico, sin importar la accion, solo se actualiza la entidad como corresponde.

Todo esto es usando Artemis para el manejo del "mundo" y kryonet para el envio de las request y los updates/responses.
Podes ver la clase 'ServerRequestProcessor' para darte una mejor idea.
 
#7
Hola Guidon! Después de tanto tiempo he llegado a la conclusión que el rumbo del AO si no se enfoca en la comunidad, pasa a ser un proyecto personal (un proyecto demasiado grande para ser personal)
Te recomiendo una lectura fundamental:
https://github.com/DakaraOnline/dakara-server/blob/master/doc/HISTORY.md
Más allá de eso, como aporte a la comunidad la documentación nunca esta de más (en el caso que no funcione el proyecto dejás una huella). Por mi parte, he estado viendo que muy pocos proyectos tienen un documento de diseño (por no decir ninguno)
Empezaría por ahí!

Igualmente, creo que todo es posible y te deseo lo mejor en el proyecto! No dejes de escribirme si querés conversar sobre la comunidad, porque es un tema que me apasiona y todo lo que pueda aportarte desde la experiencia es un agrado poder compartirlo.
Exitos!
 

guidON.-

Newbie Lvl 2
#8
Hola Guidon! Después de tanto tiempo he llegado a la conclusión que el rumbo del AO si no se enfoca en la comunidad, pasa a ser un proyecto personal (un proyecto demasiado grande para ser personal)
Te recomiendo una lectura fundamental:
https://github.com/DakaraOnline/dakara-server/blob/master/doc/HISTORY.md
Más allá de eso, como aporte a la comunidad la documentación nunca esta de más (en el caso que no funcione el proyecto dejás una huella). Por mi parte, he estado viendo que muy pocos proyectos tienen un documento de diseño (por no decir ninguno)
Empezaría por ahí!

Igualmente, creo que todo es posible y te deseo lo mejor en el proyecto! No dejes de escribirme si querés conversar sobre la comunidad, porque es un tema que me apasiona y todo lo que pueda aportarte desde la experiencia es un agrado poder compartirlo.
Exitos!
Coincido totalmente con tu conclusión. Aunque no estoy tan de acuerdo de que sea un proyecto grande para ser personal. La idea del proyecto es encontrar la simpleza y escalabilidad en todo sentido.
La idea es sacar provecho a ECS, Kryonet (fuerte punto para evitar tener un protocolo gigantesco) y los recursos que ya existen hoy en día. Si todo esto llegara a funcionar creo que usar TiledMap (o algo similar) y skeletal animations en lugar de sprites, facilitaría mucho el progreso.
Estoy convencido de que usando las herramientas correctas todo es más fácil...
 
#9
Me alegra que lo encararas tan bien, por sobre todas las cosas. A darle para adelante y acá estamos para dar una mano cuando se necesite. Te felicito.
 

guidON.-

Newbie Lvl 2
#10
Me alegra que lo encararas tan bien, por sobre todas las cosas. A darle para adelante y acá estamos para dar una mano cuando se necesite. Te felicito.
Anoche chusmeando llegue a un repo tuyo donde estaban haciendo algo parecido, puede ser?

Cabe aclarar que acepto sugerencias, PRs y cualquier tipo de ayuda.
 

Lherius

Dragón Ancestral Lvl 6
Especialista de Diseño
#11
¡Te felicito! Hace mucho tiempo que no comentaba en un post, pero éste realmente vale la pena, tenes una mentalidad muy positiva y eso es clave para llevar a cabo un proyecto, que además uno tiene mucho afecto por el mismo.

Si queres ayuda a nivel diseño, por favor, no dudes en mandarme un MP para que podamos conversarlo. ¡A seguir metiéndole!

Rodri.
 

Franeg95

CARP
Ex-Staff
#12
Excelente iniciativa.

Ya que lo colgaste el GitHub, sería buena idea que estos sub-proyectos o pruebas de concepto que mencionas, tengan una definición, alcance e hitos. Sería idea para que cualquiera con el repo en mano pueda aportar en la misma dirección que todo el equipo. Es una gran herramienta usar la comunidad, pero hay que saber manejar todo el caudal de aportes que pueden llegar, y definiendo los próximos pasos concretamente sería una buena manera de marca en sendero para cualquiera.

Muy buena propuesta, explicación y esfuerzo. Felicitaciones y mucho éxito.
 

guidON.-

Newbie Lvl 2
#14
Gracias por los comentarios!

Excelente iniciativa.

Ya que lo colgaste el GitHub, sería buena idea que estos sub-proyectos o pruebas de concepto que mencionas, tengan una definición, alcance e hitos. Sería idea para que cualquiera con el repo en mano pueda aportar en la misma dirección que todo el equipo. Es una gran herramienta usar la comunidad, pero hay que saber manejar todo el caudal de aportes que pueden llegar, y definiendo los próximos pasos concretamente sería una buena manera de marca en sendero para cualquiera.

Muy buena propuesta, explicación y esfuerzo. Felicitaciones y mucho éxito.
Si, claramente tengo que hacer estas cosas. Empezaría por documentar lo que ya esta hecho y luego tratar de armar algo (un board o compartir un poco la visión) para empezar a recibir aportes.

Me alegraría que los que estén interesados en aportar o ser parte me lo hagan saber!
 

Lord Fers

Legendario Inmortal Lvl 4
Miembro del equipo
Especialista de Tecnología
#15

guidON.-

Newbie Lvl 2
#17
MoB, utiliza Artemis junto con libGDX si no mal recuerdo, y utilizaron esta guía: https://github.com/apotapov/gdx-artemis/wiki/Quick-tutorial

De hecho, el código de MoB ronda también por 2014-2015, lo habían desarrollado para una comunidad que ya ni me acuerdo el nombre, de Nicolás Musco.

Por acá andaba dando vueltas el thread principal: https://www.gs-zone.org/temas/cliente-de-ao-hecho-en-java.89881/

Saludos.
Tal cual, la verdad fue una gran base para empezar. Artemis avanzó bastante desde entonces, y tiene cosas muy copadas como la API de Fluid Entities, que comente en el post principal y otras movidas de optimización que todavía no pude meterme a ver. Otra cosa que intento hacer por recomendación de ellos es tratar a las entidades como números enteros, en lugar de 'Entity', lo que debería mejorar la performance.
 

Facu Chamas

Creador Lux Venatore
#18
Esto me dejó sorprendido. En todas las veces que leído este tipo de post, en donde nos muestran a nosotros (la comunidad) proyectos en donde hay progresos en otro lenguaje y un posible futuro al juego, es la primera vez que siento que esto va a tener futuro, no tirado, sin usarlo, y sin jugado que eso es lo que pretendemos hacer todos acá que nos interese un Argentum Online actualizado.

No puedo darte una mano en desarrollo porque desconozco totalmente, pero conta con mi apoyo moral. ¡Muchísima suerte! :abrazo:
 

pLuS

Atómico
#19
Perdón la ignorancia pero para que los clientes podamos conectar al server ¿necesitamos el java común de los exploradores o descargar el JDK/etc...? digo como para tener en cuenta en un installer que incluya todo lo necesario para jugar, vengo experimentando mucho con distintos servers y en todos me faltan librerías o dll's, éxitos con el proyecto y gracias por contestar.
 
#20
Perdón la ignorancia pero para que los clientes podamos conectar al server ¿necesitamos el java común de los exploradores o descargar el JDK/etc...? digo como para tener en cuenta en un installer que incluya todo lo necesario para jugar, vengo experimentando mucho con distintos servers y en todos me faltan librerías o dll's, éxitos con el proyecto y gracias por contestar.
Hola! Tanto el servidor y el cliente estan en el repo, si lo que queres es un ejecutable, deberias correr la task llamada 'dist' con Gradle, que te va a crear los archivos .jar que luego podes ejecutar con Java. Aunque si es para testear tambien podes usar la tarea 'run'.
Desde una terminal, te ubicas en la carpeta donde tenes el repo, y ejecutas el comando "./gradlew server:run", o al menos asi lo corro yo usando Mac.

En windows se que puede variar y no se si tenes que setear algunas cosas en tu ambiente.
De seguro vas a necesitar la JDK.

Si necesitas que te de una mano mandame un mensaje y lo seguimos
 
Arriba