Quick Question about perlin noise

I just had a question about perlin noise. I was wondering how, if you had infinite terrain in a game (Yes, like minecraft), you would use Unity’s perlin noise to generate everything? There’s a few problems I can see.

Problems.
(1)Mathf.PerlinNoise isn’t pseduo-random, so to speak. Every point will give you the exact same value at any time for any person, no matter what. Your (0.2,0.2) is the same as everyone else’s.(2) Alright, so you can scale it to not use as big of an area at once, cool. But that makes the terrain differences seem much “smoother”, as less space is being sampled in the image for the same amount of world space, and (3) after moving away from that point far enough, the terrain would become flat forever. (4) But, if we loop back to the other side, we get the problem of repetitive terrain.

I’m just wondering if there’s a way to solve all four of these problems by having something that allows you to generate a perlin noise field of infinite size, all you need to do is give it a seed, then the position, which will be based off of that seed.

Is there any simple file or something from the assets store to grab for this, or is there a way to do this with the built-in system that I don’t know about?

No matter what your perlin noise will repeat at some point unless you make a custom coordinate system with literally no limit to the size of the number - but that would be unnecessary for 99.99999% of applications. In almost all situations that you’re going to move very far from Unity’s origin it’s better to design your entire game to move around the player rather than the other way around due to the fact that Unity uses floats for coordinates and at far distances you start losing a lot of precision.

Here’s one I wrote and it’s all yours if you want it for commercial or personal applications (not giving out my 3d one free though as it’s a far more refined version of this 2d one)… It tiles Perlin noise from long.MinValue to long.MaxValue - though you might have to take a look at the gradient function to ensure it’s not actually repeating at some point. However, you can only sample integers with this with a desired initial zoom. (64 is 1/64, 32 is 1/32 - eg integer 32 is perlin coordinate .5 at 64 zoom)

Instructions for use:

  1. Create a DeterministicRNG object with (long)seed.
  2. Create a GradientManager object with the DeterministicRNG and a Zoom Factor
  3. Create a Perlin2dHash object with the GradientManager
  4. Create PerlinVector object each time you want to sample a coordinate with the same zoom factor as the Gradient manager (very important)
  5. Use Perlin2dHash.Sample(PerlinVector) as many times as you want octaves. The vector will automatically change its coordinates by multiplying them by two for the next octave sample each time it is sampled.
  6. Under PerlinVector.vals will be the results of your sampling… vals[0] is octave 1, vals[1] is octave 2, vals[2] is octave 3 etc… You can then add these together with the desired persistance.
namespace Perlin2d
{
  using System.Collections.Generic;
  using System;
  using System.Text;
  using System.IO;
  using UnityEngine;

  public delegate fVec2 AssignGradDel(ulong x, ulong y);
  public delegate float LerpDel(float a, float b, float amount);
  public delegate float FadeDel(float t);

  public class DeterministicRNG
  {
  private long sd = 0;
  public byte[] Array;

  public DeterministicRNG(long Seed)
  {
  sd = Seed;
  string seed = String.Format("{0}", Seed);
  RNG2_0 tempRNG = new RNG2_0(seed);
  Array = tempRNG.GetArray();
  }

  public DeterministicRNG(ulong Seed)
  {
  sd = BitConverter.ToInt64(BitConverter.GetBytes(Seed), 0);
  string seed = String.Format("{0}", Seed);
  RNG2_0 tempRNG = new RNG2_0(seed);
  Array = tempRNG.GetArray();
  }
  }

  public class GradientManager : PerlinCoord
  {
  public AssignGradDel MyDel;
  public LerpDel LerpDel;
  public FadeDel FadeDel;
  private ulong Modulus;

  private DeterministicRNG MyRNG;

  public GradientManager(ulong X, ulong Y, DeterministicRNG rng, int ZoomFactor)
  {
  MyRNG = rng;
  //Coord[0] = X;
  //Coord[1] = Y;
  MyDel = new AssignGradDel(ReturnGradient);
  LerpDel = new LerpDel(Slerp);
  FadeDel = new FadeDel(Fade);
  Modulus = ulong.MaxValue /(ulong)(ZoomFactor*2);
  }

  #region Gradient Functions

  public fVec2 ReturnGradient(ulong X, ulong Y)
  {
  ulong x1 = (ulong)X & Modulus ;
  ulong y1 = (ulong)Y & Modulus ;
  x1 = x1 * x1  + 1;
  y1 = y1 * y1 * y1 +3 * x1 ;
  int val = ((byte)(((y1 ^ x1) * 961747207 ) % 256));
  fVec2 ret = fVec2.CircleGrad[MyRNG.Array[val]*2];

  //AppConsole.Instance.WriteLine(X + "  " + Y + "  " + ret.ToString());  961747207
  return ret;

  }

  #endregion

  #region LerpFunctions

  public static float StandardLerp(float a, float b, float amount)
  {
  return a * (1 - amount) + b * (amount);
  }

  public static float Slerp(float a, float b, float amount)
  {
  amount = (amount * amount) * (3 - 2 * amount);
  return StandardLerp(a, b, amount);
  }

  public static float Fade(float t)
  {
  return t*t*t*(t*(t*6-15)+10);
  }

  #endregion
  }

  public class PerlinCoord
  {
  protected ulong[] Coord = new ulong[2];
  protected fVec2 FP = new fVec2(0,0);
  protected bool flipneg = false;

  public ulong x
  {
  get
  {
  return Coord[0];
  }
  set
  {
  Coord[0] = value;
  }
  }
  public ulong y
  {
  get
  {
  return Coord[1];
  }
  set
  {
  Coord[1] = value;
  }
  }

  public PerlinCoord()
  {

  }

  public PerlinCoord(long X, long Y)
  {
  Coord[0] =  ConvertLong(X);
  Coord[1] = ConvertLong(Y);
  }

  public PerlinCoord(PerlinCoord pc)
  {
  x = pc.x;
  y = pc.y;
  }

  public ulong ConvertLong(long inc)
  {
  if(inc < 0)
  {
  flipneg = true;
  }
  if (flipneg)
  {
  return BitConverter.ToUInt64(BitConverter.GetBytes(inc), 0) + 1;
  }
  else
  {
  return BitConverter.ToUInt64(BitConverter.GetBytes(inc), 0);
  }
  }

  public override int GetHashCode()
  {
  return (int)(x ^ y);
  }

  public override bool Equals(object obj)
  {
  if (obj is PerlinCoord)
  {
  PerlinCoord pc = (PerlinCoord)obj;
  if (pc.x == this.x && pc.y == this.y)
  {
  return true;
  }
  else
  {
  return false;
  }
  }
  else
  {
  return false;
  }
  }

