Atravesar paredes, explicado: por qué un objeto rápido se cuela a través de un muro
Un objeto de ejemplo contra una pared de 0,50 m: el juego solo mira dónde está 60 veces por segundo, y a 54 m/s cada paso salta más de lo que mide el muro.
Todos los números de esta página son valores de ejemplo y la propia página los calcula a partir de unos pocos datos con nombre: los pasos por segundo, dónde está la pared y cuánto mide, y dos velocidades. No son cifras de ningún juego concreto. Muchos jugadores llaman clipping a esto; en el diccionario, clipping es otra cosa, el procedimiento que decide qué objetos ve la cámara, así que aquí se habla de atravesar la pared o de salirse del mapa. Según el juego y el sitio, el efecto es inofensivo, útil para un speedrunner o un problema real, y si un speedrun puede usarlo depende de la categoría: en Any% sí, en Glitchless no.
El juego calcula el mundo a saltos: 60 pasos por segundo, uno cada 16,7 ms.
Un juego no mueve los objetos de forma continua. Su parte de física calcula el mundo en pasos de simulación de duración fija, y entre uno y otro nada cambia. En este ejemplo hay 60 pasos por segundo, así que cada paso dura 1 s / 60 = 16,7 ms. Es el ejemplo clásico de paso fijo que pone Glenn Fiedler, y Box2D también recomienda trabajar con un paso fijo.
Entre dos pasos el juego no sabe nada: hay posición en el paso 11 y en el 12.
En cada paso el juego guarda una posición y nada más. A 9 m/s, el objeto está en 1,65 m en el paso 11, a los 183,3 ms, y en 1,80 m en el paso 12, a los 200 ms. Lo que ocurre entre esas dos posiciones no existe para el juego: no lo calcula ni lo comprueba. Los círculos de la escena son esas posiciones guardadas, una por paso.
En cada paso avanza velocidad × tiempo: a 9 m/s, 0,15 m por paso.
La distancia que recorre el objeto en cada paso es su velocidad por la duración del paso. A 9 m/s y con pasos de 16,7 ms, eso da 9 × 0,01667 s = 0,15 m. El objeto no se desliza esos 15 cm: aparece de golpe 0,15 m más adelante. Cuanto más rápido va, más separadas quedan sus posiciones, y de esa separación depende todo lo que sigue.
La colisión solo se mira en esas posiciones: ¿el objeto solapa ahora con la pared?
La prueba de colisión se hace solo en esas posiciones y es una sola pregunta: ¿el objeto solapa ahora con la pared? Si la respuesta es sí, hay contacto y el juego lo frena o lo empuja hacia fuera. Si es no, no pasa nada. En este ejemplo la pared va de 10,00 a 10,50 m, así que tiene 0,50 m de grosor, y el objeto se trata como un punto.
A 9 m/s, el paso 67 cae en 10,05 m, dentro de la pared: choque.
A 9 m/s el objeto se acerca a la pared de 0,15 en 0,15 m. En el paso 66 está en 9,90 m, todavía fuera. En el paso 67 está en 10,05 m, ya dentro de la pared, que empieza en 10,00 m. La prueba ve el solape, el juego registra el choque y la pared aguanta. Este es el caso normal, el que el juego espera.
Con pasos más cortos que la pared, 0,50 m, siempre cae una posición dentro: hasta 30 m/s.
La regla sale de comparar dos longitudes. Si el avance por paso es menor que el grosor de la pared, las posiciones quedan tan juntas que al menos una cae dentro, y el choque se detecta siempre. Con 60 pasos por segundo y 0,50 m de pared, eso vale hasta 30 m/s. Si el avance es mayor que el grosor, una posición puede quedar antes de la pared y la siguiente, detrás.
A 54 m/s, 0,90 m por paso: 9,90 m antes de la pared, 10,80 m detrás. Ninguna dentro.
Mismo objeto, misma pared, pero a 54 m/s, unos 194 km/h. Ahora cada paso avanza 54 × 0,01667 s = 0,90 m, más que el grosor de la pared. En el paso 11 está en 9,90 m, antes de la pared; en el paso 12, en 10,80 m, ya detrás. Ninguna posición cae dentro, la prueba nunca ve un solape y el objeto ha atravesado la pared sin que el juego lo note.
Los speedrunners acumulan velocidad a propósito: a más velocidad, pasos más largos.
Los speedrunners buscan velocidad a propósito. En Super Mario 64, el «backwards long jump» o BLJ encadena saltos largos hacia atrás en una cuesta o una escalera, y servía para llegar arriba de la escalera infinita con 50 estrellas. A más velocidad, más largo es cada paso: 0,15 m a 9 m/s, 0,45 m a 27 m/s y 0,90 m a 54 m/s. Esta página no afirma que ese u otro truco concreto funcione exactamente así.
Solución: probar el tramo entero (choque a 1,85 ms) o dar 120 pasos por segundo.
Hay dos soluciones. La primera comprueba el tramo entero de 9,90 a 10,80 m, no solo sus extremos: cruza la pared en 10,00 m, a 0,10 m / 54 m/s = 1,85 ms de empezar el paso, y el objeto se para ahí. Unity y Box2D lo llaman detección continua de colisiones. La segunda da pasos más cortos: con 120 por segundo avanza 0,45 m y el paso 23 cae en 10,35 m, dentro, a cambio del doble de cálculos.
Límites del modelo: el objeto es un punto que se mueve en línea recta a velocidad constante; no hay arco de salto, gravedad ni anchura. Un cuerpo con anchura solo puede saltarse la pared si su avance supera el grosor más esa anchura, y que la atraviese o no depende también de dónde caigan las posiciones, aquí en 9,90 y 10,80 m. La pared es sólida y lo bastante alta para que la altura del salto no cuente. Los motores reales además empujan hacia fuera lo que se solapa, limitan velocidades, combinan varios métodos (Box2D usa por defecto la detección continua contra cuerpos estáticos, no entre cuerpos que se mueven) y usan otras frecuencias. No es una errata en el código sino un efecto de cómo calcula el juego; si se llama glitch o bug lo explica el diccionario. El paso del speedrun muestra que la velocidad se acumula a propósito, no que un truco concreto sea exactamente este efecto.
Términos del diccionario
Fuentes
- Collision detection, Wikipedia (prueba discreta tras cada paso; si el paso es demasiado grande, la colisión puede pasar desapercibida y un objeto atraviesa otro; detección continua)
- Fix Your Timestep, Glenn Fiedler, Gaffer On Games (la simulación avanza en pasos fijos, por ejemplo de 1/60 de segundo)
- Continuous collision detection, manual de Unity (detección continua basada en barrido, red de seguridad para objetos que se atravesarían, más cálculo que la discreta)
- Simulation, documentación de Box2D (detección continua por defecto contra cuerpos estáticos, tiempo de impacto, paso fijo)
- Physics Sub-Stepping, documentación de Unreal Engine (divide el paso en subpasos; más estable a cambio de más CPU)
- Super Mario 64, Wikipedia (el «backwards long jump» o BLJ: saltos largos hacia atrás en una cuesta o una escalera)
- BLJ, sm64.com (truco para llegar arriba de la escalera infinita con 50 estrellas)
- Speedrun, Wikipedia (categorías Any% y glitchless; glitches para ganar velocidad)
- Glitch, Wikipedia (fallo sutil y a menudo temporal; en videojuegos incluye problemas de detección de colisiones)