Buenas comunidad,

Desde que llevo en GM, pocas veces me he interesado en el tema de multijugador, ya sea porque no me interesaba, no estaba listo o no creía que GameMaker estuviese listo. Tengo un juego de hormigas, en el cual me está gustando como va quedando (está en Google Play bajo el nombre de "Ant War Simulator LITE"). Un juego donde tu controlas un hormiguero y tal, y tienes que luchar contra otros hormigueros.
Me gustaría poder hacer que una persona pueda conectarse a otra, es decir, uno de ellos hace de servidor, y el otro de cliente. El problema es que no sabria que vincular;
Si tu quieres ordenar que tus hormigas ataquen una cucaracha por ejemplo, envia una señal a la IA del hormiguero y empieza a enviar hormigas, deberia hacer que si el cliente pulsa el botón de atacar, esta señal se envie al servidor? Así no tendria que sincronizar la posicion de todas las hormigas, junto a su comportamiento y tal, que pueden ser cientas en el mapa.

Muchas gracias

He visto este artículo, me ha parecido bastante interesante y explicativo:
http://www.comunidadgm.org/articulos/(programacion)-hacer-un-juego-multijugador-online-con-game-maker-studio/

Con eso sigo teniendo unas dudas:
- El método que dije es correcto? El cliente solo envia ordenes, y todo lo procesa el jugador que hace de servidor.
- Un juego online casi nunca te pide la IP para jugar, no se si es posible que por ejemplo, cuando creas un servidor, se guarda en una base de datos la IP con la que se ha creado el servidor, el puerto y la ID del jugador. Así el cliente puede decir de conectarse a ese jugador, enviar una petición a la base de datos y obtener la IP y el puerto. Supongo que para obtener la IP al crear el servidor hay que usar PHP, lo que pasa es que no se deberian abrir los puertos o algo asi? Y funcionaria usando datos móviles?

#2 Diciembre 11, 2018, 08:01:42 PM Ultima modificación: Diciembre 11, 2018, 08:03:31 PM por Johann
Puedes hacer un servidor centralizado con cualquier lenguaje de programación, incluso con el mismo GM, al que se conectan los clientes y que se encargue de sincronizarlos a todos. Asi funcionan los videojuegos grandes.

Justo iba a compartir ese articulo XD pero no es exactamente el mismo:

https://www.comunidadgm.org/articulos/(programacion)hacer-un-juego-multijugador-online-con-game-maker-studio-ver2/
https://www.comunidadgm.org/articulos/crea-tu-juego-online-tutorial-php-mysql-gml-(programacion)/
Cita de: Fenris78Si un tema os resulta de interes y veis que hay poca información, la mejor solucion no es quejarse o pedir sin pensar, sino sugerir algo bien planteado o aportarlo vosotros mismos.
Cita de: CalioSomos desarrolladores independientes y, por lo tanto, no tenemos por qué guiarnos por las tendencias del mercado.

Lo que pasa es que me interesa que un jugador haga de servidor y a la vez juegue, realmente no son 2 jugadores, sino 4.

si el juego no es a tiempo real, sino que se basa en turnos, creo que con http, con el tuto de Niu debería ser suficiente (y tu imaginación o más posts xD ) :V

PD: es el SEGUNDO link que te pasó Johann, el uso de tcp te va a complicar mucho la vida xd
[spoiler="ola k ase clickarme o k ase"]la imagen no se quita xD
[/spoiler]

Es en tiempo real, y usaré UDP. Y deberé montarlo en un servidor para que no tengan que abrir los puertos y sea mas estable.

#6 Diciembre 11, 2018, 11:44:50 PM Ultima modificación: Diciembre 12, 2018, 12:22:23 AM por Black_Cat
Hola colega, pasate por mis tutoriales, ah no, asi no era XD

ya en serio, si vas a hacer un juego en tiempo real , te conviene de sobrada una conexion UPD, la TCP retrasa todo porque es un protocolo que verifica que se haya enviado el paquete completo sin romperse.
En cambio el udp envia datos todo el tiempo sin importar cual iba primero segundo, o si se perdió por ahí. Lo cual no importa mucho realmente ya que, una instancia al moverse tanto por el mapa es imperceptible o a lo sumo se genera eso que la gente llama "lag" que le dispara al enemigo pero este desaparece un segundo y re-aparece mas adelante.

No te recomiendo para nada usar mis tutoriales de TCP, jugar algo en tiempo real con eso va a ir super lento.


EDit: bueno, veo que publicaste como 5 segundos antes xD
Lo que deberías hacer es si, establecer un servidor que pueda alojar partidas. Un servidor que reenvie los datos del juego, porque muchas veces uno mismo como jugador no puede (o lo mas usual, que no sabe) abrir puertos, configurar el firewall. Es mas, los juegos triple A, usan varios puertos a la vez, no uno solo. Entonces deberías configurar el servidor para tener los puertos abiertos.
Sino sería hacer un Hole Punching para conectar sin mucho trabajo:
https://en.wikipedia.org/wiki/Hole_punching_(networking)