  public string DebugString()
  {
  return "< " + x + ", " + y + " >  < " + FP.x + ", " + FP.y + " >";
  }
  }

  public class PerlinVector : PerlinCoord
  {
  private float ZoomFactor = 64;
  private int sampnum = 0;
  public List<float> Vals = new List<float>();

  public ulong x
  {
  get
  {
  return Coord[0];
  }
  }
  public ulong y
  {
  get
  {
  return Coord[1];
  }
  }
  public int CurrentSample
  {
  get
  {
  return sampnum;
  }
  }
  public fVec2 Float
  {
  get
  {
  return FP;
  }
  }
  public float ZoomVal
  {
  get
  {
  return ZoomFactor;
  }
  set
  {
  ZoomFactor = value;
  }
  }

  public PerlinVector()
  {

  }

  public PerlinVector(long X, long Y)
  {
  Coord[0] = ConvertLong( X);
  Coord[1] = ConvertLong(Y);
  Initilize();
  //AppConsole.Instance.WriteLine(DebugString());
  }

  public PerlinVector(long X, long Y, int Zoom)
  {
  Coord[0] = ConvertLong(X);
  Coord[1] = ConvertLong(Y);
  ZoomFactor = Zoom;
  Initilize();
  //AppConsole.Instance.WriteLine(DebugString());
  }

  public void AddVal(float val)
  {
  Vals.Add(val);
  StepFreq();
  }

  public void StepFreq()
  {
  FP.x = FP.x * 2;
  FP.y = FP.y * 2;
  Coord[0] = (x << 1) + (ulong)sampnum + (ulong)FP.x;
  Coord[1] = (y << 1)  + (ulong)sampnum + (ulong)FP.y;
  FP.x = FP.x % 1;
  FP.y = FP.y % 1;
  sampnum++;
  }

  public void Initilize()
  {
  if (!flipneg)
  {
  FP.x = (float)(x % (ulong)ZoomFactor) / ZoomFactor;
  FP.y = (float)(y % (ulong)ZoomFactor) / ZoomFactor;
  }
  else
  {
  FP.x = (float)(x % (ulong)ZoomFactor) / ZoomFactor;
  FP.y = (float)(y % (ulong)ZoomFactor) / ZoomFactor;
  }
  Coord[0] = Coord[0] / (ulong)ZoomFactor;
  Coord[1] = Coord[1] / (ulong)ZoomFactor;
  }

  public override int GetHashCode()
  {
  return (int)(Coord[0] ^ Coord[1]);
  }

  public override bool Equals(object obj)
  {
  if (obj is PerlinVector)
  {
  PerlinVector pv = (PerlinVector)obj;
  if (this.x == pv.x && this.y == pv.y)
  {
  return true;
  }
  else
  {
  return false;
  }
  }
  else
  {
  return false;
  }
  }
  }

  public partial class Perlin2dSquare
  {
  private fVec2[,] Grads = new fVec2[2, 2];
  GradientManager gm;

  public Perlin2dSquare(GradientManager Gradient, PerlinCoord Coord)
  {
  gm = Gradient;
  for (int i = 0; i < 2; i++)
  {
  for (int j = 0; j < 2; j++)
  {
  Grads[i, j] = Gradient.ReturnGradient((ulong)i+Coord.x,  (ulong)j +Coord.y);
  }
  }
  }

  public float Sample(fVec2 per)
  {
  float x1 = per.x - 1;
  float y1 = per.y - 1;

  float x11 = PrivateDot(x1, y1, Grads[1, 1]);
  float x01 = PrivateDot(per.x, y1, Grads[0,  1]);
  float x10 = PrivateDot(x1, per.y, Grads[1, 0]);
  float x00 = PrivateDot(per.x, per.y, Grads[0, 0]);

  float xx0 = gm.LerpDel(x00, x01, per.y);
  float xx1 = gm.LerpDel(x10, x11, per.y);



  return gm.LerpDel(xx0, xx1, per.x);
  }

  private float PrivateDot(float x, float y, fVec2 vec)
  {
  return x * vec.x + y * vec.y;
  }
  }

  public class Perlin2dHash
  {
  public int MaxBuffer = 1000;
  private object AddRemoveLock = new object();
  private Queue<PerlinCoord> AddOrder = new Queue<PerlinCoord>();
  private Dictionary<PerlinCoord, Perlin2dSquare> Squares = new Dictionary<PerlinCoord, Perlin2dSquare>();
  private GradientManager GM;

  public Perlin2dHash(GradientManager gm)
  {
  GM = gm;
  }

  public void Sample(PerlinVector vec)
  {
  if(!Squares.ContainsKey(vec))
  {
  CreateSquare((PerlinCoord)vec);
  }
  vec.AddVal(Squares[(PerlinCoord)vec].Sample(vec.Float));
  }

  private void CreateSquare(PerlinCoord pc)
  {
  lock(AddRemoveLock)
  {
  GM.x = pc.x;
  GM.y = pc.y;
  PerlinCoord copy = new PerlinCoord(pc);

  Perlin2dSquare p2d = new Perlin2dSquare(GM, copy);
  AddOrder.Enqueue(copy);
  Squares.Add(copy, p2d);

  while(AddOrder.Count > MaxBuffer)
  {
  Squares.Remove(AddOrder.Dequeue());
  }
  }
  }

  }

  public struct fVec2
  {
  #region CircleGrad

