diff --git a/src/exceptions.h b/src/exceptions.h
index 0ea4c935036573811ff57073022b7913992154ab..6bf832828a58bdc301f96f1197851a8021f91694 100644
--- a/src/exceptions.h
+++ b/src/exceptions.h
@@ -120,6 +120,11 @@ class ClientStateError : public BaseException {
 	ClientStateError(std::string s): BaseException(s) {}
 };
 
+class PrngException : public BaseException {
+public:
+	PrngException(std::string s): BaseException(s) {}
+};
+
 /*
 	Some "old-style" interrupts:
 */
diff --git a/src/noise.cpp b/src/noise.cpp
index 4bfc46f15053fffc0d4a4c2edb0412120c79ef23..2e4588124213be8566cff2b1abb095b689646607 100644
--- a/src/noise.cpp
+++ b/src/noise.cpp
@@ -115,7 +115,9 @@ u32 PcgRandom::range(u32 bound)
 
 s32 PcgRandom::range(s32 min, s32 max)
 {
-	assert(max >= min);
+	if (max < min)
+		throw PrngException("Invalid range (max < min)");
+
 	u32 bound = max - min + 1;
 	return range(bound) + min;
 }
diff --git a/src/noise.h b/src/noise.h
index d2287835ea9966dd618602c683e782e1f186cef1..5757cbc99871cc6473d4f53a9e11ff934eb992bc 100644
--- a/src/noise.h
+++ b/src/noise.h
@@ -26,8 +26,8 @@
 #ifndef NOISE_HEADER
 #define NOISE_HEADER
 
-#include "debug.h"
 #include "irr_v3d.h"
+#include "exceptions.h"
 #include "util/string.h"
 
 extern FlagDesc flagdesc_noiseparams[];
@@ -56,14 +56,16 @@ class PseudoRandom {
 
 	inline int range(int min, int max)
 	{
-		assert(max >= min);
+		if (max < min)
+			throw PrngException("Invalid range (max < min)");
 		/*
 		Here, we ensure the range is not too large relative to RANDOM_MAX,
 		as otherwise the effects of bias would become noticable.  Unlike
 		PcgRandom, we cannot modify this RNG's range as it would change the
 		output of this RNG for reverse compatibility.
 		*/
-		assert((u32)(max - min) <= (RANDOM_RANGE + 1) / 10);
+		if ((u32)(max - min) > (RANDOM_RANGE + 1) / 10)
+			throw PrngException("Range too large");
 
 		return (next() % (max - min + 1)) + min;
 	}