Hola querido foro, abro este post para preguntar a los usuarios de esta maravillosa comunidad, por sus técnicas y truquillos a la hora de trabajar con servidores de sockets, basados en protocolos de bytes.
Lo primero es disculparme con vosotros, por que quizás mi terminología no sea la correcta. He aprendido a programar por mi mismo, y no me ha enseñado nadie, con lo cual algunos términos puede que sean erróneos, pero intentare esforzarme en ello y ademas intentare explicarlo de otra forma mas sencilla para que nos entendamos.
Este servidor trabaja de tal forma:
-Servidor abre un puerto al que se conectan los clientes, y comienza a escuchar.
-Cuando el cliente se conecta, manda un mensaje al servidor con el protocolo Conectado y el servidor crea un nuevo proceso para el y le asigna un puerto único. Ademas, los otros clientes lo añaden a su lista de jugadores.
-Servidor crea un mensaje en el que el primer byte, señala el tipo de protocolo (en este caso, RecibirId), y tras ello añade la ID.
-Cliente recibe el mensaje, lee el primer byte y actúa según ello, en este caso, modifica su parámetro ID y enviando otro mensaje con su posición y rotación.
Esto mismo se utiliza mas tarde, por ejemplo para moverse, o para añadir nuevos jugadores conectados.
En mi caso, yo estoy trasteando con un servidor que encontré siguiendo un tutorial muy sencillo, para XNA (Si, ya se que lo han matado :qq: pero me encanta C#), quizás sirva para otros lenguajes, pero no estoy seguro xD. Os dejo el enlace al svn por si tenéis curiosidad:
https://phstudios.svn.beanstalkapp.com/samples/trunk/RelayServer/
Es bastante básico, la verdad, pero para hacer mis experimentos, me sobra! Ya que de hecho, es la primera vez que trabajo con sockets. Yo lo he estado modificando un poco a mi gusto, sobretodo para que me mostrara mas información en la consola, o para que mostrase los paquetes que envía... Pero ningún cambio importante.
Al principio todo iba bastante bien, los clientes se conectaban, se veían uno a otro, e incluso desaparecían cuando se desconectaban. Entonces me prepare para comunicar el movimiento... Y aquí llegaron los problemas. Uno de los principales problemas, creo, viene de mi sistema de movimiento. Intentare resumirlo:
El personaje se mueve con el ratón, haces click en un tile, el cliente calcula la posición y añade los waypoints o nodos conseguidos mediante A*Star, después el objeto Player se va moviendo por los waypoints hasta llegar a su destino.
En principio no hay ningún problema con el sistema de movimiento. Si, realmente el código en si es rudimentario, pero funciona. El problema viene cuando se intenta comunicar esto al servidor, y de ahí al resto de jugadores. Lo primero que intente fue lo que decía el tutorial de este servidor, crear un protocolo nuevo para cuando se moviese el jugador, enviar su posición actual. Pero esto daba resultados un poco inesperados, los jugadores dejaban de moverse antes de llegar al waypoint y cosas así, las animaciones no ocurrían o incluso saturaban el servidor por que se enviaba 100(fps) veces por segundo.
Después pensé que debía de adaptarlo para mi juego, y que lo que debía de mandar era el waypoint, y no la posición, pero por mucho que lo intentaba fallaba, con resultados como que desaparecían los jugadores, que no se calculaba bien la ruta y devolvía posiciones infinitas, o que crasheaba el cliente, así que desistí.
Mas tarde encontré lo que creía ser una solución en un proyecto que encontré por code.google, una solución bastante simple, tan simple como un timer para enviar tu posición. De hecho cuando la encontré, pensé... Por que no habré caído?, así es como funciona! Así que me dispuse a encontrar el equilibrio perfecto para que se actualizase la posición... Y como os esperáis, sin mucho éxito.
Cuando era poco tiempo(100 - 500ms), y se conectaban mas de 2 jugadores, el servidor se saturaba y crasheaba. Cuando era mucho tiempo(1s / 2s), el servidor aguantaba pero los jugadores se veían pegando saltos. El termino medio, era una mezcla de ambas, aunque me fije que a 750ms no daba tantos problemas como en los extremos. Para colmo, al usar este método, los otros jugadores conectados no podían ser animados, ya que como dije, el movimiento se basa en waypoints, y el jugador hace la animación de andar al seguir la ruta de los waypoints y mientras su velocidad sea mayor de 0.
A partir de ahí, he ido probando de muchas formas mas, pero sin buenos resultados. Como pasar la posición delta (posición - antiguaPosición), añadir un nuevo protocolo para la validación de la posición, intentar predecir el movimiento, o pasar la posición mediante las ID de los tiles en vez de coordenadas...
Así que tras un par de semanas buscando y probando formas de solucionar el problema, me decidí a escribir este post para preguntaros por las formas, métodos o truquillos que vosotros utilizáis para estos casos. No pido que me solucionéis el problema, mas bien lo que pido son consejos y otras formas con las que podría probar para solucionarlo. Quizás me he dejado algo por el camino, no lo se.
Si he de pegar algo de código, lo haré, aunque soy un poco reacio a ello ya que lo tengo hecho un desastre con tanto cambio! xD
Gracias por adelantado. Y perdonad por el tocho!