  public static fVec2[] CircleGrad = { new float[]{ 0f, 1f }, new float[]{ -0.01227154f, 0.9999247f }, new float[]{ -0.02454123f, 0.9996988f }, new float[]{ -0.03680722f, 0.9993224f }, new float[]{ -0.04906768f, 0.9987954f }, new float[]{ -0.06132074f, 0.9981181f }, new float[]{ -0.07356457f, 0.9972904f }, new float[]{ -0.08579732f, 0.9963126f }, new float[]{ -0.09801714f, 0.9951847f }, new float[]{ -0.1102222f, 0.993907f }, new float[]{ -0.1224107f, 0.9924796f }, new float[]{ -0.1345807f, 0.9909027f }, new float[]{ -0.1467305f, 0.9891765f }, new float[]{ -0.1588582f, 0.9873014f }, new float[]{ -0.1709619f, 0.9852777f }, new float[]{ -0.1830399f, 0.9831055f }, new float[]{ -0.1950903f, 0.9807853f }, new float[]{ -0.2071114f, 0.9783174f }, new float[]{ -0.2191012f, 0.9757021f }, new float[]{ -0.2310581f, 0.97294f }, new float[]{ -0.2429802f, 0.9700313f }, new float[]{ -0.2548657f, 0.9669765f }, new float[]{ -0.2667128f, 0.9637761f }, new float[]{ -0.2785197f, 0.9604305f }, new float[]{ -0.2902847f, 0.9569404f }, new float[]{ -0.3020059f, 0.953306f }, new float[]{ -0.3136818f, 0.9495282f }, new float[]{ -0.3253103f, 0.9456073f }, new float[]{ -0.3368899f, 0.9415441f }, new float[]{ -0.3484187f, 0.937339f }, new float[]{ -0.3598951f, 0.9329928f }, new float[]{ -0.3713172f, 0.9285061f }, new float[]{ -0.3826835f, 0.9238795f }, new float[]{ -0.3939921f, 0.9191139f }, new float[]{ -0.4052413f, 0.9142097f }, new float[]{ -0.4164296f, 0.9091679f }, new float[]{ -0.4275551f, 0.9039893f }, new float[]{ -0.4386162f, 0.8986745f }, new float[]{ -0.4496113f, 0.8932243f }, new float[]{ -0.4605387f, 0.8876396f }, new float[]{ -0.4713967f, 0.8819212f }, new float[]{ -0.4821838f, 0.8760701f }, new float[]{ -0.4928982f, 0.870087f }, new float[]{ -0.5035384f, 0.8639728f }, new float[]{ -0.5141028f, 0.8577286f }, new float[]{ -0.5245897f, 0.8513552f }, new float[]{ -0.5349976f, 0.8448536f }, new float[]{ -0.545325f, 0.8382247f }, new float[]{ -0.5555702f, 0.8314696f }, new float[]{ -0.5657318f, 0.8245893f },
                     new float[]{ -0.5758082f, 0.8175848f }, new float[]{ -0.5857979f, 0.8104572f }, new float[]{ -0.5956993f, 0.8032075f }, new float[]{ -0.605511f, 0.7958369f }, new float[]{ -0.6152316f, 0.7883464f }, new float[]{ -0.6248595f, 0.7807372f }, new float[]{ -0.6343933f, 0.7730104f }, new float[]{ -0.6438316f, 0.7651672f }, new float[]{ -0.6531729f, 0.7572088f }, new float[]{ -0.6624158f, 0.7491364f }, new float[]{ -0.671559f, 0.7409511f }, new float[]{ -0.680601f, 0.7326543f }, new float[]{ -0.6895406f, 0.7242471f }, new float[]{ -0.6983763f, 0.7157308f }, new float[]{ -0.7071068f, 0.7071068f }, new float[]{ -0.7157308f, 0.6983762f }, new float[]{ -0.7242471f, 0.6895405f }, new float[]{ -0.7326543f, 0.680601f }, new float[]{ -0.7409512f, 0.6715589f }, new float[]{ -0.7491364f, 0.6624157f }, new float[]{ -0.7572089f, 0.6531728f }, new float[]{ -0.7651673f, 0.6438316f }, new float[]{ -0.7730104f, 0.6343933f }, new float[]{ -0.7807373f, 0.6248595f }, new float[]{ -0.7883464f, 0.6152316f }, new float[]{ -0.7958369f, 0.605511f }, new float[]{ -0.8032075f, 0.5956993f }, new float[]{ -0.8104572f, 0.5857978f }, new float[]{ -0.8175848f, 0.5758082f }, new float[]{ -0.8245893f, 0.5657318f }, new float[]{ -0.8314697f, 0.5555702f }, new float[]{ -0.8382247f, 0.545325f }, new float[]{ -0.8448536f, 0.5349976f }, new float[]{ -0.8513552f, 0.5245897f }, new float[]{ -0.8577287f, 0.5141027f }, new float[]{ -0.8639728f, 0.5035384f }, new float[]{ -0.870087f, 0.4928982f }, new float[]{ -0.8760701f, 0.4821837f }, new float[]{ -0.8819213f, 0.4713967f }, new float[]{ -0.8876396f, 0.4605387f }, new float[]{ -0.8932243f, 0.4496113f }, new float[]{ -0.8986745f, 0.4386162f }, new float[]{ -0.9039893f, 0.4275551f }, new float[]{ -0.909168f, 0.4164295f }, new float[]{ -0.9142098f, 0.4052413f }, new float[]{ -0.9191139f, 0.3939919f }, new float[]{ -0.9238795f, 0.3826834f }, new float[]{ -0.9285061f, 0.3713171f }, new float[]{ -0.9329928f, 0.359895f }, new float[]{ -0.937339f, 0.3484187f },
                     new float[]{ -0.9415441f, 0.3368898f }, new float[]{ -0.9456074f, 0.3253102f }, new float[]{ -0.9495282f, 0.3136817f }, new float[]{ -0.953306f, 0.3020059f }, new float[]{ -0.9569404f, 0.2902846f }, new float[]{ -0.9604306f, 0.2785196f }, new float[]{ -0.9637761f, 0.2667128f }, new float[]{ -0.9669765f, 0.2548656f }, new float[]{ -0.9700313f, 0.2429801f }, new float[]{ -0.97294f, 0.2310581f }, new float[]{ -0.9757021f, 0.2191012f }, new float[]{ -0.9783174f, 0.2071113f }, new float[]{ -0.9807853f, 0.1950902f }, new float[]{ -0.9831055f, 0.1830399f }, new float[]{ -0.9852777f, 0.1709619f }, new float[]{ -0.9873014f, 0.1588581f }, new float[]{ -0.9891765f, 0.1467305f }, new float[]{ -0.9909027f, 0.1345807f }, new float[]{ -0.9924796f, 0.1224106f }, new float[]{ -0.993907f, 0.1102221f }, new float[]{ -0.9951847f, 0.09801713f }, new float[]{ -0.9963126f, 0.08579727f }, new float[]{ -0.9972904f, 0.07356449f }, new float[]{ -0.9981181f, 0.06132075f }, new float[]{ -0.9987954f, 0.04906765f }, new float[]{ -0.9993224f, 0.03680716f }, new float[]{ -0.9996988f, 0.02454114f }, new float[]{ -0.9999247f, 0.01227153f }, new float[]{ -1f, -4.371139E-08f }, new float[]{ -0.9999247f, -0.01227162f }, new float[]{ -0.9996988f, -0.02454122f }, new float[]{ -0.9993224f, -0.03680725f }, new float[]{ -0.9987954f, -0.04906774f }, new float[]{ -0.9981181f, -0.06132083f }, new float[]{ -0.9972904f, -0.07356457f }, new float[]{ -0.9963126f, -0.08579736f }, new float[]{ -0.9951847f, -0.09801722f }, new float[]{ -0.993907f, -0.1102222f }, new float[]{ -0.9924795f, -0.1224107f }, new float[]{ -0.9909026f, -0.1345808f }, new float[]{ -0.9891765f, -0.1467306f }, new float[]{ -0.9873014f, -0.1588582f }, new float[]{ -0.9852777f, -0.1709619f }, new float[]{ -0.9831055f, -0.18304f }, new float[]{ -0.9807853f, -0.1950903f }, new float[]{ -0.9783174f, -0.2071114f }, new float[]{ -0.9757021f, -0.2191013f }, new float[]{ -0.9729399f, -0.2310582f }, new float[]{ -0.9700313f, -0.2429802f }, new float[]{ -0.9669765f, -0.2548657f },
                     new float[]{ -0.9637761f, -0.2667128f }, new float[]{ -0.9604305f, -0.2785197f }, new float[]{ -0.9569403f, -0.2902847f }, new float[]{ -0.953306f, -0.302006f }, new float[]{ -0.9495282f, -0.3136817f }, new float[]{ -0.9456073f, -0.3253103f }, new float[]{ -0.9415441f, -0.3368899f }, new float[]{ -0.9373389f, -0.3484188f }, new float[]{ -0.9329928f, -0.3598951f }, new float[]{ -0.9285061f, -0.3713172f }, new float[]{ -0.9238795f, -0.3826835f }, new float[]{ -0.9191139f, -0.393992f }, new float[]{ -0.9142097f, -0.4052413f }, new float[]{ -0.909168f, -0.4164295f }, new float[]{ -0.9039893f, -0.4275551f }, new float[]{ -0.8986744f, -0.4386162f }, new float[]{ -0.8932243f, -0.4496114f }, new float[]{ -0.8876396f, -0.4605388f }, new float[]{ -0.8819212f, -0.4713968f }, new float[]{ -0.87607f, -0.4821839f }, new float[]{ -0.870087f, -0.4928982f }, new float[]{ -0.8639728f, -0.5035384f }, new float[]{ -0.8577286f, -0.5141028f }, new float[]{ -0.8513551f, -0.5245897f }, new float[]{ -0.8448535f, -0.5349977f }, new float[]{ -0.8382246f, -0.5453251f }, new float[]{ -0.8314695f, -0.5555704f }, new float[]{ -0.8245893f, -0.5657318f }, new float[]{ -0.8175848f, -0.5758082f }, new float[]{ -0.8104572f, -0.5857979f }, new float[]{ -0.8032075f, -0.5956994f }, new float[]{ -0.7958369f, -0.6055111f }, new float[]{ -0.7883464f, -0.6152317f }, new float[]{ -0.7807371f, -0.6248596f }, new float[]{ -0.7730105f, -0.6343933f }, new float[]{ -0.7651672f, -0.6438316f }, new float[]{ -0.7572088f, -0.6531729f }, new float[]{ -0.7491363f, -0.6624158f }, new float[]{ -0.7409511f, -0.671559f }, new float[]{ -0.7326542f, -0.6806011f }, new float[]{ -0.724247f, -0.6895407f }, new float[]{ -0.7157308f, -0.6983762f }, new float[]{ -0.7071068f, -0.7071068f }, new float[]{ -0.6983762f, -0.7157308f }, new float[]{ -0.6895405f, -0.7242472f }, new float[]{ -0.6806009f, -0.7326543f }, new float[]{ -0.6715589f, -0.7409512f }, new float[]{ -0.6624156f, -0.7491365f }, new float[]{ -0.6531729f, -0.7572088f }, new float[]{ -0.6438316f, -0.7651673f },
                     new float[]{ -0.6343933f, -0.7730105f }, new float[]{ -0.6248595f, -0.7807373f }, new float[]{ -0.6152315f, -0.7883465f }, new float[]{ -0.605511f, -0.795837f }, new float[]{ -0.5956991f, -0.8032076f }, new float[]{ -0.5857978f, -0.8104572f }, new float[]{ -0.5758082f, -0.8175848f }, new float[]{ -0.5657318f, -0.8245893f }, new float[]{ -0.5555702f, -0.8314697f }, new float[]{ -0.5453249f, -0.8382248f }, new float[]{ -0.5349975f, -0.8448536f }, new float[]{ -0.5245895f, -0.8513553f }, new float[]{ -0.5141028f, -0.8577286f }, new float[]{ -0.5035384f, -0.8639728f }, new float[]{ -0.4928981f, -0.870087f }, new float[]{ -0.4821837f, -0.8760701f }, new float[]{ -0.4713966f, -0.8819214f }, new float[]{ -0.4605386f, -0.8876397f }, new float[]{ -0.4496114f, -0.8932243f }, new float[]{ -0.4386162f, -0.8986745f }, new float[]{ -0.4275551f, -0.9039893f }, new float[]{ -0.4164295f, -0.909168f }, new float[]{ -0.4052412f, -0.9142098f }, new float[]{ -0.3939919f, -0.9191139f }, new float[]{ -0.3826833f, -0.9238796f }, new float[]{ -0.3713172f, -0.9285061f }, new float[]{ -0.3598951f, -0.9329928f }, new float[]{ -0.3484187f, -0.937339f }, new float[]{ -0.3368898f, -0.9415441f }, new float[]{ -0.3253102f, -0.9456074f }, new float[]{ -0.3136816f, -0.9495282f }, new float[]{ -0.3020058f, -0.9533061f }, new float[]{ -0.2902847f, -0.9569404f }, new float[]{ -0.2785197f, -0.9604305f }, new float[]{ -0.2667127f, -0.9637761f }, new float[]{ -0.2548656f, -0.9669765f }, new float[]{ -0.2429801f, -0.9700313f }, new float[]{ -0.231058f, -0.97294f }, new float[]{ -0.2191011f, -0.9757022f }, new float[]{ -0.2071114f, -0.9783174f }, new float[]{ -0.1950903f, -0.9807853f }, new float[]{ -0.1830398f, -0.9831055f }, new float[]{ -0.1709618f, -0.9852777f }, new float[]{ -0.158858f, -0.9873014f }, new float[]{ -0.1467303f, -0.9891765f }, new float[]{ -0.1345805f, -0.9909027f }, new float[]{ -0.1224107f, -0.9924795f }, new float[]{ -0.1102222f, -0.993907f }, new float[]{ -0.0980171f, -0.9951847f }, new float[]{ -0.08579723f, -0.9963126f },
                     new float[]{ -0.07356445f, -0.9972905f }, new float[]{ -0.06132058f, -0.9981181f }, new float[]{ -0.04906749f, -0.9987954f }, new float[]{ -0.03680724f, -0.9993224f }, new float[]{ -0.02454121f, -0.9996988f }, new float[]{ -0.01227149f, -0.9999247f }, new float[]{ 8.742278E-08f, -1f }, new float[]{ 0.01227166f, -0.9999247f }, new float[]{ 0.02454139f, -0.9996988f }, new float[]{ 0.03680741f, -0.9993224f }, new float[]{ 0.04906766f, -0.9987954f }, new float[]{ 0.06132076f, -0.9981181f }, new float[]{ 0.07356462f, -0.9972904f }, new float[]{ 0.08579741f, -0.9963126f }, new float[]{ 0.09801727f, -0.9951847f }, new float[]{ 0.1102224f, -0.993907f }, new float[]{ 0.1224109f, -0.9924795f }, new float[]{ 0.1345807f, -0.9909027f }, new float[]{ 0.1467305f, -0.9891765f }, new float[]{ 0.1588582f, -0.9873014f }, new float[]{ 0.170962f, -0.9852777f }, new float[]{ 0.18304f, -0.9831055f }, new float[]{ 0.1950905f, -0.9807853f }, new float[]{ 0.2071116f, -0.9783173f }, new float[]{ 0.2191012f, -0.9757021f }, new float[]{ 0.2310581f, -0.97294f }, new float[]{ 0.2429802f, -0.9700313f }, new float[]{ 0.2548658f, -0.9669765f }, new float[]{ 0.2667129f, -0.9637761f }, new float[]{ 0.2785199f, -0.9604304f }, new float[]{ 0.2902849f, -0.9569403f }, new float[]{ 0.3020059f, -0.953306f }, new float[]{ 0.3136818f, -0.9495282f }, new float[]{ 0.3253103f, -0.9456073f }, new float[]{ 0.33689f, -0.9415441f }, new float[]{ 0.3484188f, -0.9373389f }, new float[]{ 0.3598952f, -0.9329928f }, new float[]{ 0.3713174f, -0.928506f }, new float[]{ 0.3826834f, -0.9238795f }, new float[]{ 0.3939921f, -0.9191138f }, new float[]{ 0.4052414f, -0.9142097f }, new float[]{ 0.4164297f, -0.9091679f }, new float[]{ 0.4275552f, -0.9039893f }, new float[]{ 0.4386164f, -0.8986744f }, new float[]{ 0.4496115f, -0.8932242f }, new float[]{ 0.4605387f, -0.8876396f }, new float[]{ 0.4713968f, -0.8819212f }, new float[]{ 0.4821838f, -0.8760701f }, new float[]{ 0.4928983f, -0.8700869f }, new float[]{ 0.5035385f, -0.8639728f },
                     new float[]{ 0.5141029f, -0.8577285f }, new float[]{ 0.5245897f, -0.8513552f }, new float[]{ 0.5349976f, -0.8448536f }, new float[]{ 0.545325f, -0.8382246f }, new float[]{ 0.5555703f, -0.8314695f }, new float[]{ 0.5657319f, -0.8245893f }, new float[]{ 0.5758083f, -0.8175847f }, new float[]{ 0.585798f, -0.8104571f }, new float[]{ 0.5956993f, -0.8032075f }, new float[]{ 0.6055111f, -0.7958369f }, new float[]{ 0.6152316f, -0.7883464f }, new float[]{ 0.6248596f, -0.7807372f }, new float[]{ 0.6343934f, -0.7730104f }, new float[]{ 0.6438317f, -0.7651672f }, new float[]{ 0.653173f, -0.7572087f }, new float[]{ 0.6624158f, -0.7491364f }, new float[]{ 0.671559f, -0.7409511f }, new float[]{ 0.6806011f, -0.7326542f }, new float[]{ 0.6895406f, -0.724247f }, new float[]{ 0.6983764f, -0.7157307f }, new float[]{ 0.7071069f, -0.7071066f }, new float[]{ 0.715731f, -0.6983761f }, new float[]{ 0.7242471f, -0.6895406f }, new float[]{ 0.7326543f, -0.680601f }, new float[]{ 0.7409512f, -0.6715589f }, new float[]{ 0.7491364f, -0.6624157f }, new float[]{ 0.7572088f, -0.6531729f }, new float[]{ 0.7651672f, -0.6438316f }, new float[]{ 0.7730104f, -0.6343933f }, new float[]{ 0.7807372f, -0.6248595f }, new float[]{ 0.7883465f, -0.6152316f }, new float[]{ 0.7958369f, -0.605511f }, new float[]{ 0.8032076f, -0.5956992f }, new float[]{ 0.8104573f, -0.5857977f }, new float[]{ 0.8175849f, -0.575808f }, new float[]{ 0.8245894f, -0.5657316f }, new float[]{ 0.8314698f, -0.55557f }, new float[]{ 0.8382249f, -0.5453247f }, new float[]{ 0.8448538f, -0.5349973f }, new float[]{ 0.8513554f, -0.5245894f }, new float[]{ 0.8577285f, -0.5141028f }, new float[]{ 0.8639728f, -0.5035384f }, new float[]{ 0.870087f, -0.4928982f }, new float[]{ 0.8760701f, -0.4821838f }, new float[]{ 0.8819213f, -0.4713967f }, new float[]{ 0.8876396f, -0.4605386f }, new float[]{ 0.8932244f, -0.4496112f }, new float[]{ 0.8986745f, -0.4386161f }, new float[]{ 0.9039894f, -0.4275549f }, new float[]{ 0.9091681f, -0.4164294f },
                     new float[]{ 0.9142098f, -0.4052411f }, new float[]{ 0.919114f, -0.3939918f }, new float[]{ 0.9238797f, -0.3826831f }, new float[]{ 0.928506f, -0.3713173f }, new float[]{ 0.9329928f, -0.3598951f }, new float[]{ 0.937339f, -0.3484187f }, new float[]{ 0.9415441f, -0.3368899f }, new float[]{ 0.9456073f, -0.3253103f }, new float[]{ 0.9495282f, -0.3136817f }, new float[]{ 0.9533061f, -0.3020059f }, new float[]{ 0.9569404f, -0.2902845f }, new float[]{ 0.9604306f, -0.2785195f }, new float[]{ 0.9637761f, -0.2667126f }, new float[]{ 0.9669765f, -0.2548654f }, new float[]{ 0.9700313f, -0.2429799f }, new float[]{ 0.97294f, -0.2310578f }, new float[]{ 0.9757022f, -0.2191009f }, new float[]{ 0.9783173f, -0.2071115f }, new float[]{ 0.9807853f, -0.1950904f }, new float[]{ 0.9831055f, -0.1830399f }, new float[]{ 0.9852777f, -0.1709619f }, new float[]{ 0.9873014f, -0.1588581f }, new float[]{ 0.9891765f, -0.1467304f }, new float[]{ 0.9909027f, -0.1345806f }, new float[]{ 0.9924796f, -0.1224105f }, new float[]{ 0.993907f, -0.110222f }, new float[]{ 0.9951847f, -0.09801693f }, new float[]{ 0.9963126f, -0.08579707f }, new float[]{ 0.9972905f, -0.07356428f }, new float[]{ 0.9981181f, -0.06132042f }, new float[]{ 0.9987954f, -0.04906733f }, new float[]{ 0.9993224f, -0.03680731f }, new float[]{ 0.9996988f, -0.02454129f }, new float[]{ 0.9999247f, -0.01227156f }, new float[]{ 1f, 1.192488E-08f }, new float[]{ 0.9999247f, 0.01227158f }, new float[]{ 0.9996988f, 0.02454131f }, new float[]{ 0.9993224f, 0.03680734f }, new float[]{ 0.9987954f, 0.04906783f }, new float[]{ 0.9981181f, 0.06132092f }, new float[]{ 0.9972904f, 0.07356478f }, new float[]{ 0.9963126f, 0.08579757f }, new float[]{ 0.9951847f, 0.09801743f }, new float[]{ 0.9939069f, 0.1102225f }, new float[]{ 0.9924795f, 0.122411f }, new float[]{ 0.9909027f, 0.1345806f }, new float[]{ 0.9891765f, 0.1467304f }, new float[]{ 0.9873014f, 0.1588581f }, new float[]{ 0.9852777f, 0.1709619f }, new float[]{ 0.9831055f, 0.1830399f },
                     new float[]{ 0.9807853f, 0.1950904f }, new float[]{ 0.9783173f, 0.2071115f }, new float[]{ 0.9757021f, 0.2191014f }, new float[]{ 0.9729399f, 0.2310583f }, new float[]{ 0.9700312f, 0.2429804f }, new float[]{ 0.9669764f, 0.2548659f }, new float[]{ 0.963776f, 0.2667131f }, new float[]{ 0.9604304f, 0.27852f }, new float[]{ 0.9569402f, 0.290285f }, new float[]{ 0.9533061f, 0.3020059f }, new float[]{ 0.9495282f, 0.3136817f }, new float[]{ 0.9456073f, 0.3253103f }, new float[]{ 0.9415441f, 0.3368899f }, new float[]{ 0.937339f, 0.3484187f }, new float[]{ 0.9329928f, 0.3598951f }, new float[]{ 0.928506f, 0.3713173f }, new float[]{ 0.9238794f, 0.3826836f }, new float[]{ 0.9191138f, 0.3939922f }, new float[]{ 0.9142097f, 0.4052415f }, new float[]{ 0.9091679f, 0.4164298f }, new float[]{ 0.9039891f, 0.4275554f }, new float[]{ 0.8986743f, 0.4386165f }, new float[]{ 0.8932241f, 0.4496117f }, new float[]{ 0.8876396f, 0.4605387f }, new float[]{ 0.8819213f, 0.4713967f }, new float[]{ 0.8760701f, 0.4821838f }, new float[]{ 0.870087f, 0.4928982f }, new float[]{ 0.8639728f, 0.5035384f }, new float[]{ 0.8577285f, 0.5141028f }, new float[]{ 0.8513551f, 0.5245898f }, new float[]{ 0.8448535f, 0.5349978f }, new float[]{ 0.8382246f, 0.5453252f }, new float[]{ 0.8314695f, 0.5555704f }, new float[]{ 0.8245891f, 0.5657321f }, new float[]{ 0.8175846f, 0.5758085f }, new float[]{ 0.810457f, 0.5857981f }, new float[]{ 0.8032076f, 0.5956993f }, new float[]{ 0.7958369f, 0.605511f }, new float[]{ 0.7883464f, 0.6152316f }, new float[]{ 0.7807372f, 0.6248595f }, new float[]{ 0.7730104f, 0.6343933f }, new float[]{ 0.7651672f, 0.6438316f }, new float[]{ 0.7572088f, 0.6531729f }, new float[]{ 0.7491363f, 0.6624159f }, new float[]{ 0.740951f, 0.6715591f }, new float[]{ 0.7326541f, 0.6806012f }, new float[]{ 0.7242469f, 0.6895407f }, new float[]{ 0.7157306f, 0.6983765f }, new float[]{ 0.7071065f, 0.707107f }, new float[]{ 0.698376f, 0.7157311f },
                     new float[]{ 0.6895406f, 0.724247f }, new float[]{ 0.680601f, 0.7326543f }, new float[]{ 0.671559f, 0.7409511f }, new float[]{ 0.6624157f, 0.7491364f }, new float[]{ 0.6531728f, 0.7572089f }, new float[]{ 0.6438315f, 0.7651674f }, new float[]{ 0.6343932f, 0.7730106f }, new float[]{ 0.6248593f, 0.7807373f }, new float[]{ 0.6152315f, 0.7883465f }, new float[]{ 0.6055108f, 0.795837f }, new float[]{ 0.5956991f, 0.8032077f }, new float[]{ 0.5857976f, 0.8104573f }, new float[]{ 0.5758079f, 0.817585f }, new float[]{ 0.5657315f, 0.8245895f }, new float[]{ 0.5555703f, 0.8314696f }, new float[]{ 0.545325f, 0.8382247f }, new float[]{ 0.5349976f, 0.8448536f }, new float[]{ 0.5245897f, 0.8513552f }, new float[]{ 0.5141027f, 0.8577287f }, new float[]{ 0.5035383f, 0.8639729f }, new float[]{ 0.4928981f, 0.8700871f }, new float[]{ 0.4821836f, 0.8760702f }, new float[]{ 0.4713965f, 0.8819214f }, new float[]{ 0.4605385f, 0.8876398f }, new float[]{ 0.4496111f, 0.8932244f }, new float[]{ 0.4386159f, 0.8986746f }, new float[]{ 0.4275548f, 0.9039894f }, new float[]{ 0.4164292f, 0.9091681f }, new float[]{ 0.4052414f, 0.9142097f }, new float[]{ 0.3939921f, 0.9191138f }, new float[]{ 0.3826834f, 0.9238796f }, new float[]{ 0.3713171f, 0.9285061f }, new float[]{ 0.359895f, 0.9329928f }, new float[]{ 0.3484186f, 0.9373391f }, new float[]{ 0.3368897f, 0.9415441f }, new float[]{ 0.3253101f, 0.9456074f }, new float[]{ 0.3136815f, 0.9495283f }, new float[]{ 0.3020057f, 0.9533061f }, new float[]{ 0.2902844f, 0.9569404f }, new float[]{ 0.2785194f, 0.9604306f }, new float[]{ 0.2667124f, 0.9637762f }, new float[]{ 0.2548653f, 0.9669766f }, new float[]{ 0.2429802f, 0.9700313f }, new float[]{ 0.2310581f, 0.97294f }, new float[]{ 0.2191012f, 0.9757021f }, new float[]{ 0.2071113f, 0.9783174f }, new float[]{ 0.1950902f, 0.9807853f }, new float[]{ 0.1830398f, 0.9831055f }, new float[]{ 0.1709617f, 0.9852777f }, new float[]{ 0.1588579f, 0.9873015f },
                     new float[]{ 0.1467302f, 0.9891766f }, new float[]{ 0.1345804f, 0.9909027f }, new float[]{ 0.1224104f, 0.9924796f }, new float[]{ 0.1102219f, 0.993907f }, new float[]{ 0.09801677f, 0.9951848f }, new float[]{ 0.08579691f, 0.9963126f }, new float[]{ 0.0735646f, 0.9972904f }, new float[]{ 0.06132074f, 0.9981181f }, new float[]{ 0.04906764f, 0.9987954f }, new float[]{ 0.03680715f, 0.9993224f }, new float[]{ 0.02454112f, 0.9996988f }, new float[]{ 0.0122714f, 0.9999247f }  };

