Foros del Web » Programación para mayores de 30 ;) » C/C++ »

Juego MMORPG

Estas en el tema de Juego MMORPG en el foro de C/C++ en Foros del Web. Hola de nuevo a todos. Les planteo una duda que tengo, he de decir que aun no me he puesto a escribir el código, pero ...
  #1 (permalink)  
Antiguo 12/12/2015, 13:38
 
Fecha de Ingreso: enero-2006
Mensajes: 76
Antigüedad: 18 años, 11 meses
Puntos: 1
Juego MMORPG

Hola de nuevo a todos. Les planteo una duda que tengo, he de decir que aun no me he puesto a escribir el código, pero si explico la pequeña historia de donde parte la idea, me entenderán mejor lo que quiero conseguir.

La historia es muy simple, me propuse hacer un juego multijugador tipo navegador en tiempo real, exactamente un juego de ajedrez. Es decir, entrabas en la web, te registrabas/loqueabas, y le dabas a jugar, entonces se quedaba tu navegador en espera de un oponente. Si otro usuario, le daba a jugar, el sistema los emparejaba y redireccionaba a ambos a una página donde aparecía un tablero de ajedrez, uno lo veía desde el punto de vista de las blancas y el otro desde las negras. Cuando el jugador de las blancas hacia un movimiento, al instante le aparecía ese movimiento en el navegador del contrincante, y el turno le pasaba al negro, y así sucesivamente. Todo esto incluido las jugadas legales de las fichas, como el enroque, tomar al paso etc, lo conseguí, y supongo que la mayoría de veteranos lo conseguirían con un esfuerzo mínimo. De hecho lo hice con sockest, un servidor en php y los clientes en javascript. Pero he aquí uno de los problemas con los que me enfrentaba, si un jugador le daba a refrescar la página, se cargaría la página con el tablero y las fichas desde la posición original, no la actual, luego aún tenia que resolver el problema del tiempo de ambos jugadores con las recargas de páginas (ya se sabe, uno tiene que prever del cliente/usuario las acciones que no deberían de hacer), para la colocación de las piezas a la posición actual con las recargas de página que el usuario hiciese, había previsto el guardar la posición de la partida en cada movimiento con el sistema storage que trae html5, parecía rápido y tal, pero lo del tiempo lo veía un poco complicado, ya que una de las modalidades del juego de ajedrez online es el añadido de tiempo por jugada, y en las recargas lo veía chungo y seguro que no sería ni muchísimo menos real. El juego en si está soportado por el cliente, ya que el código está escrito en javascript, y este se ejecuta en el lado del cliente, con lo que el servidor solo se encargaba de hacer de repetidor o comunicar a ambos jugadores de sus movimientos. Pero para hacerlo bien, y por lo que he podido deducir de las páginas que están funcionando, la recarga no les afecta nada, solo el clásico retardo de recarga, pero el tiempo que se carga es real, y lo otro es que en las partidas que se están jugando, cualquier otro usuario puede verlas metiéndose en la partida en cualquier momento de la partida, pudiendo ver el tiempo de cada jugador. Con lo que deduzco que la partida es tratada por el servidor y no por el cliente en el navegador.
La comunicación no lo veo muy complicado y aunque sea en ingles, hay buena documentación en internet para hacer un servidor sockets en C, pero...
Yo así pensando he llegado a la conclusión de que, cuando dos clientes le dan a jugar, el programa que esta ejecutándose en la memoria del servidor, crea una instancia de un objeto en memoria, de la clase partida, pero,... si otro par de jugadores le dan a jugar, crearía otra instancia de la clase partida, y ahora viene la duda, cuando los jugadores de la primera partida hacen un movimiento, como le digo al programa servidor que objeto de que partida ha de atender?
Igual me estoy liando yo solo, pero yo entiendo que al estar corriendo el programa en el servidor, al recibir una petición por un sockets, este responde a la petición, y si empieza por la creación de un objeto de la clase partida, luego ¿como se hace para retomar ese objeto ante las sucesivas peticiones de los jugadores que han sido los responsables de la creación de ese objeto, entre los múltiples objetos que habrán creado otros jugadores?
Lo de identificar a cada usuario conectado con un identificador único lo tengo asumido, pero en código, no se exactamente como acceder a las distintas instancias del objeto partida.

