Aumentar el valor de un dato mysql progresivamente en el tiempo

Iniciado por The_Shakah, 23 Enero 2009, 02:48 AM

0 Miembros y 1 Visitante están viendo este tema.

The_Shakah

Bueno que tal gente... estoy intentando hacer un juego de navegador y me he topado con un problema muy grave

La cosa es así, cada usuario o jugador tiene 4 recursos, y una mina que produce ese recurso, por ej, para producir oro tenes un edificio que se llama mina de oro, si tenes la mina de oro en nivel 1, aumenta 40 unidades de oro por hora.

Los recursos que tiene cada jugador estan almacenados en mysql, en una columna llamada (en el caso del oro) "oro".

Este valor tiene que aumentar progresiamente a medida que pasa el tiempo segun su nivel en la mina de oro.

Entonces... no tengo ni put* idea de como hacer eso.

¿Alguna ayuda?

saludos y desde ya muchas gracias

PD: ¿Se puede hacer eso en mysql?

eLank0


mit

OGAME  :laugh:

muchos hosting tienen la herramienta para realizar tareas programadas, con eso esas lo que quieres e infinidad de tareas mas.

saludos

baZZ

no te hace falta eso. Hay una forma de hacerlo más facil. Calculas el tiempo en el cual se conecta el usuario. Calculas las diferencias de tiempo de login, hora en la cual se actualiza un edificio o como lo tengas puesto, y entonces al cargar la pagina haces antes de mostrar los datos un update con los correspondientes multiplicadores y rates que tengas puestos. Hacer esto sin ayuda "externa" complica el desarrollo, a parte de que cada vez que un usuario cargue la pagia vas a tener que hacer cálculos, por cada actualizacion de edifico tendras que crear una entrada en la base de datos para guardar la hora en la k se ha construido...etc. Ésto es para que cuando un usuario deje construyendo un edificio y se desconecte, tenga un calculo de recursos correcto al volver a conectarse despues de que el edificio se construyese. Para ello tendras q mirar que entre el tiempo_ultimo_login y tiempo_actual tengas edificos construidos. Entonces el calculo seria sumando los datos obtenidos con dichas diferencias de tiempos...etc. Es una cosa bastante facil solo hay q darle un poco al coco. Saludos y perdona por si no me has entendido jejje. Si no me has entendido bien te pongo un ejemplo mas facil. deeeeu
- EVGA ATX - Intel X58
- i7 920 @ 3,2 Ghz
- 2x260 gtx 216 SLI
- 3x1 GB OCZ DIMM DDR3 1600 Mhz
- Tacens Sagitta II
- Seagate 7200.12
Falta:
- T.R.U.E ^^
- i7 @ 4,0 Ghz

SaXo

Hola,

Le veo un problema a tu solución. Ya que los datos no son para uso exclusivo del usuario, si no de todos los usuarios que participan en el juego y es prohibitivo realizar una actualización cada vez que un usuario solicite una pagina. Si por ejemplo tenemos 10.000 usuarios que han realizado 20 actualizaciones de datos (construir, aumentar, movimiento, etc..) cada uno... multiplica esos usuarios por las actualizaciones de cada uno y por los accesos que tiene la pagina (pues con unos 10000 usuarios podría llegar perfectamente a los 100.000 accesos diarios) y sin cache, ya que cada acceso realizaría una comprobación de las tareas y una actualización en la base de datos.

Lo más sensato sería realizar una pool de actualizaciones y un sistema de actualización. No tiene por que ser con cron ya que podríamos lanzar un cgi en el servidor que este constantemente comprobando y ordenando las tareas de la pool y actualizando los datos cuando sea necesario (con un uso de cache en memoria se aumentaría el rendimiento). Minimizando al máximo los accesos de escritura a la base de datos por parte de los usuarios (sólo escribirían en el caso de completar una acción y no siempre que cargue una página al realizar una actualización masiva de acciones).