  #endregion

  private float[] Floats;

  public float x
  {
  get
  {
  return Floats[0];
  }
  set
  {
  Floats[0] = value;
  }
  }
  public float y
  {
  get
  {
  return Floats[1];
  }
  set
  {
  Floats[1] = value;
  }
  }
  public float this[int a]
  {
  get
  {
  switch (a)
  {
  case 0:
  return Floats[0];
  case 1:
  return Floats[1];
  default:
  throw new IndexOutOfRangeException("Attempted to access a nonexistent component of an fVec2");
  }
  }
  set
  {
  switch (a)
  {
  case 0:
  Floats[0] = value;
  break;
  case 1:
  Floats[1] = value;
  break;
  default:
  throw new IndexOutOfRangeException("Attempted to access a nonexistent component of an fVec2");
  }
  }
  }
  public fVec2 U
  {
  get
  {
  return GetUnit();
  }
  }
  public float L
  {
  get
  {
  return (float)Math.Sqrt(Math.Pow(x, 2) + Math.Pow(y, 2));
  }
  set
  {
  this = value * U;
  }
  }

  #region Constructors



  public fVec2(float X, float Y)
  {
  Floats = new float[2];
  x = X;
  y = Y;
  }

  #endregion

  public fVec2 RotateVec(float rads)
  {
  float COS = (float)Math.Cos(rads);
  float SIN = (float)Math.Sin(rads);

  return new fVec2(x * COS - y * SIN, x * SIN + y * COS);
  }