Gracias de antemano.
  #2 (permalink)  
Antiguo 12/12/2015, 16:20
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 10 años, 2 meses
Puntos: 204
Respuesta: Juego MMORPG

Estas intentando mezclar demasiadas cosas.

Si el servidor va con PHP no vas a poder crear nada persistente salvo que lo almacenes en una base de datos. El motivo es que el programa de PHP muere cuando la página termina de cargarse... Si el usuario recarga la página se inicia una segunda sesión de Php independiente de la primera.

El estado de la partida lo puedes almacenar en una base de datos, si un jugador refresca la página recuperas la partida y listo.

El control de los tiempos igual... Almacenas la marca de tiempo en el servidor y después cuentas el tiempo transcurrido entre la marca de tiempo y el momento en el que el jugador realiza la jugada... Si el jugador refresca la pantalla la marca de tiempo no variará y únicamente perderá el tiempo.

Cómo identificar que un jugador ha refrescado la pantalla? Bueno, para eso se inventaron las variables de sesión y las cookies... Si un jugador borra las suyas saltará algún timeout y la partida se le dará por pérdida.

Un saludo
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.
  #3 (permalink)  
Antiguo 12/12/2015, 18:18
 
Fecha de Ingreso: enero-2006
Mensajes: 76
Antigüedad: 18 años, 11 meses
Puntos: 1
Respuesta: Juego MMORPG

Hola eferion y gracias por responder.

No di todos los datos, de ahí tu afirmación de que el programa en php moriria al cerrarse la conexión del cliente. más que nada porque para hacer un servidor de sockets, lo que se tiene que hacer es lanzar el programa servidor como un servicio en windows o demonio en Linux, y correra siempre en segunda plano en el servidor, luego el php que mi juego si que tenia algo para acceder a la base de datos, ya era exclusivo para cada usuario, pero el servidor en sí, estaba funcionando por siempre. De hecho cuando hice la prueba para subirlo a internet, no tenia acceso en modo consola al servidor, ya que era gratuito, pero si que tenia la funcion de usar sockets, así que el hosting gratuito que utilice me redireccionaba las peticiones a mi propio ordenador, que era donde corria el archivo para las peticiones sockets. Por lo que el uso de php en el servidor es correcto, de hecho es lo que si que me funciona, lo que yo quiero es cambiar es ese archivo por uno en c o c++, y que maneje la partida.

Lo de guardar los datos de la partida para un eventual refresco de pagina en una base de datos, pues creo que o no me has entendido cuando hablé en la introducción o lo explique mal, pero eso es una utopia. El acceso a una base de datos tipo mysql para este tipo de programas con la rapidez que se pide, es una burrada de lento, de hecho ya mencione que eso lo pensaba hacer con la función storage de html5, ya que el refresco sería de parte del cliente, y sólo se pediría al servidor la hora. pero lo ideal es que los datos estén en memoria y así cuando se piden el tiempo de respuesta estaría dentro de los parámetros que se piden de rapidez. De hecho lo complicado es en el tipo de partidas con incremento de tiempo, ya que no sirve el calcular el tiempo de inicio de partida, el tiempo del rival, ... ya que según las jugadas de uno y del otro, ha habido un incremento de tiempo.

Lo que quiero es hacer un programa en c++ que funcione en el servidor, que responda a las peticiones de sockets de los clientes, y que; por cada petición de partida, cree un objeto tipo partida "por ejemplo", y así por cada petición de partida nueva, pero luego necesitaría saber como llamar a un objeto tipo partida creado anteriormente, esa es la cuestión, como saber que objeto tipo partida llamar.
  #4 (permalink)  
