Ir al contenido

publicidad
publicidad

Foto

Desarrollo de videojuego [XNA]


Este tema ha sido archivado. Esto significa que no puedes responder en este tema.
60 respuestas en este tema

  • gothmog_es

  • IGNIS EXCUBITOR

  • vida restante: 100%
  • Registrado: 01 nov 2002
  • Mensajes: 22.690
#31

Escrito 09 marzo 2009 - 15:32

Yo no sé mucho de este tema en concreto, pero a mi parecer te estás preocupando en exceso de cosas que no deberías tener en cuenta. Por ejemplo, el que un jugador tenga peor conexión que otro... eso no es problema tuyo y no puedes arreglarlo en un juego en el que la acción transcurre en tiempo real. O la cantidad de jugadores simultáneos, siendo un juego de pequeña escala, con que manejes 1000 ó 5000 jugadores de forma satisfactoria tienes para tirar de sobra. No optimices lo que no te da problemas de optimización, sobre todo si para ello necesitas muchos recursos (en este caso, principamente tiempo).

Por otro lado, tal como lo veo yo, la comunicación tiene que ser tal que así:

Jugador sufre modificación -> Jugador notifica a servidor -> Servidor notifica a resto de jugadores

El servidor no puede estar haciendo polling activamente, eso me parece una burrada, pierdes recursos de red y recursos de cpu. Aparte de que de esa forma beneficiarías o perjudicarías a los jugadores en función de su posición en la lista. Debes tratar las modificaciones en orden de llegada.

Entiendo que el problema viene del broadcasting, porque para lo demás, el servidor simplemente escucha por un único puerto.

Yo la verdad es que no veo ni siquiera necesario meterte en historias de hilos. Simplemente tienes tu objeto de estado del juego, un array de conexiones salientes y un hilo escuchando en un puerto.

Según te llega una petición, modificas el estado y haces un broadcast al resto de jugadores.

  • deviax

  • Methuselah

  • vida restante: 100%
  • Registrado: 23 mar 2005
  • Mensajes: 182
#32

Escrito 09 marzo 2009 - 17:43

Hola gothmog_es,

Gracias por las ideas, ¡¡había pasado por alto el concepto de broadcast y multicast!!.

Pero con lo que me comentas me surge una nueva duda. Necesito usar TCP para las conexiones por lo que comentaba de que tengo que asegurarme de que todos los movimientos realizados por un jugador llegan al resto de jugadores. Y tras buscar documentación por la red llego a la conclusión de que no existe un multicast o broadcast propiamente dicho para TCP, debido a la naturaleza del protocolo TCP (lo cual es lógico, al ser un protocolo orientado a conexión sería una locura el enviar y esperar respuestas de miles de clientes).

He estado leyendo sobre [url)http://www.elguille....n_TCP.htm]gente que implementa sus propios multicast[/url] y que acaba convirtiéndose en problemas de hilos, concurrencia y fragmentación de la información (parece que no me libro de problemas O:) ).

Así que de nuevo me veo en el punto de partida. Estoy de acuerdo con el flujo de comunicación que dices de "Jugador sufre modificación -> Jugador notifica a servidor -> Servidor notifica a resto de jugadores", el caso es como hacerlo para que sea lo más eficiente y no de ventaja a ninguno de los jugadores en particular (planificación).., si estar con un solo proceso escuchando lo que digan los jugadores y arrancar con el flujo (perdiendo tiempo en conexiones y desconexiones), o tener eso corriendo en tantos procesos como jugadores (perdiendo tiempo controlando la concurrencia).

Muchas gracias por la idea gothmog_es ;), un saludo!.

  • gothmog_es

  • IGNIS EXCUBITOR

  • vida restante: 100%
  • Registrado: 01 nov 2002
  • Mensajes: 22.690
#33

Escrito 09 marzo 2009 - 20:34

Mmm, error mío, con broadcast no me refería al protocolo en sí, sino simplemente a mandarle el mensaje a todos los clientes :P

Así por encima no he conseguido dar con una respuesta, pero mis conocimientos de redes están algo escasos. Te dejo los enlaces que he mirado por si pudieras sacar algo:

http://www.gamedev.n...asp?forum_id=15
http://www.gamedev.n...topic_id=319003
http://trac.bookofho...GameProgramming

  • Ollydbg

  • Valefor

  • vida restante: 100%
  • Registrado: 05 sep 2008
  • Mensajes: 6.259
#34

Escrito 10 marzo 2009 - 21:27

A ver, por partes, como diría Jack el destripador :D

Posiblemente estes intentando implementar una de las rutinas más complicadas en el desarrollo de un videojuego: Gestión On-Line de los jugadores.