  public override string ToString()
  {
  return String.Format("{0}, {1} ", x, y);
  }

  private fVec2 GetUnit()
  {
  float len = L;
  return new fVec2(x / L, y / L);
  }

  #region Overloads

  public static fVec2 operator +(float a, fVec2 b)
  {
  return new fVec2(a + b.x, a + b.y);
  }

  public static fVec2 operator +(fVec2 a, float b)
  {
  return b + a;
  }

  public static fVec2 operator +(fVec2 a, fVec2 b)
  {
  return new fVec2(a.x + b.x, a.y + b.y);
  }

  public static fVec2 operator -(fVec2 a, float b)
  {
  return new fVec2(a.x - b, a.y - b);
  }

  public static fVec2 operator -(fVec2 a, fVec2 b)
  {
  return new fVec2(a.x - b.x, a.y - b.y);
  }

  public static fVec2 operator -(fVec2 a)
  {
  return new fVec2(-a.x, -a.y);
  }

  public static fVec2 operator *(float a, fVec2 b)
  {
  return new fVec2(a * b.x, a * b.y);
  }

  public static float operator *(fVec2 a, fVec2 b)
  {
  return a.x * b.x + a.y * b.y;
  }

  public static implicit operator fVec2(float[] Vals)
  {
  return new fVec2(Vals[0], Vals[1]);
  }

