Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

PRNGs for GameMaker

Custom pseudorandom number generators for GameMaker! · By YellowAfterlife

Great PRNG asset

A topic by JesterOC created Mar 03, 2025 Views: 103 Replies: 1
Viewing posts 1 to 2

Niice.. have yet to check it out.. 

I already have Xorshift 32bit prng in GML.. do you know if it'd be faster than 64bit Xorshift? I chose Xorshift 32bit prng a while ago cus i needed to solve cross-platform random seed inconsistencies.. which Xorshift on Android and PC generated the same results.. others i tried didn't.

Developer (1 edit) (+1)

Good question!

I tried quickly adding it as that’s largely the same code as the 64-bit one, and turns out that it’s hardly faster:

And for some reason it is slower if you put the whole PRNG in a macro:

I was expecting it to be slightly faster since you don’t have to do the ordeal with manually shifting the sign bit, but I didn’t notice that you have to do & $FFFFFFFF after both << operations to simulate a 32-bit register.

If you are using Julian’s implementation of 32-bit Xorshift specifically, you’ll want to update to the latest commit because Julian didn’t previously notice this either.

Either way, I included it in the test project, but I see little reason to use the 32-bit version over the 64-bit one.


Another thing to consider with PRNGs (or other relatively small functions) is the way you implement them.

Putting the whole thing in a macro that you use instead of a function call is the fastest and global scripts with global variables are faster than method calls on constructors, but having methods call other methods also costs! So

function Xorshift32(_state) constructor {
	state = _state;
	static value = function() {
		state ^= (state << 13) & $FFFFFFFF;
		state ^= (state >> 17);
		state ^= (state << 5) & $FFFFFFFF;
		return state / 4294967296.0;
	}
	static float = function(_max) {
		return value() * _max;
	}
}

will be slower than

function Xorshift32(_state) constructor {
	state = _state;
	...
	static float = function(_max) {
		state ^= (state << 13) & $FFFFFFFF;
		state ^= (state >> 17);
		state ^= (state << 5) & $FFFFFFFF;
		return state / 4294967296.0 * _max;
	}
}

In my code I deal with this by auto-generating the scripts from Haxe source code (and have the Haxe compiler inline everything so that no function goes more than one call deep)