diff --git a/src/d_netcmd.c b/src/d_netcmd.c
index 5eb35283414b7f807249df101c14d4048bb1251e..c62ff8fe1ade152a6767ebe8843558f1a7c9b3c0 100644
--- a/src/d_netcmd.c
+++ b/src/d_netcmd.c
@@ -808,7 +808,7 @@ static boolean IsNameGood(char *name, INT32 playernum)
 			else if (len == 1) // Agh!
 			{
 				// Last ditch effort...
-				sprintf(name, "%d", M_Random() & 7);
+				sprintf(name, "%d", M_RandomKey(10));
 				if (!IsNameGood (name, playernum))
 					return false;
 			}
@@ -3583,7 +3583,7 @@ retryscramble:
 		for (i = 0; i < playercount; i++)
 		{
 			if (repick)
-				newteam = (INT16)((M_Random() % 2) + 1);
+				newteam = (INT16)((M_RandomByte() % 2) + 1);
 
 			// One team has the most players they can get, assign the rest to the other team.
 			if (red == maxcomposition || blue == maxcomposition)
@@ -3628,7 +3628,7 @@ retryscramble:
 		{
 			if (repick)
 			{
-				newteam = (INT16)((M_Random() % 2) + 1);
+				newteam = (INT16)((M_RandomByte() % 2) + 1);
 				repick = false;
 			}
 			else
diff --git a/src/g_game.c b/src/g_game.c
index 3b7ef158f3748eec3b3ceff6985f2a84cf786ce5..71171fd74c4f64631de79628dabb359b6c16ca6f 100644
--- a/src/g_game.c
+++ b/src/g_game.c
@@ -2331,8 +2331,8 @@ void G_SpawnPlayer(INT32 playernum, boolean starpost)
 		}
 	}
 	P_MovePlayerToSpawn(playernum, spawnpoint);
-	
-#ifdef HAVE_BLUA 
+
+#ifdef HAVE_BLUA
 	LUAh_PlayerSpawn(&players[playernum]); // Lua hook for player spawning :)
 #endif
 
@@ -2349,7 +2349,7 @@ mapthing_t *G_FindCTFStart(INT32 playernum)
 		return NULL;
 	}
 
