Hola chicos,
tengo un problema muy extraño con mi proyecto. Debido a su funcionamiento en determinados momentos un enemigo puede recibir múltiples impactos y por cada uno muestro un registro flotante de este en pantalla. De esta manera hay momentos donde pueden juntarse muchos textos en pantalla. El caso es que todo parece ir bien, pero al llevar unos 20 minutos de ejecución me da crashes aleatorios y no siempre.
Sospecho que el problema pueda originarse con la gestión de strings y me he hecho un programilla para hacer un uso intensivo de strings y pese a que no he conseguido que el programa reviente, si que aparecen resultados inesperados.
Este es el código:import "mod_key"
import "mod_video"
import "mod_text"
import "mod_map"
import "mod_string"
import "mod_rand"
import "mod_say"
PROCESS creaTexto(int miX, int miY, string cadena)
PRIVATE
int txtid;
int temporizador;
string miCadena;
END
BEGIN
txtid = -1;
x = miX;
y = miY;
miCadena = cadena;
temporizador = 360;
txtid = write_string(0, x, y, 0, &miCadena);
while(temporizador > 0)
temporizador--;
move_text(txtid, x, y);
FRAME;
END
OnExit:
if (txtid >= 0) delete_text(txtid); END
//say(cadena);
END
PROCESS main()
PRIVATE
int indice, contador, contador2, txtid;
string miCadena, micadena2;
END
BEGIN
set_fps(200,0);
set_mode(800,600,32, mode_window);
x = 30;
y = 550;
txtid = write_string(0, 30,550, 0, &micadena2);
while(!(key(_ESC)))
contador2++;
for (indice = 0; indice < 100; indice++)
contador++;
miCadena = "Hola caracola: " + contador;
miCadena2 = "Total: " + contador;
creaTexto(rand(10,200), rand(10,500), miCadena);
END
if (contador2%800 == 0)
if (txtid >= 0)
delete_text(txtid);
txtid = write_string(0, 30,550, 0, &micadena2);
END
END
if (key(_q))
if (txtid >= 0) delete_text(txtid); txtid = -1; END
END
if (txtid < 0)
txtid = write_string(0, 30,550, 0, &micadena2);
else
move_text(txtid, x, y);
END
FRAME;
END
END
El programa trata de pintar "hola caracola" en procesos independientes y aqui es donde esta el fallo, hay una segunda cadena "micadena2" dentro del main que debería tener el valor "Total: N" donde N es el numero de strings pintadas. Lo que me sucede es que al pasar unos pocos segundos miCadena2, ¡vale lo mismo que miCadena! ¿¡WTF!?
Ni dandole a la Q para que repinte el string se arregla el problema, por lo que parece que el problema esté en la cadena y no en el write.
¿Alguna alma caritativa puede probar el código con su versión de Bennu y comentar el resultado?
Y una última cosa es que tras unos segundos, si no repinto la string miCadena2 esta se borra por "arte de magia". Para hacer la prueba comentad la linea 67 "move_text(txtid, x, y);" ¿Esto es normal y deseable?
Si, se borra automaticamente cuando le dá la gana...
gracias, lo vere
aca esta el problema
if (txtid >= 0) delete_text(txtid); END
debe ser
if (txtid >= 0) delete_text(txtid); txtid = -1; END
el tema es que borras txtid pero nunca reseteas el id, entonces el texto desaparece, y el sistema intenta mover el texto a x,y, al no haber nada, no hace nada, el txtid que se intenta usar no existe... pero llega un momento en que el sistema reusa ese id para otro write_string y de ahi hace el move de un nuevo texto creado por creaTexto, al lugar de donde estaba "Total ..."
Hola SplinterGU,
si, he visto el fallo, bien visto. De todas maneras sigue teniendo un comportamiento extraño, el valor de miCadena2 no es el que le correspondería. Actualizo el código de arriba.
no se que valor incorrecto te da, yo llegue a ver Total: 33000, y lo corte porque me canse...
da mas informacion
en un nuevo post, no edites, porque no se que es nuevo y que es viejo, no tengo tanta memoria...
micadena2 tiene el valor correcto, usar write_text + move no es lo adecuado para probar esto...
usa say, pero solo de micadena2... vas a ver que siempre tiene el mismo valor...
Quote from: SplinterGU on May 29, 2018, 02:52:13 AM
no se que valor incorrecto te da, yo llegue a ver Total: 33000, y lo corte porque me canse...
da mas informacion
en un nuevo post, no edites, porque no se que es nuevo y que es viejo, no tengo tanta memoria...
Hola SplinterGU,
tienes razón de que quizás no expliqué bien la casuistica. El caso es que el contenido de miCadena2 cambia (en mi caso al sobrepasar los 33000) pero no a Total: N sino a Hola Caracola: N. Y esto no me deja nada tranquilo hasta no saber exactamente porque.
Adjunto dos imagenes para que se vea el resultado que a mi me devuelve. AM.png es el resultado esperado, pero en AM 001.png se ve como ha cambiado el téxto de miCadena2 de manera "inexplicable".
Modifico el código para dejarlo más simplificado donde se observa el mismo problema que comentaba:
import "mod_key"
import "mod_video"
import "mod_text"
import "mod_map"
import "mod_string"
import "mod_rand"
import "mod_say"
PROCESS creaTexto(int miX, int miY, string cadena)
PRIVATE
int txtid;
int temporizador;
string miCadena;
END
BEGIN
txtid = -1;
x = miX;
y = miY;
miCadena = cadena;
temporizador = 360;
txtid = write_string(0, x, y, 0, &miCadena);
while(temporizador > 0)
temporizador--;
move_text(txtid, x, y);
FRAME;
END
OnExit:
if (txtid >= 0) delete_text(txtid); END
//say(cadena);
END
PROCESS main()
PRIVATE
int indice, contador, contador2, txtid;
string miCadena, micadena2;
END
BEGIN
set_fps(200,0);
set_mode(800,600,32, mode_window);
x = 30;
y = 550;
txtid = write_string(0, 30,550, 0, &micadena2);
while(!(key(_ESC)))
contador2++;
for (indice = 0; indice < 100; indice++)
contador++;
miCadena = "Hola caracola: " + contador;
miCadena2 = "Total: " + contador;
creaTexto(rand(10,200), rand(10,500), miCadena);
END
move_text(txtid, x, y);
say (miCadena2);
FRAME;
END
END
En mi caso al pasar de las 33000 lineas (aprox) el valor mostrado de miCadena2 por el write cambia inexplicablemente y quiero descartar que esto pueda provocar un crash. Obviamente esto es una prueba que trata de alcanzar el límite de strings lo más rápidamente posible para ver su comportamiento, y me da la impresión de que algo malo está sucediendo.
Con Say se muestra el valor correcto de miCadena2 en todo momento, por lo que parece que el problema puede estar en la función write al alcanzar dicho limite de strings. Si se comenta la linea move_text(txtid, x, y); al alcanzar las 33000 el texto simplemente desaparece y no vuelve a aparecer.
Como reflexión, no solo en mi proyecto sino cualquier proyecto con un alto número de strings (ej: juegos de rol conversacionales) puede alcanzar este límite y tener como mínimo un funcionamiento no deseado.
Mi comentario anterior tiene unas capturas del error.
independientemente del resto tantos strings en un juego de rol no serian problema, porque en ningun momento se enseñan tantos textos en pantalla. y si el juego llega a esa cifra, tampoco tienes que guardar todo el texto en el mismo array, puedes tener varios arrays con texto, de hecho es lo mas recomendable, uno para cada mundo o fase por ejemplo
el problema es que estas moviendo un texto que muestra micadena a la posicion de micadena2...
si say da correcto, no hay problema con las strings... simplemente estas poniendo en posicion de micadena2 un texto de micadena...
"0" (cero) tampoco es un valor correcto para id de texto... quizas tengas algo ahi, ya que tu codigo considera 0 como valido...
"0" (cero) se retorna cuando hay demasiados textos en pantalla, cuando se llega a 512.
un delete_text(0) elimina todos los textos...
un solo delete_text(0) eliminaria los textos, y sin saberlo podrias estar moviendo un nuevo texto de micadena al lugar de micadena2, ya que el id de micadena2 (que fue borrado por delete_text) ahora apunta a un write de micadena.
corregi el codigo, limpia adecuadamente los ids cada vez que borras un texto y no consideres 0 como valido, 0 es error
Quote from: FreeYourMind on May 29, 2018, 10:00:35 AM
independientemente del resto tantos strings en un juego de rol no serian problema, porque en ningun momento se enseñan tantos textos en pantalla.
Eso es lo que yo me pensaba, pero no parece comportarse así, a ver como me explico para que se entienda bien:
Yo pensaba que con tal de no llegar al límite de strings en pantalla para que no se produzciera un colapso y se borraran (como mínimo) no pasaría nada, pero no es lo que me está sucediendo en mi proyecto.
Por lo que me ha parecido observar el problema es que al imprimir strings estos llegan a un número límite. En mi proyecto los enemigos van recibiendo impactos y voy mostrando sus valores por pantalla en un registro. Después de unos 20 minutos de juego, lo mismo solo hay 10 strings en ese momento en pantalla pero al entrar la 11ª string en pantalla, ciertas strings se borran o cambian de valor y poco después todo hace un crash.
Entonces, lo que trataba de hacer con ese programa de ejemplo que he subido es acelerar "el crash" y aun que no he conseguido que crashee el programa es super obvio que algo le pasa al write de miCadena2 justo después de que se provoque el colapso y borrado de strings.
Respecto a lo que comentas de reusar el mismo array, en este caso cada proceso tiene su propia string, donde le pasan por referencia un valor pero para asegurar el tiro lo guardo en una string propia del proceso e independiente al resto de procesos, en su seccion private... Imagina que en vez de enviar a ese proceso "hola caracola" le envio frases con sentido y una posición X e Y.
Quote from: SplinterGU on May 29, 2018, 01:22:06 PM
el problema es que estas moviendo un texto que muestra micadena a la posicion de micadena2...
Los límites de pintado del proceso "creaTexto()" son entre 10 y 500 en el eje Y, y main pinta en 550. Así que eso no debería suceder nunca, xDD (sino vaya porquería de prueba que os estaría enviando)
Quote from: SplinterGU on May 29, 2018, 01:22:06 PM"0" (cero) tampoco es un valor correcto para id de texto... quizas tengas algo ahi, ya que tu codigo considera 0 como valido...
"0" (cero) se retorna cuando hay demasiados textos en pantalla, cuando se llega a 512.
Returns
INT : TextID (http://wiki.bennugd.org/index.php?title=TextID)
-1 | - Error. |
>=0 | - The TextID (http://wiki.bennugd.org/index.php?title=TextID) of the text. |
Eso es lo que pone en la wiki. De hecho tenía todo mi código con un >0 y lo cambié a >=0 para ajustarme a la wiki. E incluso te abrí una sugerencia para no aceptar el código 0 como valido ¿recuerdas? Dijiste que te lo pensarías ;)
SplinterGU, has dicho una cosa que me hace que pensar si te pudiera dar alguna pista: dices que el límite está en 512, pero el problema aparece siempre a los 33.000 (aprox) y no a los 512. Diría que siempre es el mismo número. ¿Splinter, te dice algo el número 33.000 o ¡32.768!? Tiene una pinta muy sospechosa...
Conclusión, estoy de acuerdo con splinterGU de que no es la string, pero algo le pasa al write y puede ser seria la cosa.
mira que yo soy testarudo a veces... pero me ganas... :D
esto esta mal
OnExit:
if (txtid >= 0) delete_text(txtid); END
//say(cadena);
END
debe ser
OnExit:
if (txtid > 0) delete_text(txtid); END
//say(cadena);
END
y ademas necesitas esto, reemplazar esto
txtid = write_string(0, x, y, 0, &miCadena);
por esto
txtid = write_string(0, x, y, 0, &miCadena);
if ( !txtid )
say("no mas textos en pantalla!");
return;
end
para que entiendas que pasa
import "mod_key"
import "mod_video"
import "mod_text"
import "mod_map"
import "mod_string"
import "mod_rand"
import "mod_say"
import "mod_proc"
PROCESS creaTexto(int miX, int miY, string cadena)
PRIVATE
int txtid;
int temporizador;
string miCadena;
END
BEGIN
txtid = -1;
x = miX;
y = miY;
miCadena = cadena;
temporizador = 360;
txtid = write_string(0, x, y, 0, &miCadena);
if ( !txtid )
say("no mas textos en pantalla!");
// descomentame exit();
return;
end
say(txtid);
while(temporizador > 0)
temporizador--;
move_text(txtid, x, y);
FRAME;
END
OnExit:
if (txtid > 0) delete_text(txtid); END
//say(cadena);
END
PROCESS main()
PRIVATE
int indice, contador, contador2, txtid;
string miCadena, micadena2;
END
BEGIN
set_fps(0,0);
set_mode(800,600,32, mode_window);
x = 30;
y = 550;
txtid = write_string(0, 30,550, 0, &micadena2);
while(!(key(_ESC)))
contador2++;
for (indice = 0; indice < 100; indice++)
contador++;
miCadena = "Hola caracola: " + contador;
miCadena2 = "Total: " + contador;
creaTexto(rand(10,200), rand(10,500), miCadena);
END
move_text(txtid, x, y);
say (miCadena2);
FRAME;
END
let_me_alone();
END
asi el codigo es como funciona, hasta 500 mil en segundos
hay una linea que puse que dice // descomentame, descomentala y veras el ultimo id asignado... solo 512 textos, en realidad 511... luego retorna 0, pero si tu pones
if (txtid >= 0) delete_text(txtid); END
cuando el write_string falla, txtid vale 0, y cuando el temporizador termina, se ejecuta el onexit y borra delete_text(0) *** TODOS LOS TEXTOS EN PANTALLA ***!!!! pero tu main sigue pensando que miCadena2 sigue vivo con el id obtenido cuando creaste su propio write_string... entonces, tu logica vuelve a crear todos los textos de nuevo... y cuando crea un write_string con miCadena con id igual al del main, entonces lo mueve al lugar de miCadena2...
te voy a poner otro codigo mas, para que veas lo que te digo... bug autoexplicado...
import "mod_key"
import "mod_video"
import "mod_text"
import "mod_map"
import "mod_string"
import "mod_rand"
import "mod_say"
import "mod_proc"
global
int main_txtid;
int no_mas_textos_flag = 0;
int voy_a_borrar_todos = 0;
int bug_flag = 0;
end
PROCESS creaTexto(int miX, int miY, string cadena)
PRIVATE
int txtid;
int temporizador;
string miCadena;
END
BEGIN
txtid = -1;
x = miX;
y = miY;
miCadena = cadena;
temporizador = 360;
txtid = write_string(0, x, y, 0, &miCadena);
if ( !txtid )
if ( !no_mas_textos_flag )
say("no mas textos en pantalla! (texto aparece solo primera vez, luego sucedera el error)");
no_mas_textos_flag = 1;
end
end
if ( txtid == main_txtid && !bug_flag)
say( "aca genere un miCadena con id de miCadena2... bye bye... (muestro solo 1 vez)");
bug_flag = 1;
end
while(temporizador > 0)
temporizador--;
move_text(txtid, x, y);
FRAME;
END
OnExit:
if (!txtid && !voy_a_borrar_todos) say( "voy a borrar todos los textos, incluyendo main_txtid (solo muestro primera vez)"); voy_a_borrar_todos = 1; end
if (txtid >= 0) delete_text(txtid); END
//say(cadena);
END
PROCESS main()
PRIVATE
int indice, contador, contador2, txtid;
string miCadena, micadena2;
END
BEGIN
set_fps(0,0);
set_mode(800,600,32, mode_window);
x = 30;
y = 550;
main_txtid = write_string(0, 30,550, 0, &micadena2);
while(!(key(_ESC)))
contador2++;
for (indice = 0; indice < 100; indice++)
contador++;
miCadena = "Hola caracola: " + contador;
miCadena2 = "Total: " + contador;
creaTexto(rand(10,200), rand(10,500), miCadena);
END
move_text(main_txtid, x, y);
// say (miCadena2);
FRAME;
END
let_me_alone();
END
NOTA: 32000 no tiene nada que ver con 32768, simplemente es casualidad que se reuse el mismo id cerca de ese numero... de hecho a mi me falla a los 36500 exactos, creados...
ya esta explicado el problema, debes controlar los ids de textos que creas, si haces un delete_text(0) se borra todo, write* retorna 0 ante error... (la wiki esta mal), luego de borrar todo los ids se reusan, si tu logica no limpia el id, en algun momento va a asignar ese id a otro texto, y tu logica hara cosas pensando que es otro texto que ya no existe...
Quote from: Arcontus on May 29, 2018, 11:27:11 PM
Eso es lo que pone en la wiki. De hecho tenía todo mi código con un >0 y lo cambié a >=0 para ajustarme a la wiki. E incluso te abrí una sugerencia para no aceptar el código 0 como valido ¿recuerdas? Dijiste que te lo pensarías ;)
y en esa ocasion evidentemente te respondi sin pensar mucho, o te dije que lo veria, ya que nunca puede retornar un id = 0 en un texto valido, ya que delete_text(0) borra todos los textos...
Quote from: SplinterGU on May 30, 2018, 01:22:33 AM
NOTA: 32000 no tiene nada que ver con 32768, simplemente es casualidad que se reuse el mismo id cerca de ese numero... de hecho a mi me falla a los 36500 exactos, creados...
ya esta explicado el problema, debes controlar los ids de textos que creas, si haces un delete_text(0) se borra todo, write* retorna 0 ante error... (la wiki esta mal), luego de borrar todo los ids se reusan, si tu logica no limpia el id, en algun momento va a asignar ese id a otro texto, y tu logica hara cosas pensando que es otro texto que ya no existe...
Bien visto SplinterGU!
¿Y en este caso podría explicar que provocara un crash? Por ejemplo tratando de borrar un ID que ya ha sido borrado por el delete_text(0).
Con el nuevo código todo va estupendamente:
import "mod_key"
import "mod_video"
import "mod_text"
import "mod_map"
import "mod_string"
import "mod_rand"
import "mod_say"
PROCESS creaTexto(int miX, int miY, string cadena)
PRIVATE
int txtid;
int temporizador;
string miCadena;
END
BEGIN
txtid = -1;
x = miX;
y = miY;
miCadena = cadena;
temporizador = 360;
txtid = write_string(0, x, y, 0, &miCadena);
while(temporizador > 0)
temporizador--;
move_text(txtid, x, y);
FRAME;
END
OnExit:
if (txtid > 0) delete_text(txtid); END
//say(cadena);
END
PROCESS main()
PRIVATE
int indice, contador, contador2, txtid;
string miCadena, micadena2;
END
BEGIN
set_fps(200,0);
set_mode(800,600,32, mode_window);
x = 30;
y = 550;
txtid = write_string(0, 30,550, 0, &micadena2);
while(!(key(_ESC)))
contador2++;
for (indice = 0; indice < 100; indice++)
contador++;
miCadena = "Hola caracola: " + contador;
miCadena2 = "Total: " + contador;
creaTexto(rand(10,200), rand(10,500), miCadena);
END
move_text(txtid, x, y);
say (miCadena2);
FRAME;
END
END
Ahora he de cambiar nuevamente de >= a > en la detección de ID's en tooodo mi proyecto.
¿Alguien con derechos de edición podría corregir la wiki para tener correcta la documentación?
Quote from: Arcontus on May 30, 2018, 08:09:15 AM
Quote from: SplinterGU on May 30, 2018, 01:22:33 AM
NOTA: 32000 no tiene nada que ver con 32768, simplemente es casualidad que se reuse el mismo id cerca de ese numero... de hecho a mi me falla a los 36500 exactos, creados...
ya esta explicado el problema, debes controlar los ids de textos que creas, si haces un delete_text(0) se borra todo, write* retorna 0 ante error... (la wiki esta mal), luego de borrar todo los ids se reusan, si tu logica no limpia el id, en algun momento va a asignar ese id a otro texto, y tu logica hara cosas pensando que es otro texto que ya no existe...
Bien visto SplinterGU! y te voy a dar un karmazo!
¿Y en este caso podría explicar que provocara un crash? Por ejemplo tratando de borrar un ID que ya ha sido borrado por el delete_text(0).
Con el nuevo código todo va estupendamente:
import "mod_key"
import "mod_video"
import "mod_text"
import "mod_map"
import "mod_string"
import "mod_rand"
import "mod_say"
PROCESS creaTexto(int miX, int miY, string cadena)
PRIVATE
int txtid;
int temporizador;
string miCadena;
END
BEGIN
txtid = -1;
x = miX;
y = miY;
miCadena = cadena;
temporizador = 360;
txtid = write_string(0, x, y, 0, &miCadena);
while(temporizador > 0)
temporizador--;
move_text(txtid, x, y);
FRAME;
END
OnExit:
if (txtid > 0) delete_text(txtid); END
//say(cadena);
END
PROCESS main()
PRIVATE
int indice, contador, contador2, txtid;
string miCadena, micadena2;
END
BEGIN
set_fps(200,0);
set_mode(800,600,32, mode_window);
x = 30;
y = 550;
txtid = write_string(0, 30,550, 0, &micadena2);
while(!(key(_ESC)))
contador2++;
for (indice = 0; indice < 100; indice++)
contador++;
miCadena = "Hola caracola: " + contador;
miCadena2 = "Total: " + contador;
creaTexto(rand(10,200), rand(10,500), miCadena);
END
move_text(txtid, x, y);
say (miCadena2);
FRAME;
END
END
Ahora he de cambiar nuevamente de >= a > en la detección de ID's en tooodo mi proyecto.
¿Alguien con derechos de edición podría corregir la wiki para tener correcta la documentación?
no creo que el crash tenga que ver con esto... seguramente si manejas punteros se deba a algo de eso... al momento no hay algun bug conocido que pueda probar un crash... salvo el bug del render que a veces con rotaciones y sizes dibuja cualquier cosa...
Quote from: SplinterGU on May 30, 2018, 09:52:15 PM
no creo que el crash tenga que ver con esto... seguramente si manejas punteros se deba a algo de eso... al momento no hay algun bug conocido que pueda probar un crash... salvo el bug del render que a veces con rotaciones y sizes dibuja cualquier cosa...
¿No? ¿Incluso mandando un delete_text(id) a una id que ha sido borrada por un delete_text(0) previamente? ¿Esto está protegido de alguna manera para que el programa no haga nada?
que version de bennugd estas usando ? creo recordar que lo de error al pagar id's no existentes hace tiempo que se ignora para que no salte error
Quote from: FreeYourMind on May 31, 2018, 08:50:15 AM
que version de bennugd estas usando ? creo recordar que lo de error al pagar id's no existentes hace tiempo que se ignora para que no salte error
He actualizado recientemente, pero es posible que estuviera utilizando una versión afectada. He hecho tantos cambios ya que ni se como se ha arreglado el tema.Por cierto, sonara muy noob pero: ¿hay algún comando para ver la versión de bennu que estoy usando?
Quote from: Arcontus on May 31, 2018, 08:41:43 AM
Quote from: SplinterGU on May 30, 2018, 09:52:15 PM
no creo que el crash tenga que ver con esto... seguramente si manejas punteros se deba a algo de eso... al momento no hay algun bug conocido que pueda probar un crash... salvo el bug del render que a veces con rotaciones y sizes dibuja cualquier cosa...
¿No? ¿Incluso mandando un delete_text(id) a una id que ha sido borrada por un delete_text(0) previamente? ¿Esto está protegido de alguna manera para que el programa no haga nada?
por supuesto... esta protegido...
Quote from: FreeYourMind on May 31, 2018, 08:50:15 AM
que version de bennugd estas usando ? creo recordar que lo de error al pagar id's no existentes hace tiempo que se ignora para que no salte error
no recuerdo eso...
era con los sonidos creo recordar, matar un sonido inexistente
Quote from: Arcontus on May 31, 2018, 10:22:35 AM
Quote from: FreeYourMind on May 31, 2018, 08:50:15 AM
que version de bennugd estas usando ? creo recordar que lo de error al pagar id's no existentes hace tiempo que se ignora para que no salte error
He actualizado recientemente, pero es posible que estuviera utilizando una versión afectada. He hecho tantos cambios ya que ni se como se ha arreglado el tema.Por cierto, sonara muy noob pero: ¿hay algún comando para ver la versión de bennu que estoy usando?
si, corre el bgdi sin argumentos y te muestra el numero de version y demas
Quote from: FreeYourMind on June 01, 2018, 11:50:23 AM
era con los sonidos creo recordar, matar un sonido inexistente
puede ser, pero el esta preguntando de textos
Quote from: SplinterGU on June 01, 2018, 12:01:11 PM
Quote from: FreeYourMind on June 01, 2018, 11:50:23 AM
era con los sonidos creo recordar, matar un sonido inexistente
puede ser, pero el esta preguntando de textos
Llevo varios días y muchas horas de juego sin un crash y he vuelto a activar los registros de los textos. He cambiado cosas en mi código, como lo del >= por > en los id's de textos, y descartando esto nada que a primera vista puediera reflejar un crash. En fin, a ver si ya esta todo ok y no vuelve a dar por saco :D
excelente!