Antiguo 13/12/2015, 04:07
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 10 años, 2 meses
Puntos: 204
Respuesta: Juego MMORPG

Cita:
Iniciado por xonil Ver Mensaje
Lo de guardar los datos de la partida para un eventual refresco de pagina en una base de datos, pues creo que o no me has entendido cuando hablé en la introducción o lo explique mal, pero eso es una utopia. El acceso a una base de datos tipo mysql para este tipo de programas con la rapidez que se pide, es una burrada de lento, de hecho ya mencione que eso lo pensaba hacer con la función storage de html5, ya que el refresco sería de parte del cliente, y sólo se pediría al servidor la hora. pero lo ideal es que los datos estén en memoria y así cuando se piden el tiempo de respuesta estaría dentro de los parámetros que se piden de rapidez. De hecho lo complicado es en el tipo de partidas con incremento de tiempo, ya que no sirve el calcular el tiempo de inicio de partida, el tiempo del rival, ... ya que según las jugadas de uno y del otro, ha habido un incremento de tiempo.
Cuanto puede ocupar una partida en la base de datos? 10kb?
En una conexión a 10MB se podría tardar unos 100ms en enviar los datos al Cliente contando con pedirlos a la base de datos.

Google envía varios gigas de datos por segundo, recuperando todo de bases de datos y nadie se queja de su rendimiento.

Hacerse como digo se puede, simplemente hay que encontrar un equilibrio entre el número de jugadores y el número de servidores. Obviamente con servidores gratuitos se limita mucho el número de partidas simultáneas.

En cuanto a la penalización por actualizar... Eso es algo que hace el jugador de forma voluntaria y manual... El sabrá.

Cita:
Iniciado por xonil Ver Mensaje
Lo que quiero es hacer un programa en c++ que funcione en el servidor, que responda a las peticiones de sockets de los clientes, y que; por cada petición de partida, cree un objeto tipo partida "por ejemplo", y así por cada petición de partida nueva, pero luego necesitaría saber como llamar a un objeto tipo partida creado anteriormente, esa es la cuestión, como saber que objeto tipo partida llamar.
Y realmente crees que un programa tuyo va a estar más optimizado que una base de datos programada por gente con un nivel sorprendente?

Al fin y al cabo tu programa va almacenar las partidas... Que es lo que va a hacer la base de datos. ¿Y que desventaja se supone que va a tener la base de datos respecto a tu programa?
  • Rapidez. Eres consciente que mysql es una aplicacion bastante optimizada? con un buen esquema de tu base de datos ira como un tiro.
  • Rapidez (II)? Tu programa tendrá todo en memoria, vale. Las bases de datos tienen caché, que son datos almacenados en memoria. Si a la base de datos le das el tamaño suficiente de caché tendrá todas las partidas en memoria y su velocidad será inmejorable.
  • Rapidez (y III) que el servidor se conecte a una aplicación que esta en tu pc va a tener una latencia considerable. Los servidores de internet suelen evitar esto haciendo que servidor y base de datos estén en la misma red, lo que reduce el tiempo de transmisión y evita las colisiones. No vas a poder competir contra eso.
  • Seguridad? Vas a programar un sistema de autenticación con cifrado a nivel de red? No se, para evitar que pirateen tu programa a los 5 minutos... MySQL ya viene con todo eso integrado.

Piensa que el programa no lo vas a terminar en dos días.

Un saludo.
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.
  #5 (permalink)  
Antiguo 13/12/2015, 07:26
 
Fecha de Ingreso: enero-2006
Mensajes: 76
Antigüedad: 18 años, 11 meses
Puntos: 1
Respuesta: Juego MMORPG

No es que mi programa en C++ o C esté más optimizado que una base de datos, simplemente que al guardar algo en mysql lo que se hace es abrir la conexión a la base de datos, comprobar que la conexión sea correcta, asignar la tabla, construir la sentencia de consulta/modificación, realizar la operación, cerrar la base de datos, etc.