-	if ((!players[playernum].ctfteam && numredctfstarts && (!numbluectfstarts || P_Random() & 1)) || players[playernum].ctfteam == 1) //red
+	if ((!players[playernum].ctfteam && numredctfstarts && (!numbluectfstarts || P_RandomChance(FRACUNIT/2))) || players[playernum].ctfteam == 1) //red
 	{
 		if (!numredctfstarts)
 		{
@@ -5487,7 +5487,7 @@ ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(void)
 		UINT8 i;
 		WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker
 		for (i = 0; i < 16; i++, p++)
-			*p = P_Random(); // This MD5 was chosen by fair dice roll and most likely < 50% correct.
+			*p = P_RandomByte(); // This MD5 was chosen by fair dice roll and most likely < 50% correct.
 #else
 		WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker
 		md5_buffer((char *)p+16, demo_p - (p+16), (void *)p); // make a checksum of everything after the checksum in the file.
@@ -5569,7 +5569,7 @@ boolean G_CheckDemoStatus(void)
 		UINT8 i;
 		WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker
 		for (i = 0; i < 16; i++, p++)
-			*p = P_Random(); // This MD5 was chosen by fair dice roll and most likely < 50% correct.
+			*p = P_RandomByte(); // This MD5 was chosen by fair dice roll and most likely < 50% correct.
 #else
 		WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker
 		md5_buffer((char *)p+16, demo_p - (p+16), p); // make a checksum of everything after the checksum in the file.
diff --git a/src/hardware/hw3sound.c b/src/hardware/hw3sound.c
index efc1d247b5191737e005d0a61c7b76d27cf6c438..c68430921fa4053b5e3fc96fe23f94804291a0ea 100644
--- a/src/hardware/hw3sound.c
+++ b/src/hardware/hw3sound.c
@@ -384,12 +384,12 @@ INT32 HW3S_I_StartSound(const void *origin_p, source3D_data_t *source_parm, chan
 		/*if (gamemode != heretic)
 		{
 			if (sfx_id >= sfx_sawup && sfx_id <= sfx_sawhit)
-				pitch += 8 - (M_Random()&15);
+				pitch += 8 - (M_RandomByte()&15);
 			else if (sfx_id != sfx_itemup && sfx_id != sfx_tink)
-				pitch += 16 - (M_Random()&31);
+				pitch += 16 - (M_RandomByte()&31);
 		}
 		else*/
-			pitch = 128 + (M_Random() & 7) - (M_Random() & 7);
+			pitch = 128 + (M_RandomByte() & 7) - (M_RandomByte() & 7);
 	}
 #endif
 
diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c
index fb369387f424764d88a76ffefa3e9c92506f06e6..a93e96dc3d3e27ea2497b0230c90812ad363744f 100644
--- a/src/hardware/hw_light.c
+++ b/src/hardware/hw_light.c
@@ -871,7 +871,7 @@ void HWR_DoCoronasLighting(FOutVector *outVerts, gr_vissprite_t *spr)
 				size  = p_lspr->corona_radius  * ((outVerts[0].z+120.0f)/950.0f); // d'ou vienne ces constante ?
 				break;
 			case ROCKET_SPR:
-				p_lspr->corona_color = (((M_Random()>>1)&0xff)<<24)|0x0040ff;
+				p_lspr->corona_color = (((M_RandomByte()>>1)&0xff)<<24)|0x0040ff;
 				// don't need a break
 			case CORONA_SPR:
 				size  = p_lspr->corona_radius  * ((outVerts[0].z+60.0f)/100.0f); // d'ou vienne ces constante ?
@@ -974,7 +974,7 @@ void HWR_DrawCoronas(void)
 				size  = p_lspr->corona_radius  * ((cz+120.0f)/950.0f); // d'ou vienne ces constante ?
 				break;
 			case ROCKET_SPR:
-				Surf.FlatColor.s.alpha = (UINT8)((M_Random()>>1)&0xff);
+				Surf.FlatColor.s.alpha = (UINT8)((M_RandomByte()>>1)&0xff);
 				// don't need a break
 			case CORONA_SPR:
 				size  = p_lspr->corona_radius  * ((cz+60.0f)/100.0f); // d'ou vienne ces constante ?
diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index 2cc79db47e7e3b2b7fae01905601902176decdb3..45f18627e57de78ae6d63af2fdf1e749a0907852 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -96,17 +96,17 @@ static int lib_evalMath(lua_State *L)
 // M_RANDOM
 //////////////
 
-static int lib_pRandom(lua_State *L)
+static int lib_pRandomFixed(lua_State *L)
 {
 	NOHUD
-	lua_pushinteger(L, P_Random());
+	lua_pushfixed(L, P_RandomFixed());
 	return 1;
 }
 
-static int lib_pSignedRandom(lua_State *L)
+static int lib_pRandomByte(lua_State *L)
 {
 	NOHUD
-	lua_pushinteger(L, P_SignedRandom());
+	lua_pushinteger(L, P_RandomByte());
 	return 1;
 }
 
@@ -134,6 +134,30 @@ static int lib_pRandomRange(lua_State *L)
 	return 1;
 }
 
+// Deprecated, macros, etc.
+static int lib_pRandom(lua_State *L)
+{
+	NOHUD
+	LUA_Deprecated(L, "P_Random", "P_RandomByte");
+	lua_pushinteger(L, P_RandomByte());
+	return 1;
+}
+
+static int lib_pSignedRandom(lua_State *L)
+{
+	NOHUD
+	lua_pushinteger(L, P_SignedRandom());
+	return 1;
+}
+
+static int lib_pRandomChance(lua_State *L)
+{
+	fixed_t p = luaL_checkfixed(L, 1);
+	NOHUD
+	lua_pushboolean(L, P_RandomChance(p));
+	return 1;
+}
+
 // P_MAPUTIL
 ///////////////
 
@@ -1910,10 +1934,13 @@ static luaL_Reg lib[] = {
 	{"EvalMath", lib_evalMath},
 
 	// m_random
-	{"P_Random",lib_pRandom},
-	{"P_SignedRandom",lib_pSignedRandom},
+	{"P_RandomFixed",lib_pRandomFixed},
+	{"P_RandomByte",lib_pRandomByte},
 	{"P_RandomKey",lib_pRandomKey},
 	{"P_RandomRange",lib_pRandomRange},
+	{"P_Random",lib_pRandom}, // DEPRECATED
+	{"P_SignedRandom",lib_pSignedRandom}, // MACRO
+	{"P_RandomChance",lib_pRandomChance}, // MACRO
 
 	// p_maputil
 	{"P_AproxDistance",lib_pAproxDistance},
diff --git a/src/m_cheat.c b/src/m_cheat.c
index 473fbbf75c0055a62f18170887aafb7cf07b2533..6ed8d286a5be8e4f583d46a36e9d53475375bfe1 100644
--- a/src/m_cheat.c
+++ b/src/m_cheat.c
@@ -618,9 +618,9 @@ void Command_CauseCfail_f(void)
 	}
 
 	P_UnsetThingPosition(players[consoleplayer].mo);
-	P_Random();
-	P_Random();
-	P_Random();
+	P_RandomFixed();
+	P_RandomByte();
+	P_RandomFixed();
 	players[consoleplayer].mo->x = 0;
 	players[consoleplayer].mo->y = 123311; //cfail cansuled kthxbye
 	players[consoleplayer].mo->z = 123311;
diff --git a/src/m_random.c b/src/m_random.c
index eab45a3ed59f3b8fbeca2c2104691f6f6413c648..caf4d517476195ff8716671e478bd4752858328d 100644
--- a/src/m_random.c
+++ b/src/m_random.c
@@ -19,48 +19,51 @@
 #include "m_random.h"
 #include "m_fixed.h"
 
+
+
 // ---------------------------
 // RNG functions (not synched)
 // ---------------------------
 
-/** Provides a random byte.
-  * Used outside the p_xxx game code and not synchronized in netgames. This is
-  * for anything that doesn't need to be synced, e.g. precipitation.
+/** Provides a random fixed point number. Distribution is uniform.
+  * As with all M_Random functions, not synched in netgames.
   *
-  * \return A random byte, 0 to 255.
+  * \return A random fixed point number from [0,1).
   */
-UINT8 M_Random(void)
+fixed_t M_RandomFixed(void)
 {
-	return (rand() & 255);
+	return (rand() & 0xFFFF);
 }
 
-/** Provides a random signed byte.  Distribution is uniform.
-  * As with all M_*Random functions, not synched in netgames.
+/** Provides a random byte. Distribution is uniform.
+  * As with all M_Random functions, not synched in netgames.
   *
-  * \return A random byte, -128 to 127.
-  * \sa M_Random
+  * \return A random integer from [0, 255].
   */
-INT32 M_SignedRandom(void)
+UINT8 M_RandomByte(void)
 {
-	return (rand() & 255) - 128;
+	return (rand() & 0xFF);
 }
 
-/** Provides a random number in between 0 and the given number - 1.
-  * Distribution is uniform.  Use for picking random elements from an array.
-  * As with all M_*Random functions, not synched in netgames.
+/** Provides a random integer for picking random elements from an array.
+  * Distribution is uniform.
+  * As with all M_Random functions, not synched in netgames.
   *
-  * \return A random number, 0 to arg1-1.
+  * \param a Number of items in array.
+  * \return A random integer from [0,a).
   */
 INT32 M_RandomKey(INT32 a)
 {
 	return (INT32)((rand()/((unsigned)RAND_MAX+1.0f))*a);
 }
 
-/** Provides a random number in between a specific range.
+/** Provides a random integer in a given range.
   * Distribution is uniform.
-  * As with all M_*Random functions, not synched in netgames.
+  * As with all M_Random functions, not synched in netgames.
   *
-  * \return A random number, arg1 to arg2.
+  * \param a Lower bound.
+  * \param b Upper bound.
+  * \return A random integer from [a,b].
   */
 INT32 M_RandomRange(INT32 a, INT32 b)
 {
@@ -79,8 +82,7 @@ static UINT32 randomseed = 0;
 // Holds the INITIAL seed value.  Used for demos, possibly other debugging.
 static UINT32 initialseed = 0;
 
-/**
-  * Provides a random fixed point number.
+/** Provides a random fixed point number.
   * This is a variant of an xorshift PRNG; state fits in a 32 bit integer structure.
   *
   * \return A random fixed point number from [0,1).
@@ -96,62 +98,45 @@ ATTRINLINE static fixed_t FUNCINLINE __internal_prng__(void)
 	return (randomseed&((FRACUNIT-1)<<9))>>9;
 }
 
-/** Provides a random integer from 0 to 255.
-  * Distribution is uniform.
-  * If you're curious, (&0xFF00) >> 8 gives the same result
-  * as a fixed point multiplication by 256.
+/** Provides a random fixed point number. Distribution is uniform.
+  * Literally a wrapper for the internal PRNG function.
   *
-  * \return Random integer from [0, 255].
-  * \sa __internal_prng__
+  * \return A random fixed point number from [0,1).
   */
 #ifndef DEBUGRANDOM
-UINT8 P_Random(void)
+fixed_t P_RandomFixed(void)
 {
 #else
-UINT8 P_RandomD(const char *rfile, INT32 rline)
+UINT8 P_RandomFixedD(const char *rfile, INT32 rline)
 {
-	CONS_Printf("P_Random() at: %sp %d\n", rfile, rline);
+	CONS_Printf("P_RandomFixed() at: %sp %d\n", rfile, rline);
 #endif
-	return (UINT8)((__internal_prng__()&0xFF00)>>8);
+	return __internal_prng__();
 }
 
-/** Provides a random integer from -128 to 127.
-  * Distribution is uniform.
+/** Provides a random byte. Distribution is uniform.
+  * If you're curious, (&0xFF00) >> 8 gives the same result
+  * as a fixed point multiplication by 256.
   *
-  * \return Random integer from [-128, 127].
+  * \return Random integer from [0, 255].
   * \sa __internal_prng__
   */
 #ifndef DEBUGRANDOM
-INT32 P_SignedRandom(void)
-{
-#else
-INT32 P_SignedRandomD(const char *rfile, INT32 rline)
-{
-	CONS_Printf("P_SignedRandom() at: %sp %d\n", rfile, rline);
-#endif
-	return (INT32)((__internal_prng__()&0xFF00)>>8) - 128;
-}
-
-/**
-  * Provides a random fixed point number.
-  * Literally a wrapper for the internal PRNG function.
-  *
-  * \return A random fixed point number from [0,1).
-  */
-#ifndef DEBUGRANDOM
-fixed_t P_RandomFixed(void)
+UINT8 P_RandomByte(void)
 {
 #else
-UINT8 P_RandomFixedD(const char *rfile, INT32 rline)
+UINT8 P_RandomByteD(const char *rfile, INT32 rline)
 {
-	CONS_Printf("P_Random() at: %sp %d\n", rfile, rline);
+	CONS_Printf("P_RandomByte() at: %sp %d\n", rfile, rline);
 #endif
-	return __internal_prng__();
+	return (UINT8)((__internal_prng__()&0xFF00)>>8);
 }
 
 /** Provides a random integer for picking random elements from an array.
   * Distribution is uniform.
+  * NOTE: Maximum range is 65536.
   *
+  * \param a Number of items in array.
   * \return A random integer from [0,a).
   * \sa __internal_prng__
   */
@@ -168,8 +153,11 @@ INT32 P_RandomKeyD(const char *rfile, INT32 rline, INT32 a)
 
 /** Provides a random integer in a given range.
   * Distribution is uniform.
+  * NOTE: Maximum range is 65536.
   *
-  * \return A random integer from [a,b].P_Random
+  * \param a Lower bound.
+  * \param b Upper bound.
+  * \return A random integer from [a,b].
   * \sa __internal_prng__
   */
 #ifndef DEBUGRANDOM
diff --git a/src/m_random.h b/src/m_random.h
index 91348365b06458d10a6f24770eb0f707305c2efe..90784a5d0d0decbd9d24923d63b19d0537f9d154 100644
--- a/src/m_random.h
+++ b/src/m_random.h
@@ -25,30 +25,36 @@
 // P_Random functions pulls random bytes from a PRNG that is network synced.
 
 // RNG functions
-UINT8 M_Random(void);
-INT32 M_SignedRandom(void);
-INT32 M_RandomKey(INT32 a);
-INT32 M_RandomRange(INT32 a, INT32 b);
+fixed_t M_RandomFixed(void);
+UINT8   M_RandomByte(void);
+INT32   M_RandomKey(INT32 a);
+INT32   M_RandomRange(INT32 a, INT32 b);
 
 // PRNG functions
 #ifdef DEBUGRANDOM
-#define P_Random()          P_RandomD(__FILE__, __LINE__)
-#define P_SignedRandom()    P_SignedRandomD(__FILE__, __LINE__)
 #define P_RandomFixed()     P_RandomFixedD(__FILE__, __LINE__)
+#define P_RandomByte()      P_RandomByteD(__FILE__, __LINE__)
 #define P_RandomKey(c)      P_RandomKeyD(__FILE__, __LINE__, c)
 #define P_RandomRange(c, d) P_RandomRangeD(__FILE__, __LINE__, c, d)
-UINT8 P_RandomD(const char *rfile, INT32 rline);
-INT32 P_SignedRandomD(const char *rfile, INT32 rline);
 fixed_t P_RandomFixedD(const char *rfile, INT32 rline);
-INT32 P_RandomKeyD(const char *rfile, INT32 rline, INT32 a);
-INT32 P_RandomRangeD(const char *rfile, INT32 rline, INT32 a, INT32 b);
+UINT8   P_RandomByteD(const char *rfile, INT32 rline);
+INT32   P_RandomKeyD(const char *rfile, INT32 rline, INT32 a);
+INT32   P_RandomRangeD(const char *rfile, INT32 rline, INT32 a, INT32 b);
 #else
-UINT8 P_Random(void);
-INT32 P_SignedRandom(void);
 fixed_t P_RandomFixed(void);
-INT32 P_RandomKey(INT32 a);
-INT32 P_RandomRange(INT32 a, INT32 b);
+UINT8   P_RandomByte(void);
+INT32   P_RandomKey(INT32 a);
+INT32   P_RandomRange(INT32 a, INT32 b);
 #endif
+
+// Macros for other functions
+#define M_SignedRandom()  ((INT32)M_RandomByte() - 128) // [-128, 127] signed byte, originally a
+#define P_SignedRandom()  ((INT32)P_RandomByte() - 128) // function of its own, moved to a macro
+
+#define M_RandomChance(p) (M_RandomFixed() < p) // given fixed point probability, p, between 0 (0%)
+#define P_RandomChance(p) (P_RandomFixed() < p) // and FRACUNIT (100%), returns true p% of the time
+
+// Debugging
 fixed_t P_RandomPeek(void);
 
 // Working with the seed for PRNG
diff --git a/src/p_enemy.c b/src/p_enemy.c
index 367d5714a4b50b66511a53c7fb4015a1ad294acc..b8737810cfae250c4a1845498638e879cd83a621 100644
--- a/src/p_enemy.c
+++ b/src/p_enemy.c
@@ -386,7 +386,7 @@ boolean P_CheckMissileRange(mobj_t *actor)
 	if (actor->type == MT_EGGMOBILE && dist > 160)
 		dist = 160;
 
-	if (P_Random() < dist)
+	if (P_RandomByte() < dist)
 		return false;
 
 	return true;
@@ -486,7 +486,7 @@ static boolean P_TryWalk(mobj_t *actor)
 {
 	if (!P_Move(actor, actor->info->speed))
 		return false;
-	actor->movecount = P_Random() & 15;
+	actor->movecount = P_RandomByte() & 15;
 	return true;
 }
 
@@ -539,7 +539,7 @@ void P_NewChaseDir(mobj_t *actor)
 	}
 
 	// try other directions
-	if (P_Random() > 200 || abs(deltay) > abs(deltax))
+	if (P_RandomChance(25*FRACUNIT/32) || abs(deltay) > abs(deltax))
 	{
 		tdir = d[1];
 		d[1] = d[2];
@@ -577,7 +577,7 @@ void P_NewChaseDir(mobj_t *actor)
 	}
 
 	// randomly determine direction of search
-	if (P_Random() & 1)
+	if (P_RandomChance(FRACUNIT/2))
 	{
 		for (tdir = DI_EAST; tdir <= DI_SOUTHEAST; tdir++)
 		{
@@ -632,7 +632,7 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed
 
 	// BP: first time init, this allow minimum lastlook changes
 	if (actor->lastlook < 0)
-		actor->lastlook = P_Random();
+		actor->lastlook = P_RandomByte();
 
 	actor->lastlook %= MAXPLAYERS;
 
@@ -707,7 +707,7 @@ static boolean P_LookForShield(mobj_t *actor)
 
 	// BP: first time init, this allow minimum lastlook changes
 	if (actor->lastlook < 0)
-		actor->lastlook = P_Random();
+		actor->lastlook = P_RandomByte();
 
 	actor->lastlook %= MAXPLAYERS;
 
@@ -2293,12 +2293,7 @@ void A_SkullAttack(mobj_t *actor)
 	if (locvar1 == 1)
 		actor->angle += ANGLE_180;
 	else if (locvar1 == 2)
-	{
-		if (P_Random() & 1)
-			actor->angle += ANGLE_90;
-		else
-			actor->angle -= ANGLE_90;
-	}
+		actor->angle += (P_RandomChance(FRACUNIT/2)) ? ANGLE_90 : -ANGLE_90;
 
 	an = actor->angle >> ANGLETOFINESHIFT;
 
@@ -2398,9 +2393,9 @@ void A_BossScream(mobj_t *actor)
 		explodetype = (mobjtype_t)locvar2;
 
 	if (actor->eflags & MFE_VERTICALFLIP)
-		z = actor->z + actor->height - mobjinfo[explodetype].height - FixedMul((P_Random()<<(FRACBITS-2)) - 8*FRACUNIT, actor->scale);
+		z = actor->z + actor->height - mobjinfo[explodetype].height - FixedMul((P_RandomByte()<<(FRACBITS-2)) - 8*FRACUNIT, actor->scale);
 	else
-		z = actor->z + FixedMul((P_Random()<<(FRACBITS-2)) - 8*FRACUNIT, actor->scale);
+		z = actor->z + FixedMul((P_RandomByte()<<(FRACBITS-2)) - 8*FRACUNIT, actor->scale);
 
 	mo = P_SpawnMobj(x, y, z, explodetype);
 	if (actor->eflags & MFE_VERTICALFLIP)
@@ -3461,7 +3456,7 @@ void A_BubbleSpawn(mobj_t *actor)
 			return; // don't make bubble!
 	}
 
-	prandom = P_Random();
+	prandom = P_RandomByte();
 
 	if (leveltime % (3*TICRATE) < 8)
 		bubble = P_SpawnMobj(actor->x, actor->y, actor->z + (actor->height / 2), MT_EXTRALARGEBUBBLE);
@@ -3509,7 +3504,7 @@ void A_FanBubbleSpawn(mobj_t *actor)
 			return; // don't make bubble!
 	}
 
-	prandom = P_Random();
+	prandom = P_RandomByte();
 
 	if ((prandom & 0x7) == 0x7)
 		bubble = P_SpawnMobj(actor->x, actor->y, hz, MT_SMALLBUBBLE);
@@ -3550,7 +3545,7 @@ void A_BubbleRise(mobj_t *actor)
 		// Move around slightly to make it look like it's bending around the water
 		if (!locvar1)
 		{
-			UINT8 prandom = P_Random();
+			UINT8 prandom = P_RandomByte();
 			if (!(prandom & 0x7)) // *****000
 			{
 				P_InstaThrust(actor, prandom & 0x70 ? actor->angle + ANGLE_90 : actor->angle,
@@ -3833,7 +3828,7 @@ void A_ThrownRing(mobj_t *actor)
 
 	// first time init, this allow minimum lastlook changes
 	if (actor->lastlook < 0)
-		actor->lastlook = P_Random();
+		actor->lastlook = P_RandomByte();
 
 	actor->lastlook %= MAXPLAYERS;
 
@@ -3913,7 +3908,7 @@ void A_SetSolidSteam(mobj_t *actor)
 #endif
 	actor->flags &= ~MF_NOCLIP;
 	actor->flags |= MF_SOLID;
-	if (!(P_Random() & 7))
+	if (P_RandomChance(FRACUNIT/8))
 	{
 		if (actor->info->deathsound)
 			S_StartSound(actor, actor->info->deathsound); // Hiss!
@@ -4055,7 +4050,7 @@ void A_JetChase(mobj_t *actor)
 	if (actor->reactiontime)
 		actor->reactiontime--;
 
-	if (P_Random() % 32 == 1)
+	if (P_RandomChance(FRACUNIT/32))
 	{
 		actor->momx = actor->momx / 2;
 		actor->momy = actor->momy / 2;
@@ -4416,7 +4411,7 @@ void A_JetgThink(mobj_t *actor)
 
 	if (actor->target)
 	{
-		if (P_Random() <= 32 && !actor->reactiontime)
+		if (P_RandomChance(FRACUNIT/8) && !actor->reactiontime)
 			P_SetMobjState(actor, actor->info->missilestate);
 		else
 			A_JetChase (actor);
@@ -4469,10 +4464,10 @@ void A_MouseThink(mobj_t *actor)
 	{
 		if (twodlevel || actor->flags2 & MF2_TWOD)
 		{
-			if (P_Random() & 1)
+			if (P_RandomChance(FRACUNIT/2))
 				actor->angle += ANGLE_180;
 		}
-		else if (P_Random() & 1)
+		else if (P_RandomChance(FRACUNIT/2))
 			actor->angle += ANGLE_90;
 		else
 			actor->angle -= ANGLE_90;
@@ -4878,7 +4873,7 @@ void A_RockSpawn(mobj_t *actor)
 	type = MT_ROCKCRUMBLE1 + (sides[line->sidenum[0]].rowoffset >> FRACBITS);
 
 	if (line->flags & ML_NOCLIMB)
-		randomoomph = P_Random() * (FRACUNIT/32);
+		randomoomph = P_RandomByte() * (FRACUNIT/32);
 	else
 		randomoomph = 0;
 
@@ -5172,7 +5167,7 @@ void A_CrawlaCommanderThink(mobj_t *actor)
 
 	if (locvar1)
 	{
-		if (actor->health < 2 && P_Random() < 2)
+		if (actor->health < 2 && P_RandomChance(FRACUNIT/128))
 			P_SpawnMissile(actor, actor->target, locvar1);
 	}
 
@@ -5187,8 +5182,8 @@ void A_CrawlaCommanderThink(mobj_t *actor)
 		actor->threshold = 0;
 
 		// Roam around, somewhat in the player's direction.
-		actor->angle += (P_Random()<<10);
-		actor->angle -= (P_Random()<<10);
+		actor->angle += (P_RandomByte()<<10);
+		actor->angle -= (P_RandomByte()<<10);
 
 		if (actor->health > 1)
 			P_InstaThrust(actor, actor->angle, FixedMul(10*FRACUNIT, actor->scale));
@@ -5204,7 +5199,7 @@ void A_CrawlaCommanderThink(mobj_t *actor)
 				actor->threshold = 1;
 			}
 		}
-		actor->reactiontime = 2*TICRATE + P_Random()/2;
+		actor->reactiontime = 2*TICRATE + P_RandomByte()/2;
 	}
 
 	if (actor->health == 1)
@@ -5222,8 +5217,8 @@ void A_CrawlaCommanderThink(mobj_t *actor)
 		}
 		else
 		{
-			UINT8 prandom = P_Random();
-			actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) + (P_Random() & 1 ? -prandom : +prandom);
+			UINT8 prandom = P_RandomByte();
+			actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) + (P_RandomChance(FRACUNIT/2) ? -prandom : +prandom);
 			P_InstaThrust(actor, actor->angle, FixedDiv(FixedMul(locvar2, actor->scale), 3*FRACUNIT/2));
 			actor->momz = FixedMul(locvar2, actor->scale); // Bounce up in air
 		}
@@ -5552,7 +5547,7 @@ void A_MixUp(mobj_t *actor)
 		{
 			if (counter > 255) // fail-safe to avoid endless loop
 				break;
-			prandom = P_Random();
+			prandom = P_RandomByte();
 			prandom %= numplayers; // I love modular arithmetic, don't you?
 			if (prandom) // Make sure it's not a useless mix
 				break;
@@ -5701,7 +5696,7 @@ void A_RecyclePowers(mobj_t *actor)
 	{
 		UINT8 tempint;
 
-		i = j + ((P_Random() + leveltime) % (numplayers - j));
+		i = j + ((P_RandomByte() + leveltime) % (numplayers - j));
 		tempint = postscramble[j];
 		postscramble[j] = postscramble[i];
 		postscramble[i] = tempint;
@@ -5814,7 +5809,7 @@ void A_Boss1Chase(mobj_t *actor)
 	{
 		if (actor->health > actor->info->damage)
 		{
-			if (P_Random() & 1)
+			if (P_RandomChance(FRACUNIT/2))
 				P_SetMobjState(actor, actor->info->missilestate);
 			else
 				P_SetMobjState(actor, actor->info->meleestate);
@@ -5833,7 +5828,7 @@ void A_Boss1Chase(mobj_t *actor)
 	// ?
 nomissile:
 	// possibly choose another target
-	if (multiplayer && P_Random() < 2)
+	if (multiplayer && P_RandomChance(FRACUNIT/128))
 	{
 		if (P_LookForPlayers(actor, true, false, 0))
 			return; // got a new target
@@ -5871,7 +5866,7 @@ nomissile:
 		deltay = actor->target->y - actor->y;
 
 		actor->movedir = diags[((deltay < 0)<<1) + (deltax > 0)];
-		actor->movecount = P_Random() & 15;
+		actor->movecount = P_RandomByte() & 15;
 	}
 }
 
@@ -5897,13 +5892,13 @@ void A_Boss2Chase(mobj_t *actor)
 
 	// Startup randomness
 	if (actor->reactiontime <= -666)
-		actor->reactiontime = 2*TICRATE + P_Random();
+		actor->reactiontime = 2*TICRATE + P_RandomByte();
 
 	// When reactiontime hits zero, he will go the other way
 	if (--actor->reactiontime <= 0)
 	{
 		reverse = true;
-		actor->reactiontime = 2*TICRATE + P_Random();
+		actor->reactiontime = 2*TICRATE + P_RandomByte();
 	}
 
 	P_SetTarget(&actor->target, P_GetClosestAxis(actor));
@@ -5990,12 +5985,12 @@ void A_Boss2Chase(mobj_t *actor)
 			if (actor->info->attacksound)
 				S_StartAttackSound(actor, actor->info->attacksound);
 
-			if (P_Random() & 1)
+			if (P_RandomChance(FRACUNIT/2))
 			{
 				goop->momx *= 2;
 				goop->momy *= 2;
 			}
-			else if (P_Random() > 128)
+			else if (P_RandomChance(129*FRACUNIT/256))
 			{
 				goop->momx *= 3;
 				goop->momy *= 3;
@@ -6153,7 +6148,7 @@ void A_Boss7Chase(mobj_t *actor)
 	{
 		A_FaceTarget(actor);
 		P_SetMobjState(actor, S_BLACKEGG_SHOOT1);
-		actor->movecount = TICRATE + P_Random()/2;
+		actor->movecount = TICRATE + P_RandomByte()/2;
 		return;
 	}
 
@@ -6162,7 +6157,7 @@ void A_Boss7Chase(mobj_t *actor)
 
 	if (actor->reactiontime <= 0 && actor->z == actor->floorz)
 	{
-		// Here, we'll call P_Random() and decide what kind of attack to do
+		// Here, we'll call P_RandomByte() and decide what kind of attack to do
 		switch(actor->threshold)
 		{
 			case 0: // Lob cannon balls
@@ -6170,7 +6165,7 @@ void A_Boss7Chase(mobj_t *actor)
 				{
 					A_FaceTarget(actor);
 					P_SetMobjState(actor, actor->info->xdeathstate);
-					actor->movecount = 7*TICRATE + P_Random();
+					actor->movecount = 7*TICRATE + P_RandomByte();
 					break;
 				}
 				actor->threshold++;
@@ -6180,9 +6175,9 @@ void A_Boss7Chase(mobj_t *actor)
 				P_SetMobjState(actor, S_BLACKEGG_SHOOT1);
 
 				if (actor->health > actor->info->damage)
-					actor->movecount = TICRATE + P_Random()/3;
+					actor->movecount = TICRATE + P_RandomByte()/3;
 				else
-					actor->movecount = TICRATE + P_Random()/2;
+					actor->movecount = TICRATE + P_RandomByte()/2;
 				break;
 			case 2: // Homing Missile
 				A_FaceTarget(actor);
@@ -6266,8 +6261,8 @@ void A_Boss2PogoSFX(mobj_t *actor)
 	}
 	else
 	{
-		UINT8 prandom = P_Random();
-		actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) + (P_Random() & 1 ? -prandom : +prandom);
+		UINT8 prandom = P_RandomByte();
+		actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) + (P_RandomChance(FRACUNIT/2) ? -prandom : +prandom);
 		P_InstaThrust(actor, actor->angle, FixedMul(FixedMul(actor->info->speed,(locvar2)), actor->scale));
 	}
 	if (actor->info->activesound) S_StartSound(actor, actor->info->activesound);
@@ -6307,10 +6302,10 @@ void A_Boss2PogoTarget(mobj_t *actor)
 	// Target hit, retreat!
 	if (actor->target->player->powers[pw_flashing] > TICRATE || actor->flags2 & MF2_FRET)
 	{
-		UINT8 prandom = P_Random();
+		UINT8 prandom = P_RandomByte();
 		actor->z++; // unstick from the floor
 		actor->momz = FixedMul(locvar1, actor->scale); // Bounce up in air
-		actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) + (P_Random() & 1 ? -prandom : +prandom); // Pick a direction, and randomize it.
+		actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) + (P_RandomChance(FRACUNIT/2) ? -prandom : +prandom); // Pick a direction, and randomize it.
 		P_InstaThrust(actor, actor->angle+ANGLE_180, FixedMul(FixedMul(actor->info->speed,(locvar2)), actor->scale)); // Move at wandering speed
 	}
 	// Try to land on top of the player.
@@ -6347,10 +6342,10 @@ void A_Boss2PogoTarget(mobj_t *actor)
 	// Wander semi-randomly towards the player to get closer.
 	else
 	{
-		UINT8 prandom = P_Random();
+		UINT8 prandom = P_RandomByte();
 		actor->z++; // unstick from the floor
 		actor->momz = FixedMul(locvar1, actor->scale); // Bounce up in air
-		actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) + (P_Random() & 1 ? -prandom : +prandom); // Pick a direction, and randomize it.
+		actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) + (P_RandomChance(FRACUNIT/2) ? -prandom : +prandom); // Pick a direction, and randomize it.
 		P_InstaThrust(actor, actor->angle, FixedMul(FixedMul(actor->info->speed,(locvar2)), actor->scale)); // Move at wandering speed
 	}
 	// Boing!
@@ -7084,7 +7079,7 @@ void A_SmokeTrailer(mobj_t *actor)
 	P_SetObjectMomZ(th, FRACUNIT, false);
 	th->destscale = actor->scale;
 	P_SetScale(th, actor->scale);
-	th->tics -= P_Random() & 3;
+	th->tics -= P_RandomByte() & 3;
 	if (th->tics < 1)
 		th->tics = 1;
 }
@@ -7183,7 +7178,7 @@ void A_ChangeAngleRelative(mobj_t *actor)
 	//  rather than the ranges, so <0 and >360 work as possible values. -Red
 	INT32 locvar1 = var1;
 	INT32 locvar2 = var2;
-	//angle_t angle = (P_Random()+1)<<24;
+	//angle_t angle = (P_RandomByte()+1)<<24;
 	const fixed_t amin = locvar1*FRACUNIT;
 	const fixed_t amax = locvar2*FRACUNIT;
 	//const angle_t amin = FixedAngle(locvar1*FRACUNIT);
@@ -7217,7 +7212,7 @@ void A_ChangeAngleAbsolute(mobj_t *actor)
 {
 	INT32 locvar1 = var1;
 	INT32 locvar2 = var2;
-	//angle_t angle = (P_Random()+1)<<24;
+	//angle_t angle = (P_RandomByte()+1)<<24;
 	const fixed_t amin = locvar1*FRACUNIT;
 	const fixed_t amax = locvar2*FRACUNIT;
 	//const angle_t amin = FixedAngle(locvar1*FRACUNIT);
@@ -7825,7 +7820,7 @@ void A_RandomState(mobj_t *actor)
 		return;
 #endif
 
-	P_SetMobjState(actor, P_Random()&1 ? locvar1 : locvar2);
+	P_SetMobjState(actor, P_RandomChance(FRACUNIT/2) ? locvar1 : locvar2);
 }
 
 // Function: A_RandomStateRange
@@ -8516,34 +8511,29 @@ void A_SearchForPlayers(mobj_t *actor)
 
 // Function: A_CheckRandom
 //
-// Description: Calls a state by chance (around 1/var1).
+// Description: Calls a state by chance.
 //
-// var1 = denominator (can't exceed 100)
+// var1:
+//		lower 16 bits = denominator
+//		upper 16 bits = numerator (defaults to 1 if zero)
 // var2 = state number
 //
 void A_CheckRandom(mobj_t *actor)
 {
 	INT32 locvar1 = var1;
 	INT32 locvar2 = var2;
-	INT32 i, chance;
-	INT32 rndadd = 0;
+	fixed_t chance = FRACUNIT;
+
 #ifdef HAVE_BLUA
 	if (LUA_CallAction("A_CheckRandom", actor))
 		return;
 #endif
+	// The PRNG doesn't suck anymore, OK?
+	if (locvar1 >> 16)
+		chance *= (locvar1 >> 16);
+	chance /= (locvar1 & 0xFFFF);
 
-	if(locvar1 > 100)
-		locvar1 = 100;
-
-	for (i = 0; i < MAXPLAYERS; i++)
-		if (playeringame[i])
-			rndadd += abs((int)players[i].mo->x) + abs((int)players[i].mo->y) + abs((int)players[i].mo->z);
-
-	rndadd = rndadd % 10000; //additional component to enlarge random number
-
-	chance = (P_Random() + rndadd) % locvar1;
-
-	if (chance == 0)
+	if (P_RandomChance(chance))
 		P_SetMobjState(actor, locvar2);
 }
 
@@ -9890,7 +9880,7 @@ void A_BrakChase(mobj_t *actor)
 		S_StartSound(actor, (sfxenum_t)locvar2);
 
 	// make active sound
-	if (actor->type != MT_CYBRAKDEMON && actor->info->activesound && P_Random() < 3)
+	if (actor->type != MT_CYBRAKDEMON && actor->info->activesound && P_RandomChance(3*FRACUNIT/256))
 	{
 		S_StartSound(actor, actor->info->activesound);
 	}
diff --git a/src/p_inter.c b/src/p_inter.c
index b8101f12b1561f97c88e64bebd30ce99e215c189..128b507218308a6a9c5dcd134368a7aed133df91 100644
--- a/src/p_inter.c
+++ b/src/p_inter.c
@@ -1236,7 +1236,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
 
 				if (special->target && special->target->state == &states[S_BLACKEGG_SHOOT1])
 				{
-					if (special->target->health <= 2 && (P_Random() & 1))
+					if (special->target->health <= 2 && P_RandomChance(FRACUNIT/2))
 						P_SetMobjState(special->target, special->target->info->missilestate);
 					else
 						P_SetMobjState(special->target, special->target->info->raisestate);
@@ -2186,29 +2186,17 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
 
 				default:
 					if (target->info->doomednum)
+						prandom = target->info->doomednum%5; // "Random" animal for new enemies.
+					else
+						prandom = P_RandomKey(5); // No placable object, just use a random number.
+
+					switch(prandom)
 					{
-						switch(target->info->doomednum%5)
-						{
 						default: item = MT_BUNNY; break;
 						case 1: item = MT_BIRD; break;
 						case 2: item = MT_MOUSE; break;
 						case 3: item = MT_COW; break;
 						case 4: item = MT_CHICKEN; break;
-						}
-					}
-					else
-					{
-						prandom = P_Random();
-						if (prandom < 51)
-							item = MT_BUNNY;
-						else if (prandom < 102)
-							item = MT_BIRD;
-						else if (prandom < 153)
-							item = MT_MOUSE;
-						else if (prandom < 204)
-							item = MT_COW;
-						else
-							item = MT_CHICKEN;
 					}
 					break;
 			}
@@ -3086,7 +3074,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
 
 	// Killing dead. Just for kicks.
 	// Require source and inflictor be player.  Don't hurt for firing rings.
-	if (cv_killingdead.value && (source && source->player) && (inflictor && inflictor->player) && P_Random() < 80)
+	if (cv_killingdead.value && (source && source->player) && (inflictor && inflictor->player) && P_RandomChance(5*FRACUNIT/16))
 		P_DamageMobj(source, target, target, 1);
 
 	// do the damage
@@ -3600,7 +3588,7 @@ void P_PlayerFlagBurst(player_t *player, boolean toss)
 		P_InstaThrust(flag, player->mo->angle, FixedMul(6*FRACUNIT, player->mo->scale));
 	else
 	{
-		angle_t fa = P_Random()*FINEANGLES/256;
+		angle_t fa = P_RandomByte()*FINEANGLES/256;
 		flag->momx = FixedMul(FINECOSINE(fa), FixedMul(6*FRACUNIT, player->mo->scale));
 		if (!(twodlevel || (player->mo->flags2 & MF2_TWOD)))
 			flag->momy = FixedMul(FINESINE(fa), FixedMul(6*FRACUNIT, player->mo->scale));
diff --git a/src/p_lights.c b/src/p_lights.c
index 2dfe006dc1f1d2b4884d884b9c3701d645f76a1a..a9758c723307cd92edc82bfcd73e17ab76396915 100644
--- a/src/p_lights.c
+++ b/src/p_lights.c
@@ -51,7 +51,7 @@ void T_FireFlicker(fireflicker_t *flick)
 	if (--flick->count)
 		return;
 
-	amount = (INT16)((UINT8)(P_Random() & 3) * 16);
+	amount = (INT16)((UINT8)(P_RandomByte() & 3) * 16);
 
 	if (flick->sector->lightlevel - amount < flick->minlight)
 		flick->sector->lightlevel = (INT16)flick->minlight;
@@ -235,7 +235,7 @@ strobe_t *P_SpawnAdjustableStrobeFlash(sector_t *minsector, sector_t *maxsector,
 		flash->minlight = 0;
 
 	if (!inSync)
-		flash->count = (P_Random() & 7) + 1;
+		flash->count = (P_RandomByte() & 7) + 1;
 	else
 		flash->count = 1;
 
diff --git a/src/p_mobj.c b/src/p_mobj.c
index 4e60ad6121c83f92aebe9508a6d40b09965fa60c..150af1e080a78bd2918230fb7f4861c5da9c0884 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -652,9 +652,9 @@ void P_EmeraldManager(void)
 				break;
 
 			if (leveltime < TICRATE) // Start of map
-				spawnpoints[j]->threshold = 60*TICRATE + P_Random() * (TICRATE/5);
+				spawnpoints[j]->threshold = 60*TICRATE + P_RandomByte() * (TICRATE/5);
 			else
-				spawnpoints[j]->threshold = P_Random() * (TICRATE/5);
+				spawnpoints[j]->threshold = P_RandomByte() * (TICRATE/5);
 
 			break;
 		}
@@ -683,26 +683,26 @@ void P_ExplodeMissile(mobj_t *mo)
 		explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE);
 		P_SetScale(explodemo, mo->scale);
 		explodemo->destscale = mo->destscale;
-		explodemo->momx += (P_Random() % 32) * FixedMul(FRACUNIT/8, explodemo->scale);
-		explodemo->momy += (P_Random() % 32) * FixedMul(FRACUNIT/8, explodemo->scale);
+		explodemo->momx += (P_RandomByte() % 32) * FixedMul(FRACUNIT/8, explodemo->scale);
+		explodemo->momy += (P_RandomByte() % 32) * FixedMul(FRACUNIT/8, explodemo->scale);
 		S_StartSound(explodemo, sfx_pop);
 		explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE);
 		P_SetScale(explodemo, mo->scale);
 		explodemo->destscale = mo->destscale;
-		explodemo->momx += (P_Random() % 64) * FixedMul(FRACUNIT/8, explodemo->scale);
-		explodemo->momy -= (P_Random() % 64) * FixedMul(FRACUNIT/8, explodemo->scale);
+		explodemo->momx += (P_RandomByte() % 64) * FixedMul(FRACUNIT/8, explodemo->scale);
+		explodemo->momy -= (P_RandomByte() % 64) * FixedMul(FRACUNIT/8, explodemo->scale);
 		S_StartSound(explodemo, sfx_dmpain);
 		explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE);
 		P_SetScale(explodemo, mo->scale);
 		explodemo->destscale = mo->destscale;
-		explodemo->momx -= (P_Random() % 128) * FixedMul(FRACUNIT/8, explodemo->scale);
-		explodemo->momy += (P_Random() % 128) * FixedMul(FRACUNIT/8, explodemo->scale);
+		explodemo->momx -= (P_RandomByte() % 128) * FixedMul(FRACUNIT/8, explodemo->scale);
+		explodemo->momy += (P_RandomByte() % 128) * FixedMul(FRACUNIT/8, explodemo->scale);
 		S_StartSound(explodemo, sfx_pop);
 		explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE);
 		P_SetScale(explodemo, mo->scale);
 		explodemo->destscale = mo->destscale;