Con respecto a qué enviar al servidor.
Lo ideal sería mandar una señal cuando se ejecute cierta condicion. Por ejemplo, una vez que se haya atacado al hormiguero, el hormiguero del cliente debería enviar esa señal al servidor y entonces el servidor debería repartir la misma señal a los otros hormigueros.
Basicamente:
1-Cliente1 ataca hormiguero.
2-El hormiguero de cliente1 envia al servidor la señal.
3-El servidor retransmite a todos los demas clientes.
4-Los otros clientes reciben la señal.
5-Los hormigueros en los otros clientes, comienzan a generar hormigas.


Citardeberia hacer que si el cliente pulsa el botón de atacar, esta señal se envie al servidor? Así no tendria que sincronizar la posicion de todas las hormigas, junto a su comportamiento y tal, que pueden ser cientas en el mapa.
En un principio debería funcionar, pero el problema es que si se pierde el paquete, por ejemplo desde el cliente al servidor. Solo el cliente que crea las hormigas va a verlas salir. Mientras que los demás nunca recibirían la señal que se perdio en el trayecto.
Lo mismo podría pasar si desde el servidor se pierde el paquete hacia algún cliente.
A mi, me parece que deberías reducir las coordenadas a un dato pequeño, quiza un shortInt, ya que la resolucion no pasaria de los 2000px entonces ocuparía menos bytes, no se cuanto ocupa eso, en C al menos sé que son 2 bytes, mas otros 2 para la coordenada y, serían 4 en total por cada instancia. Poniendole que sacas 500 hormigas, algo un poco inusual, 2000bytes que son a lo sumo 2kb? Solo enviando hormigas. Yo CREO que no debería representar un problema. CREO

De todas maneras sería cuestion de probar eso sino alguna optimizacion, por ejemplo enviar la mitad de las posiciones en un step, la mita en otro, si total, es practicamente irrelevante tener la posicion exacta de cada hormiga. No así su estado de vida/muerto.


Otra cosa que recomendaba siempre el makero Texic, al hacer este tipo de juegos, era, enviar la señal para que se creen las instancias en los demas clientes, y que cada uno haga el calculo por si mismo. Lo cual puede ser el camino mas largo, pero iría bastante fluido el trafico de red.



Cita de: Black_Cat en Diciembre 11, 2018, 11:44:50 PM
Hola colega, pasate por mis tutoriales, ah no, asi no era XD

ya en serio, si vas a hacer un juego en tiempo real , te conviene de sobrada una conexion UPD, la TCP retrasa todo porque es un protocolo que verifica que se haya enviado el paquete completo sin romperse.
En cambio el udp envia datos todo el tiempo sin importar cual iba primero segundo, o si se perdió por ahí. Lo cual no importa mucho realmente ya que, una instancia al moverse tanto por el mapa es imperceptible o a lo sumo se genera eso que la gente llama "lag" que le dispara al enemigo pero este desaparece un segundo y re-aparece mas adelante.

No te recomiendo para nada usar mis tutoriales de TCP, jugar algo en tiempo real con eso va a ir super lento.


EDit: bueno, veo que publicaste como 5 segundos antes xD
Lo que deberías hacer es si, establecer un servidor que pueda alojar partidas. Un servidor que reenvie los datos del juego, porque muchas veces uno mismo como jugador no puede (o lo mas usual, que no sabe) abrir puertos, configurar el firewall. Es mas, los juegos triple A, usan varios puertos a la vez, no uno solo. Entonces deberías configurar el servidor para tener los puertos abiertos.
Sino sería hacer un Hole Punching para conectar sin mucho trabajo:
https://en.wikipedia.org/wiki/Hole_punching_(networking)


Con respecto a qué enviar al servidor.
Lo ideal sería mandar una señal cuando se ejecute cierta condicion. Por ejemplo, una vez que se haya atacado al hormiguero, el hormiguero del cliente debería enviar esa señal al servidor y entonces el servidor debería repartir la misma señal a los otros hormigueros.
Basicamente:
1-Cliente1 ataca hormiguero.
2-El hormiguero de cliente1 envia al servidor la señal.
3-El servidor retransmite a todos los demas clientes.
4-Los otros clientes reciben la señal.
5-Los hormigueros en los otros clientes, comienzan a generar hormigas.

En un principio debería funcionar, pero el problema es que si se pierde el paquete, por ejemplo desde el cliente al servidor. Solo el cliente que crea las hormigas va a verlas salir. Mientras que los demás nunca recibirían la señal que se perdio en el trayecto.
Lo mismo podría pasar si desde el servidor se pierde el paquete hacia algún cliente.
A mi, me parece que deberías reducir las coordenadas a un dato pequeño, quiza un shortInt, ya que la resolucion no pasaria de los 2000px entonces ocuparía menos bytes, no se cuanto ocupa eso, en C al menos sé que son 2 bytes, mas otros 2 para la coordenada y, serían 4 en total por cada instancia. Poniendole que sacas 500 hormigas, algo un poco inusual, 2000bytes que son a lo sumo 2kb? Solo enviando hormigas. Yo CREO que no debería representar un problema. CREO