No lo digo por suponer, es que es así.
Si te molestas en consultar en internet sobre la conexión entre dos usuarios por web, verás que una de las opciones es a través de una base de datos mysql, es decir, tu envías unos datos, estos de guardan en la base de datos, y el otro usuario hace la consulta, y así se mantiene comunicados en una misma página los usuarios que quieras, pero eso para un chat si no te importa lo que se tarde, pues puede servir, pero no es recomendable, de hecho lo suelen descartar, ya que es muyyyyyyyyy lento la comunicación.

Rapidez I. ni me planteo la optimización, ya que lo único que que haría de más el nuevo servidor, es guardar en variables son 64 caracteres, quizás 70, y enviarlos por socket. Con lo que creo que esa perdida de tiempo se gana en la velocidad que se lleva de tener el programa servidor en php a C o C++.
Rapidez II. Lo de que esté en memoria es la respuesta más rápida, ya he dicho los inconvenientes del proceso de acceder a una base de datos.
Rapidez III. Como ya he dicho antes, la conexión se hace a través de sockets, con lo que lo de la rapidez de conexión, está más que conseguida.
Seguridad: La autentificación seguirá siendo en php-mysql, eso es irreemplazable, lo que quiero cambiar es el archivo que correra como servicio/demonio en el servidor y que es el responsable de atender las peticiones que entran por sockets.

A mi uno de mis profesores, cuando le comente lo de hacer un juego de navegador tipo travian, lo que me dijo es que cada acción que se hacia en el juego, se jugaba lo que quisiese a que no se hacia a través de la BD, ya que la latencia volvería el juego injugable, ya que las bases de datos no son rápidas en responder por la conexión, sino que lo son por la eficacia en buscar la información en sus archivos.
Y repito, que no te hablo de teoría, sino de hechos empíricos, para trabajar en tiempo real, no se debe de usar una base de datos, ya que es demasiado lento.
La respuesta de un programa escrito en C o C++ es mucho más rápido, y sólo debería guardar unos pocos ks, con lo que se puede incluso medir su tiempo de respuesta.

Gracias por responder.

Última edición por xonil; 13/12/2015 a las 07:35
  #6 (permalink)  
Antiguo 13/12/2015, 07:50
Avatar de vangodp  
Fecha de Ingreso: octubre-2013
Mensajes: 934
Antigüedad: 11 años, 2 meses
Puntos: 38
Respuesta: Juego MMORPG

Contrate un servidor con una de esas cuando se lancen >_<: http://computerhoy.com/noticias/hard...4-128-gb-37467
  #7 (permalink)  
Antiguo 13/12/2015, 07:51
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 10 años, 2 meses
Puntos: 204
Respuesta: Juego MMORPG

Cita:
Iniciado por xonil Ver Mensaje
A mi uno de mis profesores, cuando le comente lo de hacer un juego de navegador tipo travian, lo que me dijo es que cada acción que se hacia en el juego, se jugaba lo que quisiese a que no se hacia a través de la BD, ya que la latencia volvería el juego injugable, ya que las bases de datos no son rápidas en responder por la conexión, sino que lo son por la eficacia en buscar la información en sus archivos.
Y repito, que no te hablo de teoría, sino de hechos empíricos, para trabajar en tiempo real, no se debe de usar una base de datos, ya que es demasiado lento.
La respuesta de un programa escrito en C o C++ es mucho más rápido, y sólo debería guardar unos pocos ks, con lo que se puede incluso medir su tiempo de respuesta.
Te vuelvo a decir, google mueve varios gigas de datos por segundo en su buscador y la latencia para mostrarte 100 millones de resultados se puede medir en centésimas de segundo.

Lo que más suele afectar a la latencia suele ser el ancho de banda. Lo que no puedes pretender es que un portal gratuito te ofrezca un ancho de banda en condiciones... no es su intención palmar pasta con el servicio. Ya te puedo yo asegurar que un servidor tipo LoL no dispone de un ancho de banda de 100MB precisamente porque no daría abasto... y este tipo de servidores hacen uso de una base de datos ya que el coste de tener todo en memoria es desorbitado... y funcionan sin problemas.