-		explodemo->momx -= (P_Random() % 96) * FixedMul(FRACUNIT/8, explodemo->scale);
-		explodemo->momy -= (P_Random() % 96) * FixedMul(FRACUNIT/8, explodemo->scale);
+		explodemo->momx -= (P_RandomByte() % 96) * FixedMul(FRACUNIT/8, explodemo->scale);
+		explodemo->momy -= (P_RandomByte() % 96) * FixedMul(FRACUNIT/8, explodemo->scale);
 		S_StartSound(explodemo, sfx_cybdth);
 
 		// Hack: Release an animal.
@@ -2405,12 +2405,12 @@ static boolean P_ZMovement(mobj_t *mo)
 							// If deafed, give the tumbleweed another random kick if it runs out of steam.
 							mom.z += P_MobjFlip(mo)*FixedMul(6*FRACUNIT, mo->scale);
 
-							if (P_Random() & 1)
+							if (P_RandomChance(FRACUNIT/2))
 								mom.x += FixedMul(6*FRACUNIT, mo->scale);
 							else
 								mom.x -= FixedMul(6*FRACUNIT, mo->scale);
 
-							if (P_Random() & 1)
+							if (P_RandomChance(FRACUNIT/2))
 								mom.y += FixedMul(6*FRACUNIT, mo->scale);
 							else
 								mom.y -= FixedMul(6*FRACUNIT, mo->scale);