Hace tiempo miré documentación para ponerme al día sobre este tema, y ya te digo desde aquí que no es nada fácil implementarlo bien. Mi preocupación radicaba más en el aspecto del "hacking" que en el aspecto del protocolo.

Te lo comento, porque por mucho que encriptes el protocolo "cliente-servidor" (he visto autenticas chapuzas en juegos con mas de 500.000 usuarios, con eso te lo digo todo), si dejas que el cliente tome muchas decisiones, tu juego es campo abonado a los chetos (y no precisamente los chetos de matutano).

Mal, muy mal, fatal, error, meec, warning, cheto incoming:

1) Jugador sufre modificación (por ejemplo, posición)
2) Jugador notifica la posición al servidor
3) Servidor notifica la posición al resto de jugadores

Medianamente bien:

1) Jugador sufre modificacion (por ejemplo, posición)
2) Jugador notifica la posición al servidor
3) Servidor: ¿La posición que me dices es válida?
3a) Servidor: Si. Posición válida: Notificar al resto
3b) Servidor: No. No actualizar la posicion del jugador

Correcto:
1) El jugador es "una pantalla tonta"
2) Servidor: La posición (x,y) anterior del jugador es distinta a la posición (x,y) actual
3a) Servidor: Si: Actualizar posicion jugador
3b) Servidor: No. No actualizar la posición del jugador.

En este último caso, el cliente no toma ninguna decisión, es únicamente un "renderizador de estados".

Obviamente cada opción tiene sus pros y sus contras. Un "Cliente" que toma decisiones descarga de trabajo al servidor, pero por el contrario te la pueden meter doblada.
Un "Cliente" que sea un terminal "tonto" carga de trabajo al servidor, pero es más difícil (que no imposible) que te la metan doblada.

Además existen multitud de "trucos" para engañar al servidor: ¿Te suenan los chetos llamados "speedhack"?. Pues básicamente estos chetos se aprovechan de la latencía existente entre el cliente y servidor para introducir retardos en la comunicación. El servidor de alguna forma interpola la posición "futura" de un cierto cliente para mitigar de algún modo los efectos del ping. Pues "jugando" con estos parámetros es posible "engañar" al servidor para que crea que la posición "futura" sea (x+n,y+n) en vez de (x,y) no sé si me explico.

Pero vamos, que me estoy volviendo a ir por los cerros de Úbeda.

Tendría que para y pensar una buena solución (que no es fácil) ya que ni tú opción 1) ni tú opción 2) son las más eficientes.

Ánimo y adelante.

Saludos.

PD: Por cierto, hacer broadcasting ("A" envía un mensaje que se recogido por todos los "nodos que están a la escucha por el puerto de broadcast") en .NET es igual de fácil que iniciar una conexión UDP / TCPIP. Si necesitas te paso el código del broadcasting que hago yo en mi aplicación (para ver entre otras cosas cuantas instancias de mi programa se están ejecutando en la misma LAN)

  • deviax

  • Methuselah

  • vida restante: 100%
  • Registrado: 23 mar 2005
  • Mensajes: 182
#35

Escrito 11 marzo 2009 - 11:50

Muchas gracias por las respuestas gothmog_es y Ollydbg, como siempre, toda la información que me aportais me viene muy muy bien para saber que poder hacer o que tal puede estar las ideas que comento.

Las primeras dos páginas que me has puesto gothmog_es las estuve viendo hace dos días y son un gran rifi-rafe acerca de detalles muy muy importantes. Están genial porque te preparan para lo que vas a tener que lidiar y te aportan muchas ideas y soluciones. La última no la conocía así que le echaré un buen vistazo.

Y sobre las ideas que me comentas Ollydbg, voy por partes también jejeje.
Lo que comentas de toda la seguridad encriptando información, desde luego que es un básico, pero de momento mi primera preocupación es crear la infraestructura cliente-servidor que sea más eficiente, ya me ocuparé de los chetos (que no los de matutano :) muy agudo!).

Respecto al modelo que iba a utilizar para comunicar servidor y cliente, mi primera idea fue la que dices que es malísima y estoy completamente de acuerdo contigo xDD. Lo que estaba valorando ahora (tras leer los enlaces que decía gothmog_es) es que los clientes envíen mensajes al servidor con los movimientos, por ejemplo "presiono la tecla de ir hacia arriba" y que sea el servidor quien le diga "pues entonces estás en X,Y". Podría crear colas de mensajes, y planificar la ejecución en plan "1 ciclo de X milisegundos para procesar todos los mensajes, otro ciclo para responder a todo el mundo, otro ciclo para obtener nuevos mensajes". Para optimizar esta idea se me ocurre que los clientes no estén enviando constantemente las teclas presionadas, sólo los cambios, así si mantienes presionada la tecla W para avanzar, sólo lo mandas una vez y se queda avanzando hasta que la sueltas y se vuelve a mandar ese nuevo estado.