  public static implicit operator fVec2(Vector2 vec)
  {
  return new fVec2(vec.x, vec.y);
  }

  public static implicit operator Vector2(fVec2 vec)
  {
  return new Vector2(vec.x, vec.y);
  }

  public static implicit operator string(fVec2 vec)
  {
  StringBuilder sb = new StringBuilder();
  sb.Append("< ");
  sb.Append(vec.ToString());
  sb.Append(" >");
  return sb.ToString();
  }

  #endregion
  }

  public class RNG2_0
  {
  public static byte[] AllByte = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF };

  private byte[] NewArray = new byte[256];
  private byte[] SecondArray = new byte[256];
  private Pointer[] Array = new Pointer[8];
  private MemoryStream ms;
  private BinaryReader br;

  private byte[] CurKey = new byte[8];

  public class Pointer
  {
  public byte Loc = 0;

  private byte[] arr;
  private int Sel = 0;

  public Pointer(byte[] Array, byte Seed, int Behavior)
  {
  Loc = Seed;
  Sel = Behavior;
  arr = Array;


  }

  public byte Next(byte val)
  {
  switch (Sel)
  {
  case 0:
  Loc++;
  break;
  case 1:
  Loc--;
  break;
  case 2:
  Loc += val;
  break;
  case 3:
  Loc -= val;
  break;
  case 4:
  Loc = (byte)(Loc ^ val);
  break;
  case 5:
  Loc = (byte)((Loc + val) ^ val);
  break;
  case 6:
  Loc = (byte)((Loc >> 1) ^ val);
  break;
  case 7:
  Loc += (byte)(Loc ^ (val >> 1));
  break;
  default:
  break;
  }

  //stats[Loc]++;

  return (byte)(arr[Loc] ^ val);
  }
  }