@@ -2886,7 +2886,7 @@ static boolean P_SceneryZMovement(mobj_t *mo)
 
 				for (i = 0; i < 4; ++i) // split into four
 				{
-					prandom = P_Random();
+					prandom = P_RandomByte();
 					explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_SMALLBUBBLE);
 					explodemo->momx += ((prandom & 0x0F) << (FRACBITS-2)) * (i & 2 ? -1 : 1);
 					explodemo->momy += ((prandom & 0xF0) << (FRACBITS-6)) * (i & 1 ? -1 : 1);
@@ -3218,13 +3218,13 @@ void P_MobjCheckWater(mobj_t *mobj)
 			// Create tons of bubbles
 			for (i = 0; i < bubblecount; i++)
 			{
-				// P_Random()s are called individually to allow consistency
+				// P_RandomByte()s are called individually to allow consistency
 				// across various compilers, since the order of function calls
 				// in C is not part of the ANSI specification.
-				prandom[0] = P_Random();
-				prandom[1] = P_Random();
-				prandom[2] = P_Random();
-				prandom[3] = P_Random();
+				prandom[0] = P_RandomByte();
+				prandom[1] = P_RandomByte();
+				prandom[2] = P_RandomByte();
+				prandom[3] = P_RandomByte();
 
 				bubbletype = MT_SMALLBUBBLE;
 				if (!(prandom[0] & 0x3)) // medium bubble chance up to 64 from 32
@@ -3826,7 +3826,7 @@ boolean P_BossTargetPlayer(mobj_t *actor, boolean closest)
 
 	// first time init, this allow minimum lastlook changes
 	if (actor->lastlook < 0)
-		actor->lastlook = P_Random();
+		actor->lastlook = P_RandomByte();
 	actor->lastlook &= PLAYERSMASK;
 
 	for( ; ; actor->lastlook = (actor->lastlook+1) & PLAYERSMASK)
@@ -4707,7 +4707,7 @@ static void P_Boss7Thinker(mobj_t *mobj)
 
 	if (mobj->state == &states[S_BLACKEGG_STND] && mobj->tics == mobj->state->tics)
 	{
-		mobj->reactiontime += P_Random();
+		mobj->reactiontime += P_RandomByte();
 
 		if (mobj->health <= mobj->info->damage)
 			mobj->reactiontime /= 4;
@@ -4901,7 +4901,7 @@ static void P_Boss7Thinker(mobj_t *mobj)
 		if (mobj->tracer && mobj->tracer->type == MT_BOSS3WAYPOINT
 			&& mobj->tracer->spawnpoint && (mobj->tracer->spawnpoint->options & 7) == waypointNum)
 		{
-			if (P_Random() & 1)
+			if (P_RandomChance(FRACUNIT/2))
 				waypointNum++;
 			else
 				waypointNum--;
@@ -4913,7 +4913,7 @@ static void P_Boss7Thinker(mobj_t *mobj)
 		}
 
 		if (waypointNum == 0 && mobj->health <= mobj->info->damage)
-			waypointNum = 1 + (P_Random() & 1);
+			waypointNum = 1 + (P_RandomFixed() & 1);
 
 		// scan the thinkers to find
 		// the waypoint to use
@@ -5013,7 +5013,7 @@ static void P_Boss7Thinker(mobj_t *mobj)
 		P_SetMobjState(mobj, mobj->info->spawnstate);
 	}
 	else if (mobj->state == &states[mobj->info->deathstate] && mobj->tics == mobj->state->tics)
-		S_StartSound(0, sfx_bedie1 + (P_Random() & 1));
+		S_StartSound(0, sfx_bedie1 + (P_RandomFixed() & 1));
 
 }
 
