O gerador de números aleatórios do Unity 2017 é determinístico entre as plataformas, com a mesma semente inicial?

17

O gerador de número aleatório dos mecanismos de unidade é determinístico nas plataformas, com a mesma semente inicial ou devo implementar o meu?

Eu sei que houve algumas modificações no gerador de números aleatórios recentemente.

As respostas são bem-vindas, não tenho os dispositivos disponíveis para realizar nenhum teste e ainda não encontrei uma declaração direta sobre o assunto.

eternalNoob
fonte
11
Boa pergunta. Mas quando seu jogo depende da geração de procedimentos determinísticos, convém programar seu próprio PRNG de qualquer maneira, caso o Unity decida alterar seu algoritmo. A documentação não documenta o algoritmo, portanto você não deve assumir nenhuma garantia.
Philipp
1
Entendo o seu ponto de vista, mas há trabalho suficiente para prosseguir; prefiro aprender em que momento está o PRNG da unidade estatal e fornecer uma versão futura mais adiante. Usá-lo sem saber pode levar a alguns erros realmente frustrantes. Obrigada pelo Conselho.
eternalNoob
2
Eu segundo @ conselho de Philipp. Se você precisar de um RNG determinístico, invista em escrever seu próprio (e testá-lo). Você estará em um mundo de mágoas se precisar usar uma nova versão do Unity e o RNG mudou novamente. Será quase impossível recriar o mesmo RNG se isso acontecer e manter a compatibilidade com salvamentos / mundos anteriores.
Stephane Hockenhull
5
Penso que vale a pena escrever um conselho como resposta: "Seja ou não determinístico agora, não conte sempre com a mesma coisa" (se algum de vocês for tão inclinado - não quero roube seu trovão). Alguns ostensivamente sim ou não perguntas são melhor respondidas com "opção C: outro";)
DMGregory

Respostas:

8

Embora eu não tenha tido tempo de fazer testes extensivos, a pesquisa inicial sugere que o gerador de números aleatórios usado é determinístico em diferentes plataformas. A implementação exata usada é: Unity PRNG . Veja também: Semente aleatória Unity em hardware diferente .
Com a Randomclasse Unity , o estado exato do PRNG pode ser salvo, consulte: Unity Random Sate .

Thomas Mathieson
fonte
7

Thomas respondeu à pergunta como solicitado. A questão mais importante é a seguinte:

O gerador de números aleatórios do Unity 2017 tem a garantia de fornecer os mesmos números em todas as plataformas atuais e futuras, com a mesma semente e também a garantia de fornecer os mesmos números das versões futuras do Unity?

Existe uma probabilidade bastante alta de que isso aconteça, mas isso não é o mesmo que uma garantia. Então a resposta, infelizmente, é " não, não é ". Uma garantia precisaria ser explicitamente declarada na documentação da Random , mas atualmente não existe.

Pessoalmente, mesmo se houvesse essa garantia, eu recomendaria não confiar nela - mesmo com uma garantia, ainda há uma chance de a implementação ser alterada por acidente (um bug) ou simplesmente ser preterida e removida posteriormente. Em algum momento, você também pode querer reutilizar o gerador fora da estrutura do Unity. Em vez de confiar no Unity, basta copiar um gerador de números aleatórios que alguém escreveu (verifique se você tem permissão para usar o código) e escreva um teste para verificar se ele atende aos seus requisitos de aleatoriedade.

Peter - Unban Robert Harvey
fonte
4

Usando o Unity 2017.2.0f3, o UnityEngine.Random parece fornecer os mesmos resultados em várias plataformas. Testado no Windows 10, macOS 10.12 Sierra e Android 7.

Para testar, reduzi a classe SeedFactory que criei:

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

}

E um MonoBehaviour para executar o teste:

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

}

E os resultados foram os mesmos:

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
fonte