Con la idea de la cola de mensajes y planificar la ejecución tal vez podría evitarme el lío de manejar hilos y concurrencia, a costa de que tal vez me interesaría aprender a manejar sockets TCP asíncronos...

  • deviax

  • Methuselah

  • vida restante: 100%
  • Registrado: 23 mar 2005
  • Mensajes: 182
#36

Escrito 27 abril 2009 - 12:53

Sigo comentando el avance con cuenta gotas :P.

Ya he terminado de implementar toda la comunicación entre clientes y servidores. Ha supuesto bastante esfuerzo debido a la dificultad que introduce la concurrencia y a tener que crear un sistema que comunique las coordenadas de tal modo que los jugadores se muevan por el mundo de forma fluida, ¡¡además con un consumo de la red muy razonable!!. En las pruebas que he hecho, con 5 jugadores conectados a la vez el servidor usaba sólo 0.4 KB/s para envío y cada cliente 0.2 KB/s para recepción.

En ESTA entrada podeis ver un vídeo del estado del proyecto antes de mejorar el sistema de colisiones. Se supone que los cuadradotes esos grandes serían los personajes.

La siguiente parte consistirá en trabajar un poquito el sistema de menús y dar al jugador la posibilidad de crear, seleccionar y borrar personajes en el servidor.


¡Ah!, aprovecho para recordaros que sigo buscando a gente que le interese participar en el proyecto. Ahora mismo lo que más me interesa es encontrar diseñadores gráficos, la idea para el juego es: gráficos 2D, ambientación estilo cyber-punk y diseño de los personajes estilo manga. Otro área donde vendría bien algo de ayuda es para aportar ideas respecto a la jugabilidad: tipos de personajes, habilidades (recuerdo que es un MMORPG aunque con una perspectiva algo distinta :P), misiones, etc.

Algunos ejemplos del estilo que busco para personajes son los siguientes:
Imagen 1
Imagen 2
Imagen 3

S!

  • Ellolo17

  • Zodiark

  • vida restante: 100%
  • Registrado: 16 nov 2006
  • Mensajes: 6.208
#37

Escrito 27 abril 2009 - 13:49

Vaya, y yo que tengo en mis apuntes que es:

Programa cliente: Controla las colisiones, estado y la entrada de datos del jugador. Envia ya tratadas sobre si es correcta o no la posicion del jugador. Basicamente, aqui se hacen los calculos de cada personaje jugador y pasa los datos ya tratados al servidor.

Programa servidor: Recibe los datos ya tratados de posicion, estado del jugador y los objetos de cada jugador. Recibe de todos los jugadores, trata algunos datos si es necesario -las granadas por ejemplo cuentan como ejemplo de objeto del jugador, el jugador las lanza, el cliente crea el objeto, le manda al servidor que hay una granada en tal punto, el cliente dice cuando explota segun la programacion, y cuando le llega al servidor el dato de que ha explotado, el servidor crea un objeto explosion que es tratado en el servidor. Comprueba las coordenadas que tiene de todos los jugadores, ve a quienes afecta, y devuelve el vector que lleva hacia otro lado a los jugadores y el daño que pierden a cada respectivo cliente-

Bueno, no se si me he explicado bien, pero mas o menos asi. Los calculos pesados, en el cliente -como colisiones y todo eso- y los ligeros, en el servidor.

Ejemplo: el ultimo Swat. Ahi cada cadaver aparece en una posicion distinta en cada cliente porque las ragdolls y las colisiones de estas las trata el cliente. El servidor solo indica al cliente que debe crear la ragdoll en esa posicion. Y uno se da cuenta si juega en lan con alguien o al usar el micro con algun compañero, el cadaver puede estar mirando hacia otro sitio. O puedes estar haciendo un teabag en donde no hay nada.

Aunque en los ultimos tiempos ha cambiado y mis apuntes no sirven de nada porque por ejemplo en el ultimo halo se graba la partida y tienen todos esos datos registrados en el servidor y no se bien de que se encarga cada programa o si se calcula todo en el servidor o que.

Un saludo.

#38

Escrito 27 abril 2009 - 15:43

Bueno cuando terminen me lo mandan!!!! XD... jajajaja

  • deviax

  • Methuselah

  • vida restante: 100%
  • Registrado: 23 mar 2005
  • Mensajes: 182
#39

Escrito 27 abril 2009 - 16:15

Estoy en completo de acuerdo contigo Ellolo17,