Si quieres algo más específico lo que tienes que hacer es saltarte el protocolo http y la conexión tcp y basar tu programa en un servidor y clientes propios. Para ello simplemente tienes que currarte las dos aplicaciones, definir un protocolo de comunicación, ...

Además, para escalar el servicio también hay que ser coherentes con el número de usuarios que vaya a tener el servicio... no es lo mismo dar cobertura a 20 usuarios que a 20.000. La mejor solución para cada escenario es distinta.

Por otro lado me río yo de lo que opinen muchos profesores... si no que me expliquen por qué en algunos sitios siguen enseñando programación con lenguajes fuera de mercado. No digo que tu profesor pertenezca a ese grupo, pero a muchos hay que darles de comer aparte.

Eso sí, yo te recomendaría programarte tu propio servidor. Aprenderás muchas más cosas que si te limitas a aprovechar infraestructuras ya hechas. La mejor forma de conocer cómo funcionan estas cosas es manchándose las manos.

Un saludo.
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.
  #8 (permalink)  
Antiguo 13/12/2015, 08:01
Avatar de vangodp  
Fecha de Ingreso: octubre-2013
Mensajes: 934
Antigüedad: 11 años, 2 meses
Puntos: 38
Respuesta: Juego MMORPG

Contrate un servidor con una de esas cuando se lancen >_<: http://computerhoy.com/noticias/hard...4-128-gb-37467

Por cierto, yo no sé mucho de BDs pero tu das por echo que la búsqueda se hará en toda base de dados, eso llevaría tiempo sí, pero a lo mejor esa bd la puedes hacer tú optimizada, e mantener el descriptor de archivos abierto(FD) solo en la parte del cliente, un cliente por FD, es decir, si el cliente se conecta, se cría el FD para ese archivo/cliente, seria como tener el puntero encima de las variables todo el tiempo. Además ese tal triviam que has mencionado ni precisa de tanta rapidez, no es un shooter. XD Supongo que MySQL ya deba tener algo que permita configurarla en ese sentido, pero como he dicho, solo soy un gato muerto, y muchas veces digo tonterías >_<.

Pense en la función ftell que guarda o ponto en que se encentran os dados que se desee, es leer hasta encontrar esos datos, y cuando encuentres hacer algo como:
clienteX = ftell(fichero);

Con lo anterior no teria búsquedas, si no que el programa ya sabe donde está el archivo, es el tiempo de mover la aguja >_<. Como dije antes, quizás en shooters no valga, pero en Trivian ese seguro vale, lo que dice Eferion no esta mal dicho haga pruebas de tiempo, si sabes algo de la configuración de MySQL y los FD, o usando ftell quizás.

Última edición por vangodp; 13/12/2015 a las 08:10
  #9 (permalink)  
Antiguo 13/12/2015, 08:14
 
Fecha de Ingreso: enero-2006
Mensajes: 76
Antigüedad: 18 años, 11 meses
Puntos: 1
Respuesta: Juego MMORPG

Cita:
Iniciado por eferion Ver Mensaje
Te vuelvo a decir, google mueve varios gigas de datos por segundo en su buscador y la latencia para mostrarte 100 millones de resultados se puede medir en centésimas de segundo.

Lo que más suele afectar a la latencia suele ser el ancho de banda. Lo que no puedes pretender es que un portal gratuito te ofrezca un ancho de banda en condiciones... no es su intención palmar pasta con el servicio. Ya te puedo yo asegurar que un servidor tipo LoL no dispone de un ancho de banda de 100MB precisamente porque no daría abasto... y este tipo de servidores hacen uso de una base de datos ya que el coste de tener todo en memoria es desorbitado... y funcionan sin problemas.

