Czy generator liczb losowych Unity 2017 jest deterministyczny na różnych platformach z tym samym początkowym początkiem?

17

Czy generatory liczb losowych w silnikach jedności są deterministyczne na różnych platformach z tym samym początkowym początkiem, czy powinienem wdrożyć własny?

Wiem, że ostatnio wprowadzono pewne modyfikacje generatora liczb losowych.

Odpowiedzi są mile widziane, nie mam pod ręką żadnych urządzeń, aby wykonać jakiekolwiek testy i nie znalazłem jeszcze bezpośredniego oświadczenia w tej sprawie.

eternalNoob
źródło
11
Dobre pytanie. Ale kiedy twoja gra zależy od deterministycznego generowania procedur, możesz i tak zaprogramować swój PRNG, na wypadek gdyby Unity kiedykolwiek zdecydowało się zmienić algorytm. Dokumentacja nie dokumentuje algorytmu, więc nie należy zakładać żadnych gwarancji.
Philipp
1
Rozumiem twój punkt widzenia, ale jest wystarczająco dużo pracy, aby się z tym pogodzić, wolałbym dowiedzieć się, jaki jest obecnie PRNG jedności stanu i zapewnić przyszłą wersję próbną w dalszej kolejności. Używanie go bez wiedzy może prowadzić do naprawdę frustrujących błędów. Dzięki za radę.
wiecznyNoob
2
Popieram radę @ Philipp. Jeśli potrzebujesz deterministycznego RNG, powinieneś zainwestować w napisanie własnego (i przetestowanie go). Będziesz w świecie bólu, jeśli kiedykolwiek będziesz potrzebować nowej wersji Unity, a RNG zmieni się ponownie. Jeśli to się stanie, odtworzenie tego samego RNG będzie prawie niemożliwe i zachowanie zgodności z poprzednimi zapisami / światami.
Stephane Hockenhull
5
Myślę, że rada byłaby warta napisania jako odpowiedzi: „Czy teraz jest deterministyczna, czy nie, nie licz na to, że zawsze będzie taka sama” (Jeśli którykolwiek z was byłby tak skłonny - nie chcę ukraść piorun). Na niektóre pozornie tak lub nie można lepiej odpowiedzieć „opcją C: inne”;)
DMGregory

Odpowiedzi:

8

Chociaż nie miałem czasu na żadne obszerne testy, wstępne badania sugerują, że zastosowany generator liczb losowych jest deterministyczny na różnych platformach. Zastosowana dokładna implementacja to: Unity PRNG . Zobacz także: Unity Random Seed On Different Hardware .
Dzięki Randomklasie Unity można zapisać dokładny stan PRNG, patrz: Losowe dane Unity .

Thomas Mathieson
źródło
7

Thomas odpowiedział na zadane pytanie. Ważniejsze pytanie jest następujące:

Czy generator liczb losowych Unity 2017 ma zagwarantować dostarczanie takich samych liczb na wszystkich obecnych i przyszłych platformach przy tym samym nasieniu, i czy gwarantuje to również dostarczenie tych samych liczb, co przyszłe wydania Unity?

Prawdopodobieństwo takiego zachowania jest raczej wysokie, ale nie jest to równoznaczne z gwarancją. Zatem odpowiedź brzmi „ nie, nie jest ”. Gwarancja musi być wyraźnie określona w dokumentacji Random , ale obecnie nie ma czegoś takiego.

Osobiście, nawet gdyby istniała taka gwarancja, odradzam jej zaufanie - nawet z gwarancją nadal istnieje szansa, że ​​implementacja zostanie zmieniona przypadkowo (błąd) lub po prostu przestarzała, a następnie usunięta. W pewnym momencie możesz również chcieć ponownie użyć generatora poza środowiskiem Unity. Zamiast polegać na Unity, po prostu skopiuj generator liczb losowych , który napisał ktoś inny (upewnij się, że możesz używać kodu) i napisz test, aby sprawdzić, czy spełnia on twoje wymagania dotyczące losowości.

Piotr
źródło
4

Używając Unity 2017.2.0f3, UnityEngine.Random wydaje się dawać takie same wyniki na wielu platformach. Testowany na Windows 10, macOS 10.12 Sierra i Android 7.

Aby przetestować, ograniczyłem utworzoną przeze mnie klasę SeedFactory:

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;
    }

}

I MonoBehaviour do uruchomienia testu:

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);
    }

}

Wszystkie wyniki były takie same:

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
źródło