De todas maneras sería cuestion de probar eso sino alguna optimizacion, por ejemplo enviar la mitad de las posiciones en un step, la mita en otro, si total, es practicamente irrelevante tener la posicion exacta de cada hormiga. No así su estado de vida/muerto.


Otra cosa que recomendaba siempre el makero Texic, al hacer este tipo de juegos, era, enviar la señal para que se creen las instancias en los demas clientes, y que cada uno haga el calculo por si mismo. Lo cual puede ser el camino mas largo, pero iría bastante fluido el trafico de red.

Vale, bueno, a decir verdad estoy algo perdido. Suerte que tengo un tutor de seguridad informática que sabe como funcionan estas cosas. Voy a plantear una cosa y a ver si tiene sentido;
- Compro un servidor y hago que pueda alojar varias partidas.
- Los clientes se conectan una partida del servidor.
- El servidor me sirve para enviar datos entre los clientes.
- Yo soy cliente 1, y decido enviar hormigas a un cierto lugar, así que pulso en la orden, y en vez de procesarla en el propio cliente y luego enviarla al servidor, la envio directamente al servidor, para que este envie los paquetes a TODOS los clientes, así si el paquete se pierde en el envio, el cliente que lo ha enviado no procesará la orden de enviar hormigas.
- Mi mayor duda es, todos los clientes tienen las instancias? Ya que por ejemplo, yo soy cliente 1 y estoy atacando a una hormiga de cliente 2, tendria que enviar un paquete desde cliente 1 a cliente 2 diciendo que he dañado a esa hormiga? Y por ejemplo si la hormiga de cliente 2 muere, enviar un paquete para que cliente 1 elimine esa hormiga?

Muchas gracias



UDP se utiliza porque envia directamente los paquetes hacia el lugar que le especifiques. Es más, incluso nisiquiera necesita realmente una conexion.

El problema es que:
1) se pueden perder datos al enviarlos
2) pueden llegar unos antes que otros, es decir , desordenados.
Es lo optimo para juegos multijugador en tiempo real? Si. Solo habría que solventar a mano estos inconvenientes.


Bueno, los pasos teoricos que debieran seguirse son:
1) Conseguir un host para colocar el servidor del juego. Crear la partida o bien, preparar la aplicación para que pueda manejar diversas partidas.
2) Una vez creado el servidor, los clientes deberían poder conectarse a la partida o bien a una partida dentro de la lista.
3) Una vez conectados los clientes con el servidor, solo es cuestión de que los clientes envien los datos.
4) Ahora, es trabajo del servidor enviar los datos a los jugadores. Ya sean lo que se unieron al principio de la partida o bien los que se están uniendo en medio.


Luego para los clientes, suponiendo que cliente1 ataca a una hormiga del cliente2:
Cliente1 debería mandar la informacion de ataque cuando en su juego, la hormiga_cliente1 este atacando a hormiga_cliente2.
Luego ocurriría que simplemente el servidor re-envia el paquete a los demas jugadores para que se vean lo mismo que cliente1.

Dicho esto, y quiero dejar claro que decirlo es mucho mas sencillo que hacerlo.

Deberías aplicar unas cuantas optimizaciones para mejorar el rendimiento de la red, además, teniendo en cuenta que pudieran haber 1000 hormigas, por ejemplo.
Como ser:
1) descartar los paquetes que llegaron tarde
2) no enviar las coordenadas si la posicion de la hormiga, no varió demasiado. Yo presupongo que al no ser un juego en el cual tengas que apuntar, la posicion es irrelevante en determinados casos. Sabes pos.x es practicamente lo mismo que x+2. No haría falta enviar las coordenadas todo el tiempo sino cuando se producta un movimiento notable.



A ver, es que hay una cosa que no sabeis, y creo que mejoraria la optimización. Es el hecho de que realmente no necesito enviar constantemente la posicióbn. Ya que las hormigas salen del hormiguero y se dirigen a una cierta posición mediante un pathfinding de grid, por lo que si mando que la orden de que en todos los clientes, ese hormiguero empiece a sacar hormigas en esa dirección, y otros parámetros, ya estaría hecho, ya que cogerian el mismo path igualmente. No se si me explico jaja.

Cosas como si una hormiga esta IDLE, y se le acerca una cucaracha, esta deberia atacarla, y se veria en todos los clientes, ya que debería estar en la misma posición y tal.

Se nota que en este tema voy perdido jaja, me miraré el curso de Tigerito019 cuando tenga tiempo.

Ah, viendo un poco el perfil de Tigerito veo que combina Python con GM.
Está bastante buena la idea, nunca se me había ocurrido.  Incluso hasta capaz se puede hacer una DB para registrar ususarios o alguna de esas cosas jaja