  public RNG2_0()
  {
  long val = DateTime.UtcNow.Ticks;
  byte[] Seed = new byte[] { (byte)(val >> 56), (byte)(val >> 48), (byte)(val >> 40), (byte)(val >> 32), (byte)(val >> 24), (byte)(val >> 16), (byte)(val >> 8), (byte)val };

  for (int i = 0; i < Seed.Length; i++)
  {
  if (i == 0)
  {
  for (int j = 0; j < 256; j++)
  {
  NewArray[j] = AllByte[(Seed[0] ^ j)];
  }
  }
  else if (i % 2 == 1)
  {
  //AppConsole.AppConsole.Instance.WriteLine("Second Array!");
  for (int j = 0; j < 256; j++)
  {
  SecondArray[j] = (byte)(NewArray[(Seed[i] ^ j)] ^ Seed[i]);
  }
  }
  else
  {
  for (int j = 0; j < 256; j++)
  {
  NewArray[j] = (byte)((SecondArray[(Seed[i] ^ j)] + Seed[i]));
  }
  //AppConsole.AppConsole.Instance.WriteLine("First Array!");
  }
  }
  if (Seed.Length % 2 == 0)
  {
  //AppConsole.AppConsole.Instance.WriteLine("Switching!");
  NewArray = SecondArray;
  }

  FillPointerArr(Seed);
  InitalizeMS();
  InitializeKey(Seed);

  }

