Le générateur de nombres aléatoires d'Unity 2017 est-il déterministe sur toutes les plateformes, étant donné la même valeur initiale?

17

Le générateur de nombres aléatoires des moteurs d'unité est-il déterministe sur toutes les plateformes, étant donné la même valeur initiale ou dois-je implémenter le mien?

Je sais qu'il y a eu récemment des modifications au générateur de nombres aléatoires.

Les réponses sont appréciées, je n'ai pas les appareils sous la main pour effectuer des tests et je n'ai pas encore trouvé de déclaration directe à ce sujet.

eternalNoob
la source
11
Bonne question. Mais lorsque votre jeu dépend d'une génération procédurale déterministe, vous voudrez peut-être quand même programmer votre propre PRNG au cas où Unity déciderait de changer son algorithme. La documentation ne documente pas l'algorithme, vous ne devez donc assumer aucune garantie.
Philipp
1
Je comprends votre point de vue, mais il y a suffisamment de travail pour continuer, je préfère apprendre dans quel PRNG de l'unité d'État se trouve en ce moment et fournir une version à l'épreuve du futur plus loin. L'utiliser sans le savoir peut conduire à des bugs vraiment frustrants. Merci pour vos conseils.
eternalNoob
2
J'appuie les conseils de @ Philipp. Si vous avez besoin d'un RNG déterministe, vous devriez investir dans l'écriture du vôtre (et le tester). Vous serez dans un monde de souffrance si vous avez besoin d'utiliser une nouvelle version d'Unity et que le RNG change à nouveau. Il vous sera presque impossible de recréer le même RNG si cela se produit et de conserver la compatibilité avec les sauvegardes / mondes précédents.
Stephane Hockenhull
5
Je pense que les conseils mériteraient d’être rédigés comme une réponse: «Que ce soit ou non déterministe maintenant, ne comptez pas sur le fait qu’il soit toujours le même» (si l’un d’entre vous est si enclin - je ne veux pas voler votre tonnerre). Il est préférable de répondre à certaines questions ostensiblement oui ou non par "option C: autre";)
DMGregory

Réponses:

8

Bien que je n'aie pas eu le temps de faire des tests approfondis, les premières recherches suggèrent que le générateur de nombres aléatoires utilisé est déterministe sur différentes plates-formes. L'implémentation exacte utilisée est: Unity PRNG . Voir aussi: Graine aléatoire Unity sur un matériel différent .
Avec la Randomclasse Unity , l'état exact du PRNG peut être enregistré, voir: Unity Random Sate .

Thomas Mathieson
la source
7

Thomas a répondu à la question comme demandé. La question la plus importante est la suivante:

Le générateur de nombres aléatoires Unity 2017 est-il garanti de fournir les mêmes nombres sur toutes les plates-formes actuelles et futures étant donné la même graine, et est-il également garanti de fournir les mêmes nombres que les futures versions de Unity?

Il y a une probabilité assez élevée que ce soit le cas, mais ce n'est pas la même chose qu'une garantie. La réponse est donc malheureusement « non, ce n'est pas le cas ». Une garantie devrait être explicitement mentionnée dans la documentation de Random , mais pour l' instant il n'y a rien de tel.

Personnellement, même s'il existait une telle garantie, je recommanderais de ne pas lui faire confiance - même avec une garantie, il y a toujours une chance que l'implémentation soit modifiée par accident (un bogue), ou tout simplement obsolète, puis supprimée. À un moment donné, vous souhaiterez peut-être également réutiliser le générateur en dehors du cadre Unity. Au lieu de compter sur Unity, copiez simplement un générateur de nombres aléatoires que quelqu'un d'autre a écrit (assurez-vous que vous êtes autorisé à utiliser le code) et écrivez un test pour vérifier qu'il répond à vos exigences en matière d'aléatoire.

Peter - Unban Robert Harvey
la source
4

Avec Unity 2017.2.0f3, UnityEngine.Random semble donner les mêmes résultats sur plusieurs plates-formes. Testé sur Windows 10, macOS 10.12 Sierra et Android 7.

Pour tester, j'ai réduit une classe SeedFactory que j'ai créée:

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

}

Et un MonoBehaviour pour exécuter le test:

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

}

Et les résultats ont tous été les mêmes:

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
la source