De hecho, es más o menos como lo hago ;). Me gusta plantear el tema del procesamiento y envío de información a través de la red como si se tratara de un problema de computación distribuida, y en estos casos cada elemento de la red tiene una función.

En los clientes calculo colisiones y coordenadas (porque por el momento no hay más que eso) y estos se envían al servidor. Por ejemplo, presionas la tecla arriba, entonces el cliente envía su coordenada y que se dirige hacia arriba, así se sabe en donde está y hacia donde va en todo momento, y cuando colisiona se envía el mismo mensaje que cuando se deja de presionar todas las teclas, así el jugador se detiene y todos los jugadores lo saben.

Pero todo esto tiene su contrapartida, que es lo que comentaba anteriormente Ollydbg, cuanta más información se procese en los clientes, más posibilidad de cheating introduces. En el ejemplo que ponías de la granada, si el juego envía que tu granada cae en una coordenada, y el servidor no comprueba si es posible realizar ese movimiento, podrías lanzar una granada al otro extremo del mundo.., por eso hay gran parte de movimientos que tienen que ser procesados o por lo menos supervisados por el servidor (basicamente cualquiera que afecte al resto de jugadores).

Así que tranquilo, tus apuntes aun cumplen con la normativa vigente jejeje, sólo que con lo tramposos que somos algunos jugadores :twisted: hay que ir poniendo parchecillos.

  • Ollydbg

  • Valefor

  • vida restante: 100%
  • Registrado: 05 sep 2008
  • Mensajes: 6.259
#40

Escrito 28 abril 2009 - 20:07

¿La implementación v3.0 es aún correcta? (¿qué pasó con la implementación v4.0 ;) ? ¿O por el contrario en esa implementación estaban el SC, el SL y el SPJ todos juntos?
¿Cómo has montado el sistema de hilos en los servidores? ¿Un hilo por jugador, o bien un hilo para la recepción y otro para la transmisión? o cómo. Explica un poco más sobre el tema del balanceo de la carga, parece interesante. O cómo se comunican los servidores entre sí.
La verdad es que pinta estupendo, aunque la prueba de fuego sería probarlo no dentro de una LAN sino con "conexiones reales del mundo exterior". ¿Para cuando una descarga del cliente para realizar una prueba de "stress"? ¿o una descarga del cliente + servidores para probarlo nosotros?.

Lo dicho, el vídeo buenísimo. Buscas gente para colaborar en el proyecto. Yo te ayudaría encantado, pero lo mio no es el diseño, sino la programación en .NET, lastima :(

Saludos.

  • Ellolo17

  • Zodiark

  • vida restante: 100%
  • Registrado: 16 nov 2006
  • Mensajes: 6.208
#41

Escrito 28 abril 2009 - 20:12

Eso dentro de poco que se esta currando un buen tutorial de eso para el foro ;)

-Porque sigues haciendo el tutoria, ein?:cabreado:-

Un saludo ;)

  • deviax

  • Methuselah

  • vida restante: 100%
  • Registrado: 23 mar 2005
  • Mensajes: 182
#42

Escrito 28 abril 2009 - 21:53

Hello!,

Ollydbg, la versión 4.0 no la he comentado porque es toda la parte de implementación de servidores y clientes. De forma esquemática, al final funciona así:
1. Se arranca el SC que queda a la espera del resto de servidores.
2. Se arranca el SL, que informa al SC de que está activo.
3. Se arranca el SPJ, que informa al SC de que está activo.
4. Se conecta el cliente al SC
4.1 SC avisa a SL y a SPJ de que se va a conectar un jugador, estos servidores crean un hilo para atender la petición que recibirán del jugador y le dicen al SC los puertos por los que atenderán al jugador.
4.2 SC le comunica al jugador que ya están listos el SL y el SPJ, y le informa de en qué máquinas están corriendo estos servidores y por qué puerto le van a atender.
4.3 El jugador se comunica con SL para seleccionar, borrar o crear personajes. Una vez que selecciona un personaje, SL avisa a SPJ para que sepa que el jugador va a jugar con X personaje.
4.4 El jugador se comunica con SPJ para comenzar a jugar (SPJ le está esperando con los datos del personaje listos para jugar)
5. Comienza la comunicación del juego. El SPJ tiene dos hilos para cada jugador, uno para recibir las coordenadas y movimientos que realiza éste, y otro para enviarle las coordenadas y movimientos de los otros jugadores.

Sobre lo de las pruebas, a ver si este fin de semana abro un par de puertos en el router y lo pruebo por internet, pero en principio y visto el bajo consumo de red confío en que vaya fluido...

