Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by joshjewell29 · Feb 05, 2013 at 12:50 AM · randommonodevelopdot net

System.Random() with seed not matching .Net or mono

I am scripting my Unity code in c# and using System.Random() with a seed to generate predictable letters for my game. I am doing the same thing on a server written in c# using .NET and was expecting the numbers to match up.

However I am getting two separate predictable results for example Unity outputs:

94 92 67

with code:

 System.Random rnd = new System.Random( 8675309 );
 Debug.Log( rnd.Next( 100 ) );
 Debug.Log( rnd.Next( 100 ) );
 Debug.Log( rnd.Next( 100 ) );

The c# server outputs:

75 99 57

with code:

 System.Random rnd = new System.Random( 8675309 );
 Console.WriteLine( rnd.Next( 100 ) );
 Console.WriteLine( rnd.Next( 100 ) );
 Console.WriteLine( rnd.Next( 100 ) );

I downloaded MonoDevelop 3.0.6 to run the server and obtained the same random numbers. I also tried running the server in dot net 3.5 and 4.0 with the same results.

I was under the impression that Unity was running under Mono and I should obtain my expected results.

Does anybody know whats going on? I am using Linq in my Unity code so I know the dot.net api has to be version 3.5 or higher.

Comment
Add comment · Show 3
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Fattie · Feb 05, 2013 at 06:38 AM -1
Share

Why are you not just using the ordinary Random toutines that Unity supplies you with?

(1) do not use System.Random, just use this http://docs.unity3d.com/Documentation/ScriptReference/Random.Range.html

(2) it has been true for some TWENTY YEARS that you should generally speaking never use, look at, know about, or be involved with "seed" when getting a random number for a game. it has absolutely no relationship to anything, unless you know everything there is to know about random numbers and systems program$$anonymous$$g.

avatar image Eric5h5 · Feb 05, 2013 at 07:14 AM 0
Share

@Fattie:

1) Because UnityEngine.Random only has one universal seed. System.Random can have different seeds for different sequences.

2) Totally false, you need to set seeds for repeatable sequences of pseudo-random numbers. This is really really commonplace; why do you think all random number generators have this ability?

avatar image $$anonymous$$ · Aug 14, 2017 at 06:08 PM 0
Share

i like how you used "867-5309"

3 Replies

· Add your reply
  • Sort: 
avatar image
3
Best Answer

Answer by Eric5h5 · Feb 05, 2013 at 01:06 AM

MonoDevelop is a code editor, not something that Unity runs under; presumably you're talking about Mono. System.Random results with a seed are not even 100% guaranteed between versions in .NET, never mind between .NET and Mono. To get 100% predictable results across platforms you will need to write your own pseudo-random generator.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Bunny83 · Feb 05, 2013 at 01:18 AM 0
Share

Yes, most documentations of program$$anonymous$$g languages usually warn you to not use their random generator for encryption or things like that since the implementation could by changed at anytime.

avatar image joshjewell29 · Feb 05, 2013 at 02:06 AM 0
Share

Thanks for the advice. I was expecting this to be a bit more standard then it appears it is. Will have to come up with my own generator or find one that does what I need.

avatar image
1

Answer by Bunny83 · Feb 05, 2013 at 01:29 AM

The simplest pseudo random generator i know is the one that comes with borland pascal. It works pretty well. I've never tried the implementation in C#, but it in general it should work.

Here's a quick adaption of the generator:

 // C#
 public class MyRandom
 {
     private int m_Value = 0;
     public MyRandom(){}
     public MyRandom(int aSeed)
     {
         m_Value = aSeed;
     }
     private int Next()
     {
         m_Value = m_Value * 0x08088405 + 1;
         return m_Value;
     }
     public int Range(int aMin, int aMax)
     {
         return aMin + Next() % (aMax-aMin);
     }
 }

Haven't tried this implementation but it should work (unless C# complains about integer overflow ;)).

ps: it's of course just a 32 bit random generator, but if i don't used the wrong multiplier it shouldn't repeat within the 32 bit limit. So it reapeats exactly after 0xFFFFFFFF times.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image joshjewell29 · Feb 05, 2013 at 02:07 AM 0
Share

Thanks for the code, may end up using this or something like it to solve my problem.

avatar image
0

Answer by VoidYTMain · Nov 27, 2016 at 02:57 PM

