FANDOM


Flujo de cubos de desove

Una secuencia de cubos de desove causada por el error.

Los cubos de desove generados por el Engendrador de monstruos perderán su lugar de generación si ese lugar está ubicado directamente al este o al oeste del Engendrador.

Detalles

Los cubos de desove perdidos que vuelan directamente hacia el este o el oeste continuarán hasta que finalice el juego o el nivel, incluso navegando a través de las paredes del nivel y eventualmente envolviéndose al otro lado del mapa. Con el tiempo suficiente, esto dará como resultado una cadena casi infinita de cubos de desove que atraviesa el nivel (o múltiples flujos de este tipo en caso de que haya varios engendradores de monstruos y / o puntos de desove dispuestos de esta manera).

Ninguno de los juegos comerciales originales de Doom exhibe este error en sus niveles.

Causa

Esto fue causado por los desarrolladores de id Software que encontraron que la trigonometría era demasiado complicada y debía evitarse siempre que fuese posible.

El puntero de código A_SpawnFly() cuenta regresivamente la variable de tiempo de reacción del actor (mobj) "cubo de desove" cada vez que se lo llama, y genera el monstruo si llega a cero después de ser reducido.

void A_SpawnFly (mobj_t* mo)
{
    <insert declarations of variables>
	
    if (--mo->reactiontime)
	return;	// still flying

    <insert code to spawn stuff and destroy the spawn cube>
}

Por lo tanto, para obtener el efecto del cubo de desove que vuela a su punto de generación, es importante que el valor del tiempo de reacción inicial corresponda a cuántas veces se llamará A_SpawnFly hasta llegar al punto de destino.

La idea es muy simple: toma la distancia a recorrer, se la divide por la velocidad de vuelo del cubo y por la cantidad de tic s que se necesitan para llamar a A_SpawnFly. (Por cierto, dada la forma en que se realiza el cálculo, si los estados del cubo de generación no son homogéneos en longitud, esto también se romperá, porque A_BrainSpit supone que la longitud del estado de generación del cubo es la longitud de todos sus estados de vuelo).

Este cálculo se realiza en A_BrainSpit:

void A_BrainSpit (mobj_t*	mo)
{
    <insert declarations of variables and some irrelevant code>

    // spawn brain missile
    newmobj = P_SpawnMissile (mo, targ, MT_SPAWNSHOT);
    newmobj->target = targ;
    newmobj->reactiontime =
	((targ->y - mo->y)/newmobj->momy) / newmobj->state->tics;

    S_StartSound(NULL, sfx_bospit);
}

Aquí, P_SpawnMissile se encargará de la parte difícil de separar la velocidad del cubo de desove en un componente este-oeste (momx) y un componente norte-sur (momy). Entonces, podemos tomar uno de estos componentes y la distancia correspondiente, y será mucho más simple que tener que molestarnos con Pitágoras en ambos ejes.

Por supuesto, si el objetivo está directamente al este u oeste, entonces la distancia es 0.

La velocidad también debería ser cero, lo que llevaría a una problema de división por cero, si no fuera por las tablas de trigonometría inexactas que evitan que el impulso de un actor sea puramente ortogonal a la cuadrícula.

Límite de tiempo

Debido a que el tiempo de reacción es un entero de 32 bits con signo, después de 4.294.967.296 operaciones de decremento, el valor del tiempo de reacción abarcaría todo el espacio de 32 bits y finalmente llegaría a 0, lo que provocaría un monstruo para engendrar.

Dado que la operación de decremento se llama una vez cada 3 tics, esto tomaría aproximadamente 11,67 años, lo que hace que sea prácticamente imposible de presenciar en la práctica. Sin embargo, a través de la edición directa de los valores de memoria, se ha demostrado que el cubo de desove eventualmente engendraría un monstruo, descontando cualquier otro error que pudiera causar que el juego se bloquee antes de que hayan transcurrido 11,67 años.

El contenido de la comunidad está disponible bajo CC-BY-SA a menos que se indique lo contrario.