Y sobre lo de colgar los ejecutables, con la siguiente versión lo pondré para que se pueda descargar y cacharrear un poco. Que ya por lo menos se pueda elegir personajes (ahora mismo te los selecciona de forma automática), y que haya un sistema de menús (el que está ahora está para probar la creación de contenedores, selectores de opciones y patrones de diseño como el Observer o FactoryMethod).


Y sí Ellolo17, continúo con el tutorial :D. Ya tengo practicamente terminado el PDF que decia que iba a incluir teoría sobre redes. Ya está terminado todo el tema de la comunicación, que es un poco rollo especialmente para los que ya sepais como funciona el asunto (ventajas y desventajas de usar TCP frente a UDP), y ahora estaba comentando un poco sobre concurrencia. Creo que puede ser útil como primera aproximación a la gente que se introduzca en el tema.

Luego en el propio post pondré ejemplos muy simples de código para crear servidores y clientes con ambos protocolos y un control de concurrencia sencillo.

Ya por último, siento demorarme con el tuto, pero entre trabajo, universidad y proyecto le faltan horas a los días :oops: .

Un saludo.

PD: Toma tocho.. :?

  • Ollydbg

  • Valefor

  • vida restante: 100%
  • Registrado: 05 sep 2008
  • Mensajes: 6.259
#43

Escrito 30 abril 2009 - 00:30

Bueno, tal y como he podido interpretar he dibujado el siguiente esquema:

Imagen Enviada

Por mi parte el cliente necesita abrir dos puertos, un TCP para comunicarse con el SC y otro UDP para comunicarse con el SPJ que se le ha asignado durante el login. (no entiendo cómo es que en tu esquema solo necesitas abrir el puerto con el SC, cuando el el SPJ el que envía "cosas" al cliente, o quizás me he perdido algo)

La cosa va mas o menos como sigue:

* Se lanza el SC y se deja a la "escucha", tanto por el puerto 5000 cómo por el puerto 6000 y el puerto 7000.
* Se lanza el SL (previamente, en algún sitio está la dirección IP del SC, en un fichero INI / XML o algo parecido). El SL lee este fichero de configuración y se conecta con el SC y le envía "Aquí estoy, soy el SL y estoy en la IP xxx.xxx.xxx.xxx". Esta conexión es TCP/IP
* De igual forma se lanzan los "n" SPJ. Cada SPJ lee la configuración de un INI / XML con la direccion IP del SC. Se conectan al SC y le envían "Aqui estoy, soy el SPJ nº X y estoy en la IP xxx.xxx.xxx.xxx:pppp". Está conexión también es TCP/IP

Una vez iniciados todos los servidores se lanza un cliente.

* El cliente se conecta con el SC. El SC ve que es un cliente "no logeado" e informa al SL que el cliente con la ID:xxxxx se acaba de conectar. En mi caso no creo ningún hilo en el SL para ese cliente (ni para níngún cliente). En la práctica el cliente "estará poco tiempo conectado al SL", o dicho de otra forma, lo que se hace en el SL "no es crítico". La comunicación entre el SL y el cliente se hace a través del SC, ya que a priori en el SL vamos a estar "poco" tiempo:
Cliente to SC ---> "Lista de personajes" ---> SC to SL ---> "Devuelve la lista de personajes del ID:xxxxx" ---> SL : en el hilo del ID:xxxx consulta la BDD ---> La BDD devuelve la inforamción ---> SL to SC---> "info de los Personajes" ---> SC to Cliente ---> "info de los Personajes"

El cliente crea una nueva ficha o selecciona uno de los personajes que ya tiene creados. Todo esto mediante un "protocolo" Cliente ---> SC --- SL ---> BDD ---> SL ---> SC ---> Cliente.

Ahora viene el login:

¿Cómo balanceo la carga?. Yo he supuesto esto:

* El cliente está listo para logearse. El SL, de nuevo a traves del SC pregunta al SPJ #1 cuantos jugadores está gestionando. Hay que recordar que el SC sabe en todo momento "cuantos" SPJs hay disponibles..

SL to SC ---> "devuelveme los jugadores que hay en cada SPJ"
SC to SPJ #1 --->"¿Cúantos jugadores tienes?" SPJ #1 to SC ---> "Tengo 10"
SC to SPJ #2 --->"¿Cúantos jugadores tienes?" SPJ #2 to SC ---> "Estoy full"
SC to SPJ #3 --->"¿Cúantos jugadores tienes?" SPJ #3 to SC ---> "Tengo 40"
SC to SPJ #4 --->"¿Cúantos jugadores tienes?" SPJ #4 to SC ---> "Tengo 2"

SC to SL --->"SPJ#1:10,SPJ#2:full,SPJ#3:40,SPJ#4:2"