  public RNG2_0(string StrSeed)
  {
  byte[] Seed = StringtoByteArrayU8(StrSeed);

  for (int i = 0; i < Seed.Length; i++)
  {
  if (i == 0)
  {
  for (int j = 0; j < 256; j++)
  {
  NewArray[j] = AllByte[(Seed[0] ^ j)];
  }
  }
  else if (i % 2 == 1)
  {
  //AppConsole.AppConsole.Instance.WriteLine("Second Array!");
  for (int j = 0; j < 256; j++)
  {
  SecondArray[j] = (byte)(NewArray[(Seed[i] ^ j)] ^ Seed[i]);
  }
  }
  else
  {
  for (int j = 0; j < 256; j++)
  {
  NewArray[j] = (byte)((SecondArray[(Seed[i] ^ j)] + Seed[i]));
  }
  //AppConsole.AppConsole.Instance.WriteLine("First Array!");
  }
  }
  if (Seed.Length % 2 == 0)
  {
  //AppConsole.AppConsole.Instance.WriteLine("Switching!");
  NewArray = SecondArray;
  }

  FillPointerArr(Seed);
  InitalizeMS();
  InitializeKey(Seed);
  }

  public RNG2_0(byte[] Seed)
  {
  for (int i = 0; i < Seed.Length; i++)
  {
  if (i == 0)
  {
  for (int j = 0; j < 256; j++)
  {
  NewArray[j] = AllByte[(Seed[0] ^ j)];
  }
  }
  else if (i % 2 == 1)
  {
  //AppConsole.AppConsole.Instance.WriteLine("Second Array!");
  for (int j = 0; j < 256; j++)
  {
  SecondArray[j] = (byte)(NewArray[(Seed[i] ^ j)] ^ Seed[i]);
  }
  }
  else
  {
  for (int j = 0; j < 256; j++)
  {
  NewArray[j] = (byte)((SecondArray[(Seed[i] ^ j)] + Seed[i]));
  }
  //AppConsole.AppConsole.Instance.WriteLine("First Array!");
  }
  }
  if (Seed.Length % 2 == 0)
  {
  //AppConsole.AppConsole.Instance.WriteLine("Switching!");
  NewArray = SecondArray;
  }

  FillPointerArr(Seed);
  InitalizeMS();
  InitializeKey(Seed);
  }

  private static byte[] StringtoByteArrayU8(string tempstr)
  {
  int length = tempstr.Length;
  byte[] returnArray = new byte[length];
  for (int i = 0; i < length; i++)
  {
  byte a = (byte)((uint)tempstr[i]);
  returnArray[i] = a;
  }

  return returnArray;
  }

  private void FillPointerArr(byte[] Seed)
  {
  for (int i = 0; i < 8; i++)
  {
  Array[i] = new Pointer(NewArray, Seed[i % Seed.Length], i);
  }
  }

  private void InitializeKey(byte[] Seed)
  {
  for (int i = 0; i < 8; i++)
  {
  CurKey[i] = Seed[i % Seed.Length];
  }
  NextKey();
  }

  private void InitalizeMS()
  {
  ms = new MemoryStream(CurKey);
  br = new BinaryReader(ms);
  }

  private void NextKey()
  {
  for (int i = 0; i < 8; i++)
  {
  for (int j = 0; j < 8; j++)
  {
  CurKey[i] = (byte)(Array[j].Next(CurKey[i]));
  }
  }
  ms.Seek(0, SeekOrigin.Begin);
  //AppConsole.AppConsole.Instance.WriteLine(DPMethods.ReadByteArray(CurKey));
  }

  public float NextFloat(float min, float max)
  {
  if (min == 0)
  {
  return (float)(NextRatio() * max);
  }
  else
  {
  float range = max - min;
  return (float)(min + range * NextRatio());
  }
  }

  public int NextInt(int min, int max)
  {
  if (min == 0)
  {
  return (int)(NextRatio() * (double)max);
  }
  else
  {
  int range = max - min;
  return min + (int)(NextRatio() * (double)range);
  }
  }

  public ulong GetNextULong(ulong start, ulong stop)
  {
  if (start == 0)
  {
  return (ulong)(NextRatio() * (ulong)stop);
  }
  else
  {
  ulong range = stop - start;
  return start + (ulong)(NextRatio() * (ulong)range);
  }
  }

  public byte[] GetArray()
  {
  return NewArray;
  }

  public double NextRatio()
  {
  double val = (double)((double)NextUlong() / (double)ulong.MaxValue);
  if (val == 1)
  {
  return NextRatio();
  }
  else
  {
  return val;
  }
  }

  private ulong NextUlong()
  {
  NextKey();
  return br.ReadUInt64();
  }


  }

}

In reality though, Perlin isn’t that hard of an algorithm at all - so you can always just make your own to your specific liking.

I think that’s more code than I’ve ever written into a single file in my entire time of programming. I’ll try it out in the morning, thanks.

If it doesn’t work, I may have found a solution elsewhere, so yep.

It was all in different files - I just threw them into one. However, when I did start programming I had a 25,000k line file of class objects. I’m still in the process of cutting it all up into small files.