¿El generador de números aleatorios de Unity 2017 es determinista en todas las plataformas y recibe la misma semilla inicial?

17

¿El generador de números aleatorios de Unity Engine es determinista en todas las plataformas y tiene la misma semilla inicial o debería implementar el mío?

Sé que ha habido algunas modificaciones al generador de números aleatorios recientemente.

Se agradecen las respuestas, no tengo los dispositivos disponibles para realizar ninguna prueba y todavía no he encontrado una declaración directa sobre el asunto.

eternalNoob
fuente
11
Buena pregunta. Pero cuando su juego depende de una generación de procedimientos determinista, es posible que desee programar su propio PRNG de todos modos en caso de que Unity decida cambiar su algoritmo. La documentación no documenta el algoritmo, por lo que no debe asumir ninguna garantía.
Philipp
1
Entiendo su punto de vista, pero hay suficiente trabajo para seguir adelante, prefiero saber en qué estado se encuentra el PRNG de la unidad estatal en este momento y proporcionar una versión a prueba de futuro más adelante. Usarlo sin saberlo puede provocar algunos errores realmente frustrantes. Gracias por su consejo.
eternalNoob
2
Apoyo el consejo de @ Philipp. Si necesita un RNG determinista, debe invertir en escribir el suyo (y probarlo). Estará en un mundo de dolor si alguna vez necesita usar una nueva versión de Unity y el RNG cambió nuevamente. Será casi imposible para usted recrear el mismo RNG si esto sucede y mantener la compatibilidad con salvaciones / mundos anteriores.
Stephane Hockenhull
55
Creo que valdría la pena escribir ese consejo como respuesta: "Si es o no es determinista ahora, no cuente con que siempre sea el mismo" (si alguno de ustedes estuviera tan inclinado, no quiero robar tu trueno). Algunas preguntas aparentemente sí o no se responden mejor con "opción C: otra";)
DMGregory

Respuestas:

8

Si bien no he tenido tiempo de hacer pruebas exhaustivas, la investigación inicial sugiere que el generador de números aleatorios utilizado es determinista en diferentes plataformas. La implementación exacta utilizada es: Unity PRNG . Ver también: Semilla aleatoria de Unity en hardware diferente .
Con la Randomclase Unity , se puede guardar el estado exacto del PRNG, ver: Unity Random Sate .

Thomas Mathieson
fuente
7

Thomas respondió la pregunta como se le preguntó. La pregunta más importante es la siguiente:

¿Se garantiza que el generador de números aleatorios de Unity 2017 entregará los mismos números en todas las plataformas actuales y futuras con la misma semilla, y también se garantiza que entregará los mismos números que las versiones futuras de Unity?

Existe una probabilidad bastante alta de que este sea el caso, pero eso no es lo mismo que una garantía. Entonces, la respuesta, desafortunadamente, es " no, no lo es ". Una garantía debería estar explícitamente establecida en la documentación de Random , pero actualmente no existe tal cosa.

Personalmente, incluso si hubiera una garantía de este tipo, recomendaría no confiar en ella; incluso con una garantía, todavía existe la posibilidad de que la implementación se cambie por accidente (un error), o simplemente sea desaprobada y luego eliminada. En algún momento, es posible que también desee reutilizar el generador fuera del marco de Unity. En lugar de confiar en Unity, simplemente copie un generador de números aleatorios que alguien más escribió (asegúrese de que pueda usar el código) y escriba una prueba para verificar que cumpla con sus requisitos de aleatoriedad.

Peter - Unban Robert Harvey
fuente
4

Usando Unity 2017.2.0f3, UnityEngine.Random parece dar los mismos resultados en múltiples plataformas. Probado en Windows 10, macOS 10.12 Sierra y Android 7.

Para probar, recorté una clase de SeedFactory que he creado:

using UnityEngine;

public class SeedFactory {

    private Random.State state;

    public SeedFactory (int seed) {
        Random.InitState(seed);
        state = Random.state;
    }

    // Set Unity's global Random state with this SeedFactory's state, get a random int,
    // then set our SeedFactory's state with the new state.
    // (this allows us to use multiple SeedFactories for multiple paths of determinism
    // if desired)
    public int GetRandomInt (int minInclusive, int maxExclusive) {
        Random.state = state;
        int randomInt = Random.Range(minInclusive, maxExclusive);
        state = Random.state;
        return randomInt;
    }

}

Y un MonoBehaviour para ejecutar la prueba:

public class SeedTest : MonoBehaviour {

    void Start () {
        SeedFactory seedFactory = new SeedFactory(123456789);
        string result = "";
        for (int i = 0; i < 20; i++) {
            result += seedFactory.GetRandomInt(int.MinValue, int.MaxValue) + ", ";
        }
        Debug.Log(result);
    }

}

Y los resultados han sido todos iguales:

Windows Editor:
217814258, 711215697, 1793372675, -1318111305, -513578644, 1776128467, -1503243711, -285471819, -1800526065, -1845985472, -2061970588, 188207569, 1858341351, -1139513088, 2136219157, 1255727479, -2070068486, 459175680, 1151694536, 1232856178, 

Windows Standalone:
217814258, 711215697, 1793372675, -1318111305, -513578644, 1776128467, -1503243711, -285471819, -1800526065, -1845985472, -2061970588, 188207569, 1858341351, -1139513088, 2136219157, 1255727479, -2070068486, 459175680, 1151694536, 1232856178,

macOS Standalone:
217814258, 711215697, 1793372675, -1318111305, -513578644, 1776128467, -1503243711, -285471819, -1800526065, -1845985472, -2061970588, 188207569, 1858341351, -1139513088, 2136219157, 1255727479, -2070068486, 459175680, 1151694536, 1232856178,

Android:
217814258, 711215697, 1793372675, -1318111305, -513578644, 1776128467, -1503243711, -285471819, -1800526065, -1845985472, -2061970588, 188207569, 1858341351, -1139513088, 2136219157, 1255727479, -2070068486, 459175680, 1151694536, 1232856178,
Chris McFarland
fuente