(todo esto también via TCP por el puerto 7000)

Con esta información el SL va a "meter" al cliente en el SPJ#4, ya que es el que tiene menos "carga" de trabajo.

Por lo tanto, el SL informa al SC que va a meter a ese jugador en el SPJ#4. Esta información queda registrada en el SC y el SC envía al SPJ #4 lo siguiente:
SC to SPJ #4 --->"vas a gestionar El cliente con ID:xxxxx, así que ya estas creando dos hilos en tu servidor, uno para gestionar lo que te envía el cliente y otro para gestionar lo que vas a enviar al cliente". Al mismo tiempo el SC informa al cliente que se va a comunicar con el SPJ #4 que está en la ip:xxx.xxx.xxx.xxx:pppp (UDP).

Y aquí llega la parte donde ya me pierdo y donde no entiendo bien como lo haces:

El cliente envía al SPJ #4: "He pulsado la tecla <---"

¿Cómo demonios se enterán el resto de clientes?. Ete aqui el problema.

Yo he supuesto esto, no sé si será lo correcto:

Cliente to SPJ #4 ---> "He pulsado la tecla <---. Mi posición despues del movimiento debería ser (xxx,yyy,zzz)"
De momento no he supuesto nada en el SPJ #4 para verificar que ese movimiento es correcto. Lo que ahora me interesa es que "el resto" de jugadores "vean" que me he movido.

¿Cómo? La idea es solo enviar esa información a los jugadores "que estan cerca" ¿para que se tiene que enterar un jugador que está a 30.000 km de distancia que me he movido, que he tirado el ataque X o que he matado a la rata X?. Pues eso

Tenia pensado hacerlo asi:
En todo momento cada SPJ sabe (o por lo menos debería saber) en que posición se encuentra cada cliente que esta gestionando. La dificultad aquí reside que dos jugadores pueden estar "uno al lado de otro", pero uno puede estar en el SPJ #1 y otro en el SPJ #4, por ejemplo.

Todos los SPJs estan interconectados entre sí mediante una conexión UDP que usarán los SPJs para intercomunicarse entre ellos. De esta forma, el SPJ #1 está intercomunicado con el SPJ #2, el SPJ #2 con el SPJ #3 y el SPJ #3 con el SPJ #4 y el SPJ #4 con el SPJ #1 (es una conexión circular)

Si suponemos por ejemplo, que yo me muevo y estoy en el SPJ #2 y un amigo mio esta a mi lado y resulta que él está en el SPJ #4, la cosa iría mas o menos asi:

SPJ #2 to SPJ #3 --->"Busca 'vecinos' a las coordenadas (xxx,yyy,zzz)"
inmediatamente el SPJ #3 al recibir esto, envía lo siguiente:
SPJ #3 to SPJ #4 --->"Busca 'vecinos' a las coordenadas (xxx,yyy,zzz)"
inmediatamente el SPJ #4 al recibir esto, envía lo siguiente:
SPJ #4 to SPJ #1 --->"Busca 'vecinos' a las coordenadas (xxx,yyy,zzz)"
inmediatamente el SPJ #1 al recibir esto, envía lo siguiente:
SPJ #1 to SPJ #2 --->"Busca 'vecinos' a las coordenadas (xxx,yyy,zzz)"

¿Quizás necesite un hilo para la intercomunicacion entre SPJ's?

Aquí no se si tendría que hacer estas "busquedas" en un hilo. ¿Algún consejo?

Total, que ya bien sea en un hilo o no, el SPJ #n buscará todos aquellos jugadores que estén cerca de (xxx,yyy,zzz). Si esto es cierto, el SPJ n enviará al cliente en cuestión (aquí si que se hace dentro del hilo para aquel cliente) "El jugador xxxx está en la posición (xxx,yyy,zzz): Pintalo"

¿Estoy haciendo o interpretando algo mal?

Saludos.

  • Ellolo17

  • Zodiark

  • vida restante: 100%
  • Registrado: 16 nov 2006
  • Mensajes: 6.208
#44

Escrito 30 abril 2009 - 09:15

¿Que? :S

Mis conocimientos de redes no llegan a tanto... Al menos algo me han permitido entender de esto...


Pues yo aporto parte de la ayuda sobre este tema del motor que uso:

Here are some basic concepts for designing a multiplayer system:
- Establish Connection Types
- Select Desired Connection and IP Address
- Decide Whether User is Host or Client
- If Host, Find Game, if Client, Join Game
- Exchange Name/Gamestate Data as Players Joins
- Keep a Running List of Current Players
- Continually Run Receiving Routine for New Packets
- Proceed with Desired Game Progression
- Check for Lost/Disconnected Players
- Check for Latency (Lag), Adjust as Needed