Probablemente existan otras formas de hacer esto, pero a mi no se me ocurre ninguna buena que no sea usar un aplicativo aparte de la aplicación web para ir actualizando los datos de forma masiva sin perjudicar al rendimiento de la aplicación web.

Sobre el uso de Ajax para hacer esto se podría discutir... pero al ser javascript sería necesario que el usuario estuviera conectado para poder realizar las actualizaciones.

Un saludo,

SaXo

baZZ

En realidad, si usas un poco la picardía, solo es necesario hacer una actualizacion, y solo en el caso de que ésta sea necesaria. Si la ultima vez que se actualizaron los datos es menor que la ultima vez que se construyó un edificio (por ejemplo) actualizas. Es un calculo menor, con un coste totalmente asumible. El resto de calculos como de recursos se pueden hacer con javascript una vez obtenidos los multiplicadores. Por parte de servidor los calculos son hechos solo cuando son necesarios, nunca para adornar el cliente...xau
- EVGA ATX - Intel X58
- i7 920 @ 3,2 Ghz
- 2x260 gtx 216 SLI
- 3x1 GB OCZ DIMM DDR3 1600 Mhz
- Tacens Sagitta II
- Seagate 7200.12
Falta:
- T.R.U.E ^^
- i7 @ 4,0 Ghz

SaXo

Hola :D,

Vamos a analizarlo con un ejemplo más pequeño.

Estamos jugando tu y yo una partida de ajedrez. El movimiento de una pieza tarda 1 minuto por cada casilla que tenga que desplazarse. Ninguno de los dos sabemos que movimiento hizo el contrario hasta que no se complete el tiempo de movimiento de la pieza.

Por lo tanto ambos tenemos que actualizar cada cierto tiempo el tablero para ver si se ha completado el movimiento. Suponiendo que como máximo puedo hacer 50 peticiones por minuto de actualización al tablero para ver los movimientos estaríamos haciendo entre los dos 100 peticiones máximo a la base de datos para comprobar si se ha completado el movimiento (comprobación y actualización en caso de que proceda).

Si dispongo de un script que me actualiza los datos independientemente de las solicitudes de actualización de la página, sólo realizare una petición cada x tiempo (probablemente el tiempo mínimo de movimiento de una pieza. 1 minuto por casilla) y una única actualización en la base de datos cuando se termine el movimiento de la pieza (o piezas que cumplan el tiempo en la actualización).

Claro que el uso de AJAX no es un adorno. Yo lo usaría para ver el tiempo que queda para finalizar el movimiento de la pieza, actualizar el tablero y en cualquier caso se podría usar para mandar un flag de actualización.

Como he dicho antes, se pueden hacer de varias formas. La forma que me parece más acertada es la de tener una pieza que me haga las actualizaciones de forma independiente a la web, incluso se puede montar un emulador de threads con curl para mejorar el rendimiento. De esta forma no necesito que ningún usuario este conectado a la web para realizar la actualización de los movimientos.

Todo es discutible y no existen mejores o peores formas de implementar algo. :)

Un saludo,

SaXo

baZZ

Evidentemente

Lo que yo propongo es, siguiendo tu linea de ejemplo y mi linea de no usar una tercera aplicacion:

Mandamos el movimiento de una pieza, en una tabla eventos guardamos el evento movimiento con la posicion x,y que sea, el id de la pieza que queremos mover, la hora a la que comenzo el movimiento y la hora a la que finalizaria el movimiento. Cada vez que cargamos la pagina selecionamos de la base de datos los eventos que se vayan a cumplir y que nos afecten a nosotros. El tiempo en "directo" y todo eso se puede hacer con ajax como dices, al igual que la supuesta casilla en la que se encontrase la pieza. Evidentemente tenemos una consulta en la base de datos con cada carga de pagina y actualizacion si el evento se ha llevado a cabo completamente. Pero en tu caso tenemos lo mismo, una consulta de cuanto tiempo quedaria (o lo que fuese) y una actualizacion después (a menos que la otra aplicacion la haga). Y es que lo que yo digo es que no hace falta saber exactamente cuantos segundos quedan para x evento, lo cual se puede calcular matematicamente siempre que conozcamos el inicio y fin de dicho evento, por lo cual no seria necesario ir actualizando valores desde otra aplicacion. No se si se entiende mi punto de vista.