Si quieres algo más específico lo que tienes que hacer es saltarte el protocolo http y la conexión tcp y basar tu programa en un servidor y clientes propios. Para ello simplemente tienes que currarte las dos aplicaciones, definir un protocolo de comunicación, ...

Además, para escalar el servicio también hay que ser coherentes con el número de usuarios que vaya a tener el servicio... no es lo mismo dar cobertura a 20 usuarios que a 20.000. La mejor solución para cada escenario es distinta.

Por otro lado me río yo de lo que opinen muchos profesores... si no que me expliquen por qué en algunos sitios siguen enseñando programación con lenguajes fuera de mercado. No digo que tu profesor pertenezca a ese grupo, pero a muchos hay que darles de comer aparte.

Eso sí, yo te recomendaría programarte tu propio servidor. Aprenderás muchas más cosas que si te limitas a aprovechar infraestructuras ya hechas. La mejor forma de conocer cómo funcionan estas cosas es manchándose las manos.

Un saludo.
Gracias de nuevo por responder, lo de google yo creo que es evidente, y es precisamente lo que dices, si manejas ese volumen de información, es porque tienes la tecnología para hacerlo, por eso la solución que busco es más coherente con mis circustancias.

Lo del servidor gratuito, pues naturalmente que dejan mucho que desear, de hecho si quiero manejar sockets, ya que puedo olvidar de los servidores gratuitos, ya que si no te los limitan para que no puedas tocar los puertos, no te dan acceso via telnet para su consola, es decir, no te dan todo el acceso.

Yo las pruebas las tengo que hacer en mi propio ordenador, con lo que se elimina el factor ancho de banda, y lo que mido son el tiempo de respuesta de cada solución.

Lo de contratar un vsp, pues hace un tiempo contraté un par de ellos en hostinger y la verdad, para salir del paso, puede que sirva, pero no me convencieron mucho, aunque he de decir que eran muy básicos.

Lo que has dicho de currarme yo mismo el protocolo, saltándome el http y el tcp, pués es lo que pensé hace seis meses, cuando todo esto empezó a fraguar en mi mente.
Pero después de leerme unos cuantos libros sobre protocolos y sobre todo, todo lo relacionado con programación en tiempo real, juegos en tiempo real y mmorpg (todo en ingles claro), me encontré con la solución que he estado manejando.
El juego en si, está logrado, y las partidas se podría jugar, lo que no he implementado es el control de tiempo y lo del refresco de la página.

Se que parezco un poco tiquismiquis, pero lo del refresco de la página está controlado en páginas como chess24, chess.com, ajedrezweb, playok etc, por lo tanto lo interpreto como que son programas o soluciones informáticas robustas.

Anoche encontré una solución intermedia, entre lo que tengo ya hecho y lo que quiero. La cosa es que como tengo el archivo que responde a los eventos, ese mismo archivo, podría encargarse de manejar cada movimiento de cada jugador en cada partida, y sin tocar los objetos, sino con variables multidimensionales y tal. Eso mismo lo podría hacer en C/C++, con un objeto y variables multidimensionales (matrices/vectores). Más que nada esto no es nuevo en este proyecto, es decir, ya lo pensé y me puse a hacerlo, pero luego vi que no era necesario y lo quité para no darle trabajo al servidor y que fuese todo el trabajo del ordenador del cliente, así el cliente no notaría casi nada por unas líneas más de código,y sin embargo el servidor se libraba de ejecutar esas mismas líneas multiplicadas por cada acción de cada usuario que estuviese jugando, pero si quiero robustez, tengo que tirar por ahí.

Sin querer alargarme más, lo que voy a hacer es mirar a ver la diferencia de tiempo entre php y c++, y según lo vea, puede que me merezca la pena.

ererion, estoy interesado en lo que has dicho de saltarme el protocolo http y tcp, pero no se por donde empezar. si me puedes dar alguna orientación de lectura, lo miraría poco a poco, ya que creo que esa es la solución comercial de las páginas mencionadas anteriormente.

Etiquetas: instancia, juego, objetos, sockets
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 11:46.