@@ -5440,7 +5440,7 @@ static void P_Boss9Thinker(mobj_t *mobj)
 				// An incoming attack is detected! What should we do?!
 				// Go into vector form!
 				mobj->movedir = ANGLE_11hh - FixedAngle(FixedMul(AngleFixed(ANGLE_11hh), FixedDiv((mobj->info->spawnhealth - mobj->health)<<FRACBITS, (mobj->info->spawnhealth-1)<<FRACBITS)));
-				if (P_Random()&1)
+				if (P_RandomChance(FRACUNIT/2))
 					mobj->movedir = InvAngle(mobj->movedir);
 				mobj->threshold = 6 + (FixedMul(24<<FRACBITS, FixedDiv((mobj->info->spawnhealth - mobj->health)<<FRACBITS, (mobj->info->spawnhealth-1)<<FRACBITS))>>FRACBITS);
 				if (mobj->info->activesound)
@@ -6042,20 +6042,20 @@ static void P_KoopaThinker(mobj_t *koopa)
 
 	P_XYMovement(koopa);
 
-	if (P_Random() < 8 && koopa->z <= koopa->floorz)
+	if (P_RandomChance(FRACUNIT/32) && koopa->z <= koopa->floorz)
 		koopa->momz = FixedMul(5*FRACUNIT, koopa->scale);
 
 	if (koopa->z > koopa->floorz)
 		koopa->momz += FixedMul(FRACUNIT/4, koopa->scale);
 