El mayor coste que tendria dicha implementacion es que a un usuario se le acumulasen muchos eventos, por lo cual el tiempo de carga de pagina si que aumentaria en dicho caso (por ejemplo que haya 10000 moviemientos de piezas acumulados y nos conectemo despues de que los movimientos hayan terminado, lo cual conyevaria actualizar la posicion de las 10000 piezas en el momento en que se conecte dicho usuario, o el usuario que interactua con el).

Para evitar dicho coste está muy bien lo que propone SaXo, utilizar otra aplicacion que vaya "administrando y ejecutando" los eventos. No obstante mi propuesta creo que es válida si no dispones de una utilidad como la comentada.

Saludos!
- EVGA ATX - Intel X58
- i7 920 @ 3,2 Ghz
- 2x260 gtx 216 SLI
- 3x1 GB OCZ DIMM DDR3 1600 Mhz
- Tacens Sagitta II
- Seagate 7200.12
Falta:
- T.R.U.E ^^
- i7 @ 4,0 Ghz

SaXo

Pues le ando dando vueltas a lo que quieres hacer y aún hay algo que no me cuadra.

Cuando hago una solicitud de actualización al cargar la página, no sólo necesito que se actualicen mis movimientos, si no los del resto de los jugadores. Por lo tanto tendría que comprobar todas las tareas pendientes de ejecutarse en la pool he ir acutalizándolas si procede (fíjate, aún sin necesidad de actualizar los movimientos tendría que comprobarlos todos en cada actualización de la página). Aparte de ser un consumo considerable de procesos en el servidor ¿No aparecería un problema de sincronismo de datos con el tiempo? 

Puede que la solución más razonable pase por una combinación de ambas formas.

Un saludo,

SaXo

baZZ

Claro, tendrias que actualizar tambien los eventos de los jugadores que digamos interactuan contigo, pero en resumen eso son todos los eventos que te afectan a ti, o los eventos de un jugador al cual estas "afectando". Tampoco es muy costoso ya que son consultas SQL (suponiendo claro que usemos MySQL, algo que he dado por supuesto). Ejemplo: Un jugador mueve una ficha de la ajedrez. Ahora nostros queremos ver donde tiene las fichas el jugador. Comprobamos los eventos para saber donde estan sus fichas, algunas puede que estén en camino ya que tardan 1 minuto/casilla y otras pueden ya haber terminado (la hora que guardamos de finalizacion en el evento es menor a la hora actual). Si la ficha esta en movimiento no la podemos comer, si el evento de movimiento ha terminado ya la podriamos comer. Esto se sincroniza digamos al "ver" el tablero. Espero que entiendas a lo que me refiero. Es basicamente usar una tabla SQL como contenedor de ventos con los ID del jugador y resto de datos. Para "ahorrar" tiempo se ejecutan los eventos de la tabla cuyo ID sea el nuestro o aquel del jugador con el que interactuemos, así si interactuan con nosotros ejecutan nuestros eventos pendientes y si interactuamos con alguien los suyos, sincronizándo todo. Espero explicarme bien. Saludos!

PD: nos ha quedado un modelo de ajedrez asincrono interesante jaja.
- EVGA ATX - Intel X58
- i7 920 @ 3,2 Ghz
- 2x260 gtx 216 SLI
- 3x1 GB OCZ DIMM DDR3 1600 Mhz
- Tacens Sagitta II
- Seagate 7200.12
Falta:
- T.R.U.E ^^
- i7 @ 4,0 Ghz