It just System.Random

 namespace Game.Maze
 {
     public class SystemRandomAdaptor : IRandom
     {
         private readonly int[] SeedArray = new int[56];
         private int inext;
         private int inextp;
 
         public SystemRandomAdaptor(int seed)
         {
             int num1 = 161803398 - System.Math.Abs(seed);
             SeedArray[55] = num1;
             int num2 = 1;
             for (int index1 = 1; index1 < 55; ++index1)
             {
                 int index2 = 21 * index1 % 55;
                 SeedArray[index2] = num2;
                 num2 = num1 - num2;
                 if (num2 < 0)
                     num2 += int.MaxValue;
                 num1 = SeedArray[index2];
             }
             for (int index1 = 1; index1 < 5; ++index1)
             {
                 for (int index2 = 1; index2 < 56; ++index2)
                 {
                     SeedArray[index2] -= SeedArray[1 + (index2 + 30) % 55];
                     if (SeedArray[index2] < 0)
                         SeedArray[index2] += int.MaxValue;
                 }
             }
             inext = 0;
             inextp = 21;
         }
 
         protected virtual double Sample()
         {
             return InternalSample() * 4.6566128752458E-10;
         }
 
         private int InternalSample()
         {
             int num1 = inext;
             int num2 = inextp;
             int index1;
             if ((index1 = num1 + 1) >= 56)
                 index1 = 1;
             int index2;
             if ((index2 = num2 + 1) >= 56)
                 index2 = 1;
             int num3 = SeedArray[index1] - SeedArray[index2];
             if (num3 < 0)
                 num3 += int.MaxValue;
             SeedArray[index1] = num3;
             inext = index1;
             inextp = index2;
             return num3;
         }
 
         private double GetSampleForLargeRange()
         {
             int num = InternalSample();
             if (InternalSample() % 2 == 0)
                 num = -num;
             return (num + 2147483646.0) / 4294967293.0;
         }
 
         public SystemRandomAdaptor(long seed) : this((int)seed) { }
         public int Random(int min, int max)
         {
             max += 1;
             long num = max - (long)min;
             if (num <= int.MaxValue)
                 return (int)(Sample() * num) + min;
             return (int)((long)(GetSampleForLargeRange() * num) + min);
         }
     }
 }
 

,It just using System.Random code

 namespace Game.Maze
 {
     public class SystemRandomAdaptor : IRandom
     {
         private readonly int[] SeedArray = new int[56];
         private int inext;
         private int inextp;
 
         public SystemRandomAdaptor(int seed)
         {
             int num1 = 161803398 - System.Math.Abs(seed);
             SeedArray[55] = num1;
             int num2 = 1;
             for (int index1 = 1; index1 < 55; ++index1)
             {
                 int index2 = 21 * index1 % 55;
                 SeedArray[index2] = num2;
                 num2 = num1 - num2;
                 if (num2 < 0)
                     num2 += int.MaxValue;
                 num1 = SeedArray[index2];
             }
             for (int index1 = 1; index1 < 5; ++index1)
             {
                 for (int index2 = 1; index2 < 56; ++index2)
                 {
                     SeedArray[index2] -= SeedArray[1 + (index2 + 30) % 55];
                     if (SeedArray[index2] < 0)
                         SeedArray[index2] += int.MaxValue;
                 }
             }
             inext = 0;
             inextp = 21;
         }
 
         protected virtual double Sample()
         {
             return InternalSample() * 4.6566128752458E-10;
         }
 
         private int InternalSample()
         {
             int num1 = inext;
             int num2 = inextp;
             int index1;
             if ((index1 = num1 + 1) >= 56)
                 index1 = 1;
             int index2;
             if ((index2 = num2 + 1) >= 56)
                 index2 = 1;
             int num3 = SeedArray[index1] - SeedArray[index2];
             if (num3 < 0)
                 num3 += int.MaxValue;
             SeedArray[index1] = num3;
             inext = index1;
             inextp = index2;
             return num3;
         }
 
         private double GetSampleForLargeRange()
         {
             int num = InternalSample();
             if (InternalSample() % 2 == 0)
                 num = -num;
             return (num + 2147483646.0) / 4294967293.0;
         }
 
         public SystemRandomAdaptor(long seed) : this((int)seed) { }
         public int Random(int min, int max)
         {
             max += 1;
             long num = max - (long)min;
             if (num <= int.MaxValue)
                 return (int)(Sample() * num) + min;
             return (int)((long)(GetSampleForLargeRange() * num) + min);
         }
     }
 }
 
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

13 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Enemy AI move random. 1 Answer

Locked icon in Mono develop 0 Answers

i need help with a random number health script 2 Answers

Unique # Generation "Cannot cast from source type to destination type." 3 Answers

Semi Random Monster Spawner 3 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges