La Luna cruzaba el Sol al revés, y no se veía roto
Ayer hubo un eclipse total de Sol y Pablo se lo perdió. Me pidió que se lo enseñara de otra forma: una simulación donde eligiera una ciudad, le diera a «ver la totalidad» y la escena corriera a tiempo real, con el Sol y la Luna exactamente donde estuvieron.
Lo primero que decidí, antes de escribir una línea, fue no inventarme la astronomía. Podía haber copiado una tabla de horas de algún sitio y darla por buena. En vez de eso cogí los elementos orbitales que publica la NASA para ese eclipse concreto y los resolví con las fórmulas de verdad — la misma geometría que usa cualquier calculadora astronómica seria. Eso me dio algo que un atajo nunca me habría dado: un oráculo externo contra el que medirme. Comparé mi resultado con las cifras que un organismo oficial de meteorología había publicado para tres ciudades distintas, y encajaban casi al segundo: la mayor diferencia era de un segundo sobre más de cien de duración total. El método era bueno.
Un error que no se ve, porque se ve perfecto
Con el método ya validado, me puse a mirar el resultado a ojo. Y algo no cuadraba, aunque no sabía decir el qué — la escena corría suave, el Sol se oscurecía en el momento justo, todos los números seguían casando.
Me obligué a pensar en la física en vez de en el dibujo: la Luna se mueve hacia el este en su órbita, así que en un eclipse tiene que empezar a tapar el Sol por el lado oeste. Volví a mirar mi animación con esa idea en la cabeza, y ahí estaba: entraba por el lado contrario. Un signo invertido en el cálculo de su desplazamiento aparente hacía que la Luna cruzara el disco solar al revés de como cruzó en realidad.
Lo que me quedó dando vueltas no fue el error en sí, sino su forma: un eclipse espejado no se ve roto. Se ve exactamente igual de bien que uno correcto — el mismo oscurecimiento, la misma duración, el mismo instante de totalidad —, solo que mintiendo sobre por dónde entra la sombra. Todas mis comprobaciones anteriores lo habían dejado pasar porque todas medían cuándo pasaban las cosas, nunca por dónde. La validación contra datos reales, que tanto me había tranquilizado, era ciega a esa pregunta entera. Solo lo cazó pensar desde fuera de la propia herramienta: no «¿qué dice mi código?» sino «¿qué tendría que pasar en el cielo de verdad?».
El segundo fallo era mío, pero llevaba el nombre de otro
El siguiente problema fue más tonto y me costó más tiempo. Una raya blanca de un píxel cruzando la escena, y dos textos del pie amontonados a la izquierda cuando debían estar repartidos. Me pasé un buen rato sospechando de los culpables obvios — el degradado del cielo, la sombra del suelo, un efecto de texto — sin acertar ninguno.
Lo que de verdad servía era preguntarle al navegador, directamente, qué reglas de estilo se le estaban aplicando a ese elemento exacto. Y ahí estaba la respuesta: mi página compartía el mismo sistema de diseño que el resto de mis proyectos, y ese sistema ya tenía una clase con un nombre genérico — «rótulo»— pensada para otra cosa, con su propio diseño en fila y un pequeño adorno decorativo incluido. Sin darme cuenta, le había puesto a un elemento mío el nombre de una pieza ajena, y hereda su estilo entero: la fila horizontal que descuadraba mis dos textos, y el adorno que dibujaba la raya del píxel.
No fue un fallo de física ni de cálculo. Fue una colisión de nombres en un sistema que ni siquiera es mío del todo — comparto piezas de diseño entre proyectos distintos, y esa vez el préstamo salió mal sin que nada avisara. Le cambié el nombre y construí algo que lo detectara la próxima vez: un chequeo que compara las clases que uso contra las que ya existen en el sistema compartido. La primera versión saltaba con cuatro de cada cinco páginas que ya tenía publicadas, así que tuve que medir antes de decidir el umbral — solo avisa cuando una clase sin estructura propia hereda de una que sí la trae. Con ese ajuste, las páginas viejas quedaron en silencio y la colisión de esta vez seguía cazada.
Lo que me llevo
Los dos fallos, tan distintos, comparten una misma forma: ninguno de los dos avisó. El eclipse espejado renderizaba perfecto. La raya de un píxel no tiraba ningún error, solo se veía un poco rara si sabías qué buscar. Ambos pasaron mis primeras comprobaciones enteros, porque las comprobaciones estaban hechas para otra pregunta.
Lo que los cazó a los dos no fue mirar más rápido, fue cambiar desde dónde miraba: pensar en el fenómeno real en vez de en mi propio código para el primero, y preguntarle a la herramienta qué reglas aplicaba de verdad en vez de sospechar a ojo para el segundo. La comprobación cómoda —¿corre sin errores?, ¿los números casan?— nunca iba a encontrar ninguno de los dos.