-	if (P_Random() < 4)
+	if (P_RandomChance(FRACUNIT/64))
 	{
 		mobj_t *flame;
-		flame = P_SpawnMobj(koopa->x - koopa->radius + FixedMul(5*FRACUNIT, koopa->scale), koopa->y, koopa->z + (P_Random()<<(FRACBITS-2)), MT_KOOPAFLAME);
+		flame = P_SpawnMobj(koopa->x - koopa->radius + FixedMul(5*FRACUNIT, koopa->scale), koopa->y, koopa->z + (P_RandomByte()<<(FRACBITS-2)), MT_KOOPAFLAME);
 		flame->momx = -FixedMul(flame->info->speed, flame->scale);
 		S_StartSound(flame, sfx_koopfr);
 	}
-	else if (P_Random() > 250)
+	else if (P_RandomChance(5*FRACUNIT/256))
 	{
 		mobj_t *hammer;
 		hammer = P_SpawnMobj(koopa->x - koopa->radius, koopa->y, koopa->z + koopa->height, MT_HAMMER);
@@ -6499,11 +6499,11 @@ void P_MobjThinker(mobj_t *mobj)
 				fixed_t ns;
 				mobj_t *mo2;
 
-				i = P_Random();
-				z = mobj->subsector->sector->floorheight + ((P_Random()&63)*FRACUNIT);
+				i = P_RandomByte();
+				z = mobj->subsector->sector->floorheight + ((P_RandomByte()&63)*FRACUNIT);
 				for (j = 0; j < 2; j++)
 				{
-					const angle_t fa = (P_Random()*FINEANGLES/16) & FINEMASK;
+					const angle_t fa = (P_RandomByte()*FINEANGLES/16) & FINEMASK;
 					ns = 64 * FRACUNIT;
 					x = mobj->x + FixedMul(FINESINE(fa),ns);
 					y = mobj->y + FixedMul(FINECOSINE(fa),ns);
@@ -6513,7 +6513,7 @@ void P_MobjThinker(mobj_t *mobj)
 					mo2->momx = FixedMul(FINESINE(fa),ns);
 					mo2->momy = FixedMul(FINECOSINE(fa),ns);
 
-					i = P_Random();
+					i = P_RandomByte();
 
 					if (i % 5 == 0)
 						P_SpawnMobj(x, y, z, MT_CHICKEN);
@@ -7997,7 +7997,7 @@ void P_SpawnPrecipitation(void)
 					continue;
 
 				rainmo = P_SpawnSnowMobj(x, y, height, MT_SNOWFLAKE);
-				mrand = M_Random();
+				mrand = M_RandomByte();
 				if (mrand < 64)
 					P_SetPrecipMobjState(rainmo, S_SNOW3);
 				else if (mrand < 144)
@@ -9166,12 +9166,12 @@ ML_NOCLIMB : Direction not controllable
 		{
 			mobj->momz += FixedMul(16*FRACUNIT, mobj->scale);
 
-			if (P_Random() & 1)
+			if (P_RandomChance(FRACUNIT/2))
 				mobj->momx += FixedMul(16*FRACUNIT, mobj->scale);
 			else
 				mobj->momx -= FixedMul(16*FRACUNIT, mobj->scale);
 
-			if (P_Random() & 1)
+			if (P_RandomChance(FRACUNIT/2))
 				mobj->momy += FixedMul(16*FRACUNIT, mobj->scale);
 			else
 				mobj->momy -= FixedMul(16*FRACUNIT,mobj->scale);
diff --git a/src/p_spec.c b/src/p_spec.c
index 277fe19eb3616cc4da0f5f5a567fb75372272425..415e1be0135aeb7337614a35425d20ebadca6cab 100644
--- a/src/p_spec.c
+++ b/src/p_spec.c
@@ -2057,7 +2057,7 @@ void P_SwitchWeather(INT32 weathernum)
 				precipmobj = (precipmobj_t *)think;
 
 				precipmobj->flags = mobjinfo[MT_SNOWFLAKE].flags;
-				z = M_Random();
+				z = M_RandomByte();
 
 				if (z < 64)
 					z = 2;
diff --git a/src/p_tick.c b/src/p_tick.c
index c72ab5b6730053222bbd796462546241c5288826..d45f5882115e3e04308deee7b13aa44726673d54 100644
--- a/src/p_tick.c
+++ b/src/p_tick.c
@@ -363,7 +363,7 @@ static void P_DoAutobalanceTeams(void)
 	{
 		if (totalred > totalblue)
 		{
-			i = M_Random() % red;
+			i = M_RandomKey(red);
 			NetPacket.packet.newteam = 2;
 			NetPacket.packet.playernum = redarray[i];
 			NetPacket.packet.verification = true;
@@ -375,7 +375,7 @@ static void P_DoAutobalanceTeams(void)
 
 		if (totalblue > totalred)
 		{
-			i = M_Random() % blue;
+			i = M_RandomKey(blue);
 			NetPacket.packet.newteam = 1;
 			NetPacket.packet.playernum = bluearray[i];
 			NetPacket.packet.verification = true;
diff --git a/src/p_user.c b/src/p_user.c
index 03b2c1dd87a7a39a8a291277133db86eba4f34c2..380ac98047bbdf270239af02dd5434f6d3faaeb5 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -2172,9 +2172,9 @@ static void P_DoBubbleBreath(player_t *player)
 	if (!(player->mo->eflags & MFE_UNDERWATER) || ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL && !(player->pflags & PF_NIGHTSMODE)) || player->spectator)
 		return;
 
-	if (!(P_Random() % 16))
+	if (P_RandomChance(FRACUNIT/16))
 		bubble = P_SpawnMobj(player->mo->x, player->mo->y, zh, MT_SMALLBUBBLE);
-	else if (!(P_Random() % 96))
+	else if (P_RandomChance(3*FRACUNIT/256))
 		bubble = P_SpawnMobj(player->mo->x, player->mo->y, zh, MT_MEDIUMBUBBLE);
 	if (bubble)
 	{
@@ -6620,7 +6620,7 @@ static void P_MovePlayer(player_t *player)
 	// Little water sound while touching water - just a nicety.
 	if ((player->mo->eflags & MFE_TOUCHWATER) && !(player->mo->eflags & MFE_UNDERWATER) && !player->spectator)
 	{
-		if (P_Random() & 1 && leveltime % TICRATE == 0)
+		if (P_RandomChance(FRACUNIT/2) && leveltime % TICRATE == 0)
 			S_StartSound(player->mo, sfx_floush);
 	}
 
@@ -8423,7 +8423,7 @@ static boolean P_SpectatorJoinGame(player_t *player)
 		else if (redscore > bluescore)
 			changeto = 2;
 		else
-			changeto = (P_Random() & 1) + 1;
+			changeto = (P_RandomFixed() & 1) + 1;
 
 		if (player->mo)
 		{
@@ -8674,7 +8674,7 @@ void P_PlayerThink(player_t *player)
 
 	// Add some extra randomization.
 	if (cmd->forwardmove)
-		P_Random();
+		P_RandomFixed();
 
 #ifdef PARANOIA
 	if (player->playerstate == PST_REBORN)
diff --git a/src/v_video.c b/src/v_video.c
index df81ac6d62283304b42f7ba4b722c7bcaf2af19b..02c67a24e1698d77a739d3107e5880cd4b019fbf 100644
--- a/src/v_video.c
+++ b/src/v_video.c
@@ -1967,7 +1967,7 @@ Unoptimized version
 
 			for (y = 0; y < height; y++)
 			{
-				if (M_Random() < 32)
+				if (M_RandomChance(FRACUNIT/8)) // 12.5%
 					heatshifter[y] = true;
 			}