M
Myrdinn
Invité
L'alétaoire étant souvent à l'origine de délires sur Bnet, j'ai décidé de mettre à jour ce post qui en avait bien besoin. Désolé pour le texte original que j'ai modifié mais ca n'a plus trop d'importance vu la date ou il a été écrit. (J'ai laissé la suite comme introduction avant d'apporter les nouveauté)
Je tiens à remercier Jarulf et Hammerman qui m'avaient aiguillé à l'époque. C'est grace à eux si j'ai pu finaliser ce post aujourd'hui
Intro issu du post initial
Avant de commencer un petit rappel historique sur diabloI
Sous DiabloI l'aléatoire utilisait le temps. En bloquant
le temps sur leur PC des petits malins se sont apercu que
le jeu generait toujours le meme resultat pour une action donnée.
Ceci inclus les Drops, mais aussi les chances de toucher ...
La meme erreur n'a pas ete repetée sous DII.
Voila une petite synthese que j'ai faite pour vous
(Attention Joe ne te mets pas contre un mur )
L'aléatoire est une fonction dans laquelle le jeu acceptent
un paramètre. En cela elle reprend la syntaxe des celebres Round.
LA fonction genère un nombre entre 0 et 1 et le multiplie par le paramètre.
C'est important car le résultat final est un entier.
Les résultats sont précalculés. Il n'y a plus d'intervention du temps excepté à l'origine de la première seed.,
A partirde ce seed il est possible de connaitre et de calculer la suite de valeur.
Cette suite bien que previsible est inutilisable. Le jeu utilise l'aléatoire pour une
multitude de paramètre (deplacement des lapins, scorpions, monstres, IA des monstres
, toucher , degat ...) donc meme en connaissant la suite
( a condition que l'on connaise le seed) on ne peut s'en servir pour les drops.
Les valeurs sont reparties de facon uniforme sur l'ensemble des seeds,
mais pour un seed donné la repartition n'est pas homogène.
Résultat il y a des seeds pour lesquels il y a plus de nombres proches de zero que pour d'autres seed
Ceci favorise le drop d'unique, mais il existe d'autre particularité
Bref, l'aléatoire ne tient compte d'aucune de vos actions, et les recettes de grand mère pour le Meme Runs, j'y crois de moins en moins
EDIT ajout de quelques questions réponses en page 2
2) De la pluralité des Seeds
Le jeu n'utilise pas 1 seed mais autant de seed que nécessaire pour que les évenement soit le plus possible indépendant.
LE jeu utilise une architecture pyramidale utilisant des Unit. J'en parle en détail dans mons post sur les Dlls je ne reviendrais pas en détail su celui ci.
La première unité est l'unité JEU que j'appelerais PtGame Pt pour pointeur car on désigne l'unité par son adresse mémoire.
Cette unité contient toutes les informations sur la partie (difficulté, mot de passe, mode ...) ainsi que la liste de toutes les unités enfants : les PtUnit à savoir tout les objets / Monstres / Joueurs / missiles ...
Chaque unité possède sa propre seed dérivée des la seed du PtGame. La seed du PtGame est la première Seed créé (voir formule dans le chapitre suivant)
Il existe d'autres seeds liés à la création des Maps.
Les maps ont leur propres seed créé à partir du PtGame ou (récupérée de la sauvegarde des maps pour le solo. C'est pourquoi en solo les maps sont toujours les mêmes après avoir sauvegardée)
Ensuite les Maps sont divisées en plus petites portions appelés Room (PtRoom)
J'ai quelques détail à vérifier avant de donner la relation exacte entre toutes les seeds
3) Les Seeds Mode D'emploi
Première Seed / PtGame
Comment est calculé la première Seed (Celle du PtGame pour ceux qui suivent)
2 solutions :
[*]Vous avez utilisé la commande -Seed, dans ce cas la seed prend cette valeur
[*] Vous n'intervenez pas c'est ce que nous allonf voir maintenant
La seed est une valeur 64 bits que l'on sépare en 2 parties de 32 Bits.
Seed_Low et Seed_High
SeedHi = 0x000000029a (666 en décimal, amusant ces programmeurs)
Seed_Low=abs( (QueryPerformanceCounter + SecondsSince1900 + 0x7c558180 + GetTickCount) * 0x2f490a95 - 0x2e330917)
LEs 2 sont des valeurs Signées (Positive ou négative)
GetTickCount appelle le Kernel de Windows et retourne le nombre de millisecond depuis le démarrage de l'ordinateur
QueryPerformanceCounter appelle le Kernel de Windows et retourne une valeur qui est mise à jour constamment par le QueryPerformanceFrequency qui est systemDépendant.
deuxième seed MapSeed
Comment est calculé la deuxième seed (LA map seed pour ceux qui suivent) Si nécessaire (En solo la map seed est celle de la map sauvegardée)
Si vous utilisez la commande -Seed xxx alors c'est la même
Autrement c'est la même formule sauf que le QueryPerformanceCounter est remplacé par la Seed suivante du PtGame
Mise à jour de la seed / tirage Aléatoire
Les mises à jour de la seed sont calculées comme ceci :
1. seed_low * 0x6ac690c5
C'est une multiplication 64 Bits, la seed_low est etendue à 64 bits le temps des calculs
2. Ajoute seed_hi à la valeur 64 bit calculé
Bref Seed(64 bits) = SeedLo * 0x6ac690c5 + SeedHi
3. Cette valeur est la nouvelle seed divisé en Seed_low(32 bits de poids faible) et Seed_high(32 Bits fort)
Vous pouvez également utilisé cette génération de seed pour un tirage aléatoire entre 0 et X:
4. Diviser la seed_low par X
5. la retenue est la valeur aléatoire comprise entre 0 et (X-1) le tout en hexa
Bref en math RND[x] = SeedLo mod X
création de nouvelle Seed
En cas de création d'une nouvelle seed (A la création d'une nouvelle unit par exemple) le jeu met à jour la seed du PtGame et donne le résultat suivant pour la nouvelle Seed
Seed_Low = SeedLo (la nouvelle du PtGame)
Seed_High = 0x000000029a
Comme le Seed High est différent, toutes les valeurs futures sont différentes de celles du PtGame et des prochains objets créé par le PtGame
Je tiens à remercier Jarulf et Hammerman qui m'avaient aiguillé à l'époque. C'est grace à eux si j'ai pu finaliser ce post aujourd'hui
Intro issu du post initial
Avant de commencer un petit rappel historique sur diabloI
Sous DiabloI l'aléatoire utilisait le temps. En bloquant
le temps sur leur PC des petits malins se sont apercu que
le jeu generait toujours le meme resultat pour une action donnée.
Ceci inclus les Drops, mais aussi les chances de toucher ...
La meme erreur n'a pas ete repetée sous DII.
Voila une petite synthese que j'ai faite pour vous
(Attention Joe ne te mets pas contre un mur )
L'aléatoire est une fonction dans laquelle le jeu acceptent
un paramètre. En cela elle reprend la syntaxe des celebres Round.
LA fonction genère un nombre entre 0 et 1 et le multiplie par le paramètre.
C'est important car le résultat final est un entier.
Les résultats sont précalculés. Il n'y a plus d'intervention du temps excepté à l'origine de la première seed.,
A partirde ce seed il est possible de connaitre et de calculer la suite de valeur.
Cette suite bien que previsible est inutilisable. Le jeu utilise l'aléatoire pour une
multitude de paramètre (deplacement des lapins, scorpions, monstres, IA des monstres
, toucher , degat ...) donc meme en connaissant la suite
( a condition que l'on connaise le seed) on ne peut s'en servir pour les drops.
Les valeurs sont reparties de facon uniforme sur l'ensemble des seeds,
mais pour un seed donné la repartition n'est pas homogène.
Résultat il y a des seeds pour lesquels il y a plus de nombres proches de zero que pour d'autres seed
Ceci favorise le drop d'unique, mais il existe d'autre particularité
Bref, l'aléatoire ne tient compte d'aucune de vos actions, et les recettes de grand mère pour le Meme Runs, j'y crois de moins en moins
EDIT ajout de quelques questions réponses en page 2
2) De la pluralité des Seeds
Le jeu n'utilise pas 1 seed mais autant de seed que nécessaire pour que les évenement soit le plus possible indépendant.
LE jeu utilise une architecture pyramidale utilisant des Unit. J'en parle en détail dans mons post sur les Dlls je ne reviendrais pas en détail su celui ci.
La première unité est l'unité JEU que j'appelerais PtGame Pt pour pointeur car on désigne l'unité par son adresse mémoire.
Cette unité contient toutes les informations sur la partie (difficulté, mot de passe, mode ...) ainsi que la liste de toutes les unités enfants : les PtUnit à savoir tout les objets / Monstres / Joueurs / missiles ...
Chaque unité possède sa propre seed dérivée des la seed du PtGame. La seed du PtGame est la première Seed créé (voir formule dans le chapitre suivant)
Il existe d'autres seeds liés à la création des Maps.
Les maps ont leur propres seed créé à partir du PtGame ou (récupérée de la sauvegarde des maps pour le solo. C'est pourquoi en solo les maps sont toujours les mêmes après avoir sauvegardée)
Ensuite les Maps sont divisées en plus petites portions appelés Room (PtRoom)
J'ai quelques détail à vérifier avant de donner la relation exacte entre toutes les seeds
3) Les Seeds Mode D'emploi
Première Seed / PtGame
Comment est calculé la première Seed (Celle du PtGame pour ceux qui suivent)
2 solutions :
[*]Vous avez utilisé la commande -Seed, dans ce cas la seed prend cette valeur
[*] Vous n'intervenez pas c'est ce que nous allonf voir maintenant
La seed est une valeur 64 bits que l'on sépare en 2 parties de 32 Bits.
Seed_Low et Seed_High
SeedHi = 0x000000029a (666 en décimal, amusant ces programmeurs)
Seed_Low=abs( (QueryPerformanceCounter + SecondsSince1900 + 0x7c558180 + GetTickCount) * 0x2f490a95 - 0x2e330917)
LEs 2 sont des valeurs Signées (Positive ou négative)
GetTickCount appelle le Kernel de Windows et retourne le nombre de millisecond depuis le démarrage de l'ordinateur
QueryPerformanceCounter appelle le Kernel de Windows et retourne une valeur qui est mise à jour constamment par le QueryPerformanceFrequency qui est systemDépendant.
deuxième seed MapSeed
Comment est calculé la deuxième seed (LA map seed pour ceux qui suivent) Si nécessaire (En solo la map seed est celle de la map sauvegardée)
Si vous utilisez la commande -Seed xxx alors c'est la même
Autrement c'est la même formule sauf que le QueryPerformanceCounter est remplacé par la Seed suivante du PtGame
Mise à jour de la seed / tirage Aléatoire
Les mises à jour de la seed sont calculées comme ceci :
1. seed_low * 0x6ac690c5
C'est une multiplication 64 Bits, la seed_low est etendue à 64 bits le temps des calculs
2. Ajoute seed_hi à la valeur 64 bit calculé
Bref Seed(64 bits) = SeedLo * 0x6ac690c5 + SeedHi
3. Cette valeur est la nouvelle seed divisé en Seed_low(32 bits de poids faible) et Seed_high(32 Bits fort)
Vous pouvez également utilisé cette génération de seed pour un tirage aléatoire entre 0 et X:
4. Diviser la seed_low par X
5. la retenue est la valeur aléatoire comprise entre 0 et (X-1) le tout en hexa
Bref en math RND[x] = SeedLo mod X
création de nouvelle Seed
En cas de création d'une nouvelle seed (A la création d'une nouvelle unit par exemple) le jeu met à jour la seed du PtGame et donne le résultat suivant pour la nouvelle Seed
Seed_Low = SeedLo (la nouvelle du PtGame)
Seed_High = 0x000000029a
Comme le Seed High est différent, toutes les valeurs futures sont différentes de celles du PtGame et des prochains objets créé par le PtGame