diff --git a/ScriptCore/Math/Random.cs b/ScriptCore/Math/Random.cs
index 66bd1ea..5429415 100644
--- a/ScriptCore/Math/Random.cs
+++ b/ScriptCore/Math/Random.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
namespace GlitchyEngine.Math;
@@ -31,4 +32,13 @@ public static class RandomExtension
/// A 32-bit signed integer greater than or equal to and less than ; that is, the range of return values includes but not . If equals , is returned.
/// is greater than .
public static double Range(this Random random, double min, double max) => random.NextDouble() * (max - min) + min;
+
+ ///
+ /// Picks a random element from the given list.
+ ///
+ ///
+ /// The list to pick an element from.
+ /// The type of elements in the list.
+ /// The randomly picked element.
+ public static T Pick(this Random random, IList list) => list[random.Range(0, list.Count)];
}
diff --git a/ScriptCore/Math/ThreadSafeRandom.cs b/ScriptCore/Math/ThreadSafeRandom.cs
new file mode 100644
index 0000000..f6c14fa
--- /dev/null
+++ b/ScriptCore/Math/ThreadSafeRandom.cs
@@ -0,0 +1,38 @@
+using System;
+
+namespace GlitchyEngine.Math;
+
+///
+/// A thread safe global random number generator.
+///
+///
+/// Based on https://andrewlock.net/building-a-thread-safe-random-implementation-for-dotnet-framework/
+///
+public static class ThreadSafeRandom
+{
+ [ThreadStatic]
+ private static Random? _local;
+ private static readonly Random Global = new();
+
+ ///
+ /// Gets a thread safe random number generator.
+ ///
+ public static Random Instance
+ {
+ get
+ {
+ if (_local is null)
+ {
+ int seed;
+ lock (Global)
+ {
+ seed = Global.Next();
+ }
+
+ _local = new Random(seed);
+ }
+
+ return _local;
+ }
+ }
+}