Un par de consejos para evitar el lag:

- Never insert a SLEEP command in your main gaming routine. Pausing like this means your receiving routine can"t check for incoming packets, causing a backlog. It also means a packet may get lost as they are discarded by DirectPlay if delayed.

- Never transmit more packets then you receive from any one player.

- Always check the time it takes for packets to arrive from other players. When in doubt, never transmit packets at a rate faster then you receive packets from the slowest player.

- Always check for incoming messages in your main game loop, even when in menus.

- Never attempt to send more then one packet per SYNC. You can"t do it anyway and should never need to since all data should be contained in a single string packet (for our example).


Consejos para mejorar la integridad:

- For internet gameplay with players using a variety of connection speeds, keep packet exchanges at around 4 per second (250ms) with 4-6 players or less.

- For high speed internet connections (all players), you can generally use an exchange rate of about 5-8 packets per second.

- For LAN connections, 8-15 packets per second generally works well.

- Adding more players generally means reducing the packets per second.


Un ejemplo de una traza enviada

[code:1]packet$=playername$+"*"+str$(camera position x())+"*"+str$(camera position y())+"*"+str$(camera position z())+"*"+str$(camera angle x())+"*"+str$(camera angle y())+"*"+str$(camera angle z())+"*"+speed$+"*"+fireweapon$+"*"+ping$[/code]
Este codigo seria en Darkbasic. El comando str$ convierte a texto, las otras funciones son bastante explicitas en su nombre ^^

Si se usa ese modelo de traza, aqui tienes lo que se enviaria:
"Bill10424*543.1122*58.2311*801.8790*44.3250*172.0093*94.2210*15*0*2480"



Espero que todo esto te sirva de ayuda

  • deviax

  • Methuselah

  • vida restante: 100%
  • Registrado: 23 mar 2005
  • Mensajes: 182
#45

Escrito 30 abril 2009 - 10:31

Hello again!,

Vaya currada os habeis marcado :). Os contesto a cada uno en un post para no liar unas cosas con otras.

Ollydbg, simplemente increible :D. Con la información que dí tan esquemática practicamente has reconstruido toda la comunicación, y en algún que otro detalle has planteado soluciones alternativas, te comento:

Por mi parte el cliente necesita abrir dos puertos, un TCP para comunicarse con el SC y otro UDP para comunicarse con el SPJ que se le ha asignado durante el login. (no entiendo cómo es que en tu esquema solo necesitas abrir el puerto con el SC, cuando el el SPJ el que envía "cosas" al cliente, o quizás me he perdido algo)


Para comunicar información he usado sólo TCP, ya que al tener corriendo en cada hilo la recepción o envío de información no me supone una pérdida de tiempo el establecimiento de conexión, además que necesito garantizar que los jugadores son informados de los movimientos.

Sobre lo que no entiendes, no entiendo lo que no entiendes jejeje. El tema de los puertos, tal y como lo he planteado es lo más sencillo de cara al jugador, para que sólo tenga que abrir un puerto, el de recepción de información del SPJ. Así, sólo hace falta saber la IP y el puerto del SC, y éste ya se encargará de decirle "el SL te va a escuchar en esta IP:Puerto y el SPJ en esta IP:Puerto". Los servidores en cambio si que tienen que abrir los puertos dinámicamente. Cuando entra un jugador lo abren, y cuando sale, lo cierran y lo dejan preparado para asignarlo cuando llegue el siguiente jugador (cojo un puerto base, y sumo desplazamientos, por ejemplo arranco escuchando en el TCP:5000, pues el jugador uno conectará en 5000, el siguiente en 5001, 5002.., y si se desconecta el jugador 1, pues el siguiente que conecte entrará en el 5001 otra vez).

La cosa va mas o menos como sigue:

* Se lanza el SC y se deja a la "escucha", tanto por el puerto 5000 cómo por el puerto 6000 y el puerto 7000.
....


Esa parte la hago como comentas, tengo unos ficheros de configuración de momento en texto plano, de ellos se lee la configuración y el paso de mensajes de unos con otros consiste en lo que comentas.


Una vez iniciados todos los servidores se lanza un cliente.

* El cliente se conecta con el SC. El SC ve que es un cliente "no logeado" e informa al SL que el cliente con la ID:xxxxx se acaba de conectar. En mi caso no creo ningún hilo en el SL para ese cliente (ni para níngún cliente). En la práctica el cliente "estará poco tiempo conectado al SL", o dicho de otra forma, lo que se hace en el SL "no es crítico". La comunicación entre el SL y el cliente se hace a través del SC, ya que a priori en el SL vamos a estar "poco" tiempo:
Cliente to SC ---> "Lista de personajes" ---> SC to SL ---> "Devuelve la lista de personajes del ID:xxxxx" ---> SL : en el hilo del ID:xxxx consulta la BDD ---> La BDD devuelve la inforamción ---> SL to SC---> "info de los Personajes" ---> SC to Cliente ---> "info de los Personajes"

El cliente crea una nueva ficha o selecciona uno de los personajes que ya tiene creados. Todo esto mediante un "protocolo" Cliente ---> SC --- SL ---> BDD ---> SL ---> SC ---> Cliente.


Esta parte sí que la hago diferente. Tal y como lo he planteado, a mí si me interesa tener un hilo para cada jugador porque el SL si va a ofrecer directamente el servicio de Login. Y me interesa tener hilos porque más adelante puede pasar lo que por lo menos a mí me pasa en este tipo de juegos. Que me tiro un minuto viendo que estilo y color de pelo definiría mejor la personalidad de mi alter-ego, y no puedo bloquear a otros jugadores mientras hago esto.

Por otro lado, en la idea que comentas, lo que no haría sería poner un servidor aparte sólo para consultar la BBDD ya que lo único que puedes conseguir con ello es introducir más retardo en el proceso de login, si por lo menos el SC tuviera una carga de procesamiento mayor.., pero no es el caso. Tal y como lo entiendo también necesitarías tener hilos ejecutando en el SC para que se pueda atender a varios jugadores que esté nlogeando, así que ¿por qué no consultar la BBDD directamente en el SC y eliminar el servidor SL?, eso por lo menos en la solución que decías, y en la que yo he implementado también he pensado muchas veces si no tendría que hacer lo mismo.., porque ni el SC ni el SL tienen una carga suficiente que justifique la necesidad de existencia de ambos como servidores independientes..

Ahora viene el login:

¿Cómo balanceo la carga?. Yo he supuesto esto:
...


Planteas una buena idea, pero es algo rebuscada e introduciría mucha intercomunicación, yo había pensado en algo más simple y liviano para la red.

Lo que tenía pensado para ese balanceo es tener en el SC una lista que guarde parejas de datos SPJ-NumeroDeJugadoresQueTiene. Ya con eso el SC sabría donde meter a los jugadores sin introducir consultas entre servidores.

Y aquí llega la parte donde ya me pierdo y donde no entiendo bien como lo haces:

El cliente envía al SPJ #4: "He pulsado la tecla <---"

¿Cómo demonios se enterán el resto de clientes?. Ete aqui el problema.
...


El tema del movimiento es más sencillo de lo que parece. Lo que el jugador envía al SPJ (y éste reenvía a los otros jugadores), es un paquete con la siguiente información:
[Identificador del jugador]+[Movimiento que está realizando]+[Coordenada en la que se encuentra]

Y luego, lo que hace cada cliente es decir "han pasado X milisegundos desde que recibí que este personaje se movía a la derecha desde la coordenada , así que calculo que tiene que estar ahora en ". Los paquetes se envían y reciben con bastante frecuencia para asegurar que no se produzca mucho desfase entre clientes.

¿Cómo? La idea es solo enviar esa información a los jugadores "que estan cerca" ¿para que se tiene que enterar un jugador que está a 30.000 km de distancia que me he movido, que he tirado el ataque X o que he matado a la rata X?. Pues eso

Tenia pensado hacerlo asi:
...


La idea que planteas es también algo compleja, yo había pensado en dividir el mapa en cuadrantes y calcular en que cuadrante está el personaje en base a sus coordenadas. Por ejemplo, cuadrantes de 500pixels, pues el jugador que esté en 0,0 estará en el cuadrante 0, y el jugador que esté en 505,0 estará en el cuadrante 1. De esta forma, a la hora de enviar la información de los personajes que están alrededor, sólo envias las de los números que rodeen el cuadrante en que te encuentras.

Una pregunta interesante que haces es, ¿y cómo saber si tengo un jugador al lado en otro servidor?. Bueno, esta parte aun no la he implementado pero tenía pensado introducir un servidor adicional que lo único que guarde sea la información de la coordenada y cuadrante que ocupa un jugador. Así, cuando un SPJ reciba la información, se lo comunica a este servidor, que se lo hace saber al resto de servidores si fuera necesario (porque puedan estar en el mismo campo de visi´no) y éste reenviaría los datos al jugador que tocara.


No sé si me habré dejado algo o no te habré resuelto las dudas que tenías, lo que haya quedado en el aire ya sabes ;).

Un saludo!.


Este tema ha sido archivado. Esto significa que no puedes responder en este tema.
publicidad
publicidad