<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>BitFlip Games</title>
	<atom:link href="http://bitflipgames.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://bitflipgames.com</link>
	<description>Making great games one bit at a time.</description>
	<lastBuildDate>Wed, 09 May 2012 22:51:06 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>May Alpha Update Released!</title>
		<link>http://bitflipgames.com/2012/05/03/may-alpha-update-released/</link>
		<comments>http://bitflipgames.com/2012/05/03/may-alpha-update-released/#comments</comments>
		<pubDate>Thu, 03 May 2012 20:58:52 +0000</pubDate>
		<dc:creator>dave</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://bitflipgames.com/?p=620</guid>
		<description><![CDATA[The May update of the Minion Master Alpha has gone live. Here&#8217;s a roundup of the coverage on our release. Inide RPGs. Gamezebo. Indiegamemag. Gaming Nexus.]]></description>
			<content:encoded><![CDATA[<p>The May update of the Minion Master Alpha has gone live. Here&#8217;s a roundup of the coverage on our release.</p>
<p><a href="http://indierpgs.com/2012/05/minion-master-available-for-pre-order/">Inide RPGs</a>.</p>
<p><a href="http://www.gamezebo.com/games/minion-master/preview">Gamezebo</a>.</p>
<p><a href="http://www.indiegamemag.com/mmmm-minion-master-may-alpha-update-released/">Indiegamemag</a>.</p>
<p><a href="http://www.gamingnexus.com/">Gaming Nexus</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://bitflipgames.com/2012/05/03/may-alpha-update-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Minion Master Alpha Update #4</title>
		<link>http://bitflipgames.com/2012/04/30/minion-master-alpha-update-4/</link>
		<comments>http://bitflipgames.com/2012/04/30/minion-master-alpha-update-4/#comments</comments>
		<pubDate>Mon, 30 Apr 2012 20:22:52 +0000</pubDate>
		<dc:creator>dave</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://bitflipgames.com/?p=616</guid>
		<description><![CDATA[Exciting news in this week&#8217;s update, we&#8217;ve added Teleport!]]></description>
			<content:encoded><![CDATA[<p>Exciting news in this week&#8217;s update, we&#8217;ve added Teleport!</p>
<p><iframe width="500" height="281" src="http://www.youtube.com/embed/eRDqoM-CVXA?fs=1&#038;feature=oembed" frameborder="0" allowfullscreen></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://bitflipgames.com/2012/04/30/minion-master-alpha-update-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Minion Master Alpha Update 3</title>
		<link>http://bitflipgames.com/2012/04/25/minion-master-alpha-update-3/</link>
		<comments>http://bitflipgames.com/2012/04/25/minion-master-alpha-update-3/#comments</comments>
		<pubDate>Wed, 25 Apr 2012 21:52:57 +0000</pubDate>
		<dc:creator>dave</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://bitflipgames.com/?p=613</guid>
		<description><![CDATA[Here are the latest updates made this week in Minion Master. We&#8217;ve got new levels, some small bug fixes, and and a revamp of the Pegasus!]]></description>
			<content:encoded><![CDATA[<p>Here are the latest updates made this week in Minion Master. We&#8217;ve got new levels, some small bug fixes, and and a revamp of the Pegasus!</p>
<p><iframe width="500" height="281" src="http://www.youtube.com/embed/TWIsNzovPck?fs=1&#038;feature=oembed" frameborder="0" allowfullscreen></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://bitflipgames.com/2012/04/25/minion-master-alpha-update-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Minion Master Alpha Update Video 2</title>
		<link>http://bitflipgames.com/2012/04/16/minion-master-alpha-update-video-2/</link>
		<comments>http://bitflipgames.com/2012/04/16/minion-master-alpha-update-video-2/#comments</comments>
		<pubDate>Tue, 17 Apr 2012 01:59:15 +0000</pubDate>
		<dc:creator>dave</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://bitflipgames.com/?p=584</guid>
		<description><![CDATA[The latest Minion Master Alpha Update video. This one explores movement cost for differing tile types and climbing in elevation.]]></description>
			<content:encoded><![CDATA[<p>The latest Minion Master Alpha Update video. This one explores movement cost for differing tile types and climbing in elevation.</p>
<p><iframe width="476" height="268" src="http://www.youtube.com/embed/vLVk8ND6gls" frameborder="0" allowfullscreen></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://bitflipgames.com/2012/04/16/minion-master-alpha-update-video-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GDC Here We Come!</title>
		<link>http://bitflipgames.com/2012/02/29/gdc-here-we-come/</link>
		<comments>http://bitflipgames.com/2012/02/29/gdc-here-we-come/#comments</comments>
		<pubDate>Thu, 01 Mar 2012 01:17:56 +0000</pubDate>
		<dc:creator>dave</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[GDC]]></category>
		<category><![CDATA[Indie]]></category>
		<category><![CDATA[Minion Master]]></category>

		<guid isPermaLink="false">http://bitflipgames.com/?p=585</guid>
		<description><![CDATA[The crew over here at BitFlip has been hard at work the last few months. So hard, in fact, that our website has languished. However, exciting times are brewing. Next week, we&#8217;ll be introducing our flagship title, Minion Master, to the world at the 2012 Game Developers Conference. Minion Master will be showcased at the [...]]]></description>
			<content:encoded><![CDATA[<p><a rel="attachment wp-att-386" href="http://bitflipgames.com/games/logo_no_background/"><img class="alignleft size-medium wp-image-386" title="logo_no_background" src="http://minionmaster.com/images/mm_logo.png" alt="" width="215" height="248" /></a>The crew over here at BitFlip has been hard at work the last few months. So hard, in fact, that our website has languished. However, exciting times are brewing. Next week, we&#8217;ll be introducing our flagship title, Minion Master, to the world at the 2012 Game Developers Conference. Minion Master will be showcased at the GDC Play Expo, a 3 day function within the conference to showcase upcoming Indie titles. We&#8217;ll be showing Minion Master Tuesday through Thursday, March 6-8, from 10am to 5pm in the Esplanade Ballroom in Moscone Center. We&#8217;ll be at Kiosk #22.</p>
<p>In the meantime, you can check out the <a href="http://www.minionmaster.com/">Minion Master </a>website for more information about the game!</p>
]]></content:encoded>
			<wfw:commentRss>http://bitflipgames.com/2012/02/29/gdc-here-we-come/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Explorations on Random Numbers, Part 4</title>
		<link>http://bitflipgames.com/2011/08/02/explorations-on-random-numbers-part-4/</link>
		<comments>http://bitflipgames.com/2011/08/02/explorations-on-random-numbers-part-4/#comments</comments>
		<pubDate>Tue, 02 Aug 2011 17:01:07 +0000</pubDate>
		<dc:creator>guy</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://bitflipgames.com/?p=495</guid>
		<description><![CDATA[Astute readers will notice that the sample code in the previous post passes in a constant value as the seed to the random number generator. What would happen if we tried passing in the current time? Obviously, that would completely prevent the optimization we saw last time that just calculates the result, since the compiler [...]]]></description>
			<content:encoded><![CDATA[<p>Astute readers will notice that the sample code in the previous post passes in a constant value as the seed to the random number generator.  What would happen if we tried passing in the current time?  Obviously, that would completely prevent the optimization we saw last time that just calculates the result, since the compiler won&#8217;t know ahead of time what time you&#8217;re running your program.  So, let&#8217;s compile this code down:</p>
<pre class="brush:c++">int main()
{
	RAND tRand;
	RandInit(tRand, time(NULL));

	unsigned int nRandom = RandGetNum(tRand);
	printf("%u\n", nRandom);

	return 0;
}
</pre>
<p>This is the code that the compiler generates for RandGetNum() in x86:</p>
<pre class="brush:text">; Comments added by me
; For reference: v = 36969 * (v &amp; 0xFFFFFFFF) + (v &gt;&gt; 32);
; edx:eax contains v
0137101B  imul        eax,eax,9069h  ; Multiply low part of V by 36969
01371021  add         edx,eax        ; Add multiplied low part and high part
</pre>
<p>Holy crap!  That&#8217;s just TWO instructions for the whole thing!  That&#8217;s even better than the 64-bit version!  Speaking of which, what does that look like now?</p>
<pre class="brush:text">; Comments added by me
; For reference: v = 36969 * (v &amp; 0xFFFFFFFF) + (v &gt;&gt; 32);
; rax contains v
000000013F881024  mov         rdx,rax        ; Copy v into rdx
000000013F881027  shr         rdx,20h        ; Set rdx to the high part of v
000000013F88102B  imul        eax,eax,9069h  ; Multiply the low part of v by 36969
000000013F881031  add         edx,eax        ; Add multiplied low part to high part of v
</pre>
<p>Hmmm&#8230;  That hasn&#8217;t changed much at all from the looped version we saw earlier.  In fact, it&#8217;s exactly the same set of operations: move, shift, multiply, add.  Something interesting does come out of this, though, and that is that the 32-bit code and the last two instructions in the 64-bit code are identical, which means that the preceding two instructions in the 64-bit code are just &#8220;ceremony&#8221;.  That is, they&#8217;re getting the right data into the right registers for the later operations to &#8220;just work.&#8221;  In the 32-bit code, the high and low parts are already split up by definition, since the only way to operate on a 64-bit register using 32-bit instructions is to split it up into two 32-bit registers.  In the 64-bit code, there is an easy way to get the lower 32-bits of a register (rax is a 64-bit extension of eax in the same way that eax is a 32-bit extension of ax), but no built-in way to get the upper 32-bits other than copying the value and shifting it right.</p>
<p>Ultimately, we have to trust that the compiler has some understanding of what the code is doing, and how to translate that into efficient and correct machine code.  It can be surprising, though, just exactly how much understanding the compiler has about what&#8217;s going on and what the best way to organize the code is.  The whole point of these last two posts has been to delve into what the compiler is actually doing (don&#8217;t be afraid of the disassembly window!).</p>
<p>Your code is going to be running on a real computer, and having an understanding of what the computer is actually doing and how the code is executed is part of what makes a great programmer.  It can be interesting, educational, and fun to see what code the compiler is generating.</p>
]]></content:encoded>
			<wfw:commentRss>http://bitflipgames.com/2011/08/02/explorations-on-random-numbers-part-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Explorations on Random Numbers, Part 2.5</title>
		<link>http://bitflipgames.com/2011/07/28/explorations-on-random-numbers-part-2-5/</link>
		<comments>http://bitflipgames.com/2011/07/28/explorations-on-random-numbers-part-2-5/#comments</comments>
		<pubDate>Fri, 29 Jul 2011 00:59:48 +0000</pubDate>
		<dc:creator>guy</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://bitflipgames.com/?p=487</guid>
		<description><![CDATA[Before we delve into the nitty-gritty details of how the compiler optimizes our MWC RNG, I&#8217;d like to present our full code from the GSDEngine (modified slightly for public consumption). All of this code is released into the public domain. Here&#8217;s a C-style version (but still compiled with C++ compiler): // This is based off [...]]]></description>
			<content:encoded><![CDATA[<p>Before we delve into the nitty-gritty details of how the compiler optimizes our MWC RNG, I&#8217;d like to present our full code from the GSDEngine (modified slightly for public consumption).  All of this code is released into the public domain.</p>
<p>Here&#8217;s a C-style version (but still compiled with C++ compiler):</p>
<pre class="brush:c++">// This is based off of George Marsaglia's post to Sci.Stat.Math
// http://www.bobwheeler.com/statistics/Password/MarsagliaPost.txt
// This is the Multiply With Carry random number generator, modified
// to use a single 64-bit seed to create a 32-bit RNG, rather than
// gluing together two 16-bit RNGs (and thus two seeds)

// Default V value is the conglomeration of the default Z and W values from the Marsaglia MWC RNG
#define DEFAULT_V_VALUE 0x159A55E51F123BB5

struct RAND
{
	unsigned long long v;
};

inline void RandInit(RAND&amp; tRand, unsigned long long seed)
{
	if(seed == 0)
		seed = DEFAULT_V_VALUE;

	tRand.v = seed;
}

// Gets a number in the range [0, UINT_MAX]
inline unsigned int RandGetNum(RAND&amp; tRand)
{
	tRand.v = 36969 * (tRand.v &amp; 0xFFFFFFFF) + (tRand.v &gt;&gt; 32);
	return tRand.v &amp; 0xFFFFFFFF;
}

// Gets a random number in the range [0, Max) (that is, from 0 to Max-1)
inline unsigned int RandGetNum(RAND&amp; tRand, unsigned int nMax)
{
	return nMax ? RandGetNum(tRand) % nMax : RandGetNum(tRand);
}

// Gets a random number in the range [Min, Max]
// You will get weird results if Min is greater than Max
inline int RandGetNum(RAND&amp; tRand, int nMin, int nMax)
{
	return RandGetNum(tRand, (nMax - nMin + 1)) + nMin;
}

// Returns a floating point number in the range [0,1]
inline float RandGetFloat(RAND&amp; tRand)
{
	const float fInverse = 1.0f / (float)0xFFFFFFFF;
	return RandGetNum(tRand) * fInverse;
}</pre>
<p>Or, if you prefer C++:</p>
<pre class="brush:c++">// This is based off of George Marsaglia's post to Sci.Stat.Math
// http://www.bobwheeler.com/statistics/Password/MarsagliaPost.txt
// This is the Multiply With Carry random number generator, modified
// to use a single 64-bit seed to create a 32-bit RNG, rather than
// gluing together two 16-bit RNGs (and thus two seeds)

// Default V value is the conglomeration of the default Z and W values from the Marsaglia MWC RNG
#define DEFAULT_V_VALUE 0x159A55E51F123BB5

class RandomNumberGenerator
{
private:
	unsigned long long v;

public:
	RandomNumberGenerator(unsigned long long seed = 0)
	{
		if(seed == 0)
			seed = DEFAULT_V_VALUE;

		v = seed;
	}

	// Gets a number in the range [0, UINT_MAX]
	unsigned int GetNum()
	{
		v = 36969 * (v &amp; 0xFFFFFFFF) + (v &gt;&gt; 32);
		return v &amp; 0xFFFFFFFF;
	}

	// Gets a random number in the range [0, Max) (that is, from 0 to Max-1)
	unsigned int GetNum(unsigned int nMax)
	{
		return nMax ? GetNum() % nMax : GetNum();
	}

	// Gets a random number in the range [Min, Max]
	// You will get weird results if Min is greater than Max
	int GetNum(int nMin, int nMax)
	{
		return GetNum((nMax - nMin + 1)) + nMin;
	}

	// Returns a floating point number in the range [0,1]
	float GetFloat()
	{
		const float fInverse = 1.0f / (float)0xFFFFFFFF;
		return GetNum() * fInverse;
	}

	// Gets a random number in the range [0, Max) (that is, from 0 to Max-1)
	unsigned int operator ()(unsigned int nMax = 0)
	{
		return nMax ? GetNum(nMax) : GetNum();
	}
};</pre>
<p>Let&#8217;s write some code to use this RNG:</p>
<pre class="brush:c++">int main()
{
	RAND tRand;
	RandInit(tRand, 0);

	unsigned int nRandom = RandGetNum(tRand);
	printf("%u\n", nRandom);

	return 0;
}</pre>
<p>Or, with the C++ class:</p>
<pre class="brush:c++">int main()
{
	RandomNumberGenerator tRand;

	unsigned int nRandom = tRand.GetNum();
	printf("%u\n", nRandom);

	return 0;
}</pre>
<p>Next time, we&#8217;ll really delve into compiler optimizations, I promise!</p>
]]></content:encoded>
			<wfw:commentRss>http://bitflipgames.com/2011/07/28/explorations-on-random-numbers-part-2-5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Explorations on Random Numbers, Part 3</title>
		<link>http://bitflipgames.com/2011/07/25/explorations-on-random-numbers-part-3/</link>
		<comments>http://bitflipgames.com/2011/07/25/explorations-on-random-numbers-part-3/#comments</comments>
		<pubDate>Mon, 25 Jul 2011 21:57:27 +0000</pubDate>
		<dc:creator>guy</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://bitflipgames.com/?p=491</guid>
		<description><![CDATA[The last few posts, we&#8217;ve explored various random number generators, and ended up with a very simple and solid implementation of George Marsaglia&#8217;s Multiply-With-Carry RNG. At this point, we&#8217;re done talking about random number generators. We&#8217;re going to switch gears and talk about how the compiler actually takes the RNG code and turns it into [...]]]></description>
			<content:encoded><![CDATA[<p>The last few posts, we&#8217;ve explored various random number generators, and ended up with a very simple and solid implementation of George Marsaglia&#8217;s Multiply-With-Carry RNG.  At this point, we&#8217;re done talking about random number generators.  We&#8217;re going to switch gears and talk about how the compiler actually takes the RNG code and turns it into machine code.</p>
<p>Warning: we will be delving into assembly language, so be prepared!</p>
<p>Let&#8217;s start with some very simple code that uses our MWC RNG:</p>
<pre class="brush:c++">int main()
{
	RAND tRand;
	RandInit(tRand, 0);

	unsigned int nRandom = RandGetNum(tRand);
	printf("%u\n", nRandom);

	return 0;
}</pre>
<p>Now, we&#8217;re interested in performance, so the question is: what sort of code does the compiler actually generate for this?  Obviously, debug mode is not going to be very interesting for performance, so let&#8217;s compile in x86 Release mode and see what the compiler comes up with:</p>
<pre class="brush:text">int main()
{
	RAND tRand;
	RandInit(tRand, 0);

	unsigned int nRandom = RandGetNum(tRand);
	printf("%u\n", nRandom);
00D11000  push        15AAA322h
00D11005  push        offset string "%u\n" (0D120F4h)
00D1100A  call        dword ptr [__imp__printf (0D120A0h)]
00D11010  add         esp,8
	return 0;
00D11013  xor         eax,eax
}</pre>
<p>Wait a minute.  What?  Let&#8217;s translate that assembly language back into C code:</p>
<pre class="brush:c++">printf("%u\n", 0x15AAA322);</pre>
<p>Wow, the compiler has completely optimized away the call to RandGetNum().  It has calculated what the output of the formula would be, and just replaced the result.  What happens if we try it twice:</p>
<pre class="brush:c++">int main()
{
	RAND tRand;
	RandInit(tRand, 0);

	unsigned int nRandom = RandGetNum(tRand);
	nRandom = RandGetNum(tRand);
	printf("%u\n", nRandom);
	return 0;
}</pre>
<p>The compiler generates:</p>
<pre class="brush:text">01261000  push        0DEC01A79h
01261005  push        offset string "%u\n" (12620F4h)
0126100A  call        dword ptr [__imp__printf (12620A0h)]
01261010  add         esp,8
01261013  xor         eax,eax</pre>
<p>Practically the same thing, just with a different constant.  Let&#8217;s try a loop:</p>
<pre class="brush:c++">int main()
{
	RAND tRand;
	RandInit(tRand, 0);

	unsigned int nRandom;
	for(int i=0; i&lt;5; i++)
	{
		nRandom = RandGetNum(tRand);
	}
	printf("%u\n", nRandom);
	return 0;
}</pre>
<p>The compiler generates:</p>
<pre class="brush:text">011B1006  push        9722BEA6h
011B100B  push        offset string "%u\n" (11B20F4h)
011B1010  call        dword ptr [__imp__printf (11B20A0h)]
011B1016  add         esp,8
011B1019  xor         eax,eax</pre>
<p>The same thing!  Wow.  In fact, the Visual Studio compiler will follow the rabbit hole down as far as 10 times.  After that, it gives up and starts to generate code.  So, if we take i up to 11, then the compiler generates the following for the inside of the loop:</p>
<pre class="brush:text">; Comments added by me
; For reference: v = 36969 * (v &amp; 0xFFFFFFFF) + (v &gt;&gt; 32);
; ecx:eax contains v
01271017  mov         edx,9069h   ; Move 36969 into edx
0127101C  mul         eax,edx     ; eax contains the low part of V, so do the multiply
                                  ; and store the result in edx:eax
0127101E  xor         edi,edi     ; Clear edi
01271020  add         eax,ecx     ; Add the high part of V to the multiplied low part
                                  ; of V
01271022  adc         edx,edi     ; edi is 0, so this adds the carry flag from the
                                  ; eax+ecx operation to edx
01271024  dec         esi         ; decrement loop counter
01271025  mov         ecx,edx     ; Move edx (our temp register) into ecx (the high
                                  ; part of V)
01271027  jne         main+17h (1271017h)  ; loop</pre>
<p>Neat!  Excluding the loop instructions (dec/jne), our RNG boils down to six instructions in x86.  It&#8217;s worth noting that, although 64-bit operations are nontrivial in 32-bit assembly code, this algorithm is particularly well-suited for it, because it only operates on 32-bit pieces of the 64-bit number.</p>
<p>Of course, that&#8217;s really just a pleasant side-effect.  At its core, this really is a 64-bit operation, so let&#8217;s compile the same code for x64 and see what happens:</p>
<pre class="brush:text">; Comments added by me
; For reference: v = 36969 * (v &amp; 0xFFFFFFFF) + (v &gt;&gt; 32);
; rax contains v
000000013FB91020  mov         edx,eax         ; Move the low part of V into edx (and
                                              ; thus into rdx)
000000013FB91022  shr         rax,20h         ; Shift rax right 32, making rax contain
                                              ; the high part of V
000000013FB91026  imul        rdx,rdx,9069h   ; Multiply the low part of V by 36969
000000013FB9102D  add         rax,rdx         ; Add the multiplied low part to the
                                              ; high part
000000013FB91030  dec         r8              ; decrement loop counter
000000013FB91033  jne         main+20h (13FB91020h)  ; loop</pre>
<p>The 64-bit version is even cooler: just four instructions, each of which maps exactly to an operation in the formula.</p>
<p>If we ever had any doubt as to whether the MWC RNG is efficient, this definitely puts those doubts to rest.  We&#8217;ve also seen how the compiler can track down constant operations even across looping constructs.</p>
<p>Next time: It gets better</p>
]]></content:encoded>
			<wfw:commentRss>http://bitflipgames.com/2011/07/25/explorations-on-random-numbers-part-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Explorations on Random Numbers, Part 2</title>
		<link>http://bitflipgames.com/2011/07/21/explorations-on-random-numbers-part-2/</link>
		<comments>http://bitflipgames.com/2011/07/21/explorations-on-random-numbers-part-2/#comments</comments>
		<pubDate>Thu, 21 Jul 2011 17:48:56 +0000</pubDate>
		<dc:creator>guy</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://bitflipgames.com/?p=483</guid>
		<description><![CDATA[Last time, we saw how to use rand() and why rand() is unacceptable. We also took a look at the Mersenne Twister, which is definitely a huge improvement over rand(), but we were put off by its memory footprint of 2.5K. So, how can we do better than Mersenne Twister? Enter George Marsaglia, in a [...]]]></description>
			<content:encoded><![CDATA[<p>Last time, we saw how to use rand() and why rand() is unacceptable.  We also took a look at the Mersenne Twister, which is definitely a huge improvement over rand(), but we were put off by its memory footprint of 2.5K.  So, how can we do better than Mersenne Twister?</p>
<p>Enter George Marsaglia, in a <a href="http://www.bobwheeler.com/statistics/Password/MarsagliaPost.txt" target="_blank">posting to Sci.Stat.Math</a> on January 12th, 1999.  (Either that, or December 1st, 1999, depending on how Bob Wheeler writes his dates.)  In that post, he puts down 17 lines of code that implement 8 different RNGs.  That sounds really promising, at least as a starting point.  Let&#8217;s pick one of those and run with it and see where it takes us.</p>
<p>The RNG that we&#8217;re going to be using as our basis is Multiply With Carry (MWC).  Let&#8217;s isolate Marsaglia&#8217;s code for just the MWC RNG:</p>
<pre class="brush:c++">#define UL unsigned long
#define znew  ((z=36969*(z&amp;65535)+(z&gt;&gt;16))&lt;&lt;16)
#define wnew  ((w=18000*(w&amp;65535)+(w&gt;&gt;16))&amp;65535)
#define MWC   (znew+wnew)
static UL z=362436069, w=521288629;
void settable(UL i1, UL i2)
 { z=i1; w=i2; }</pre>
<p>Hrm.  The first obvious problem is that this RNG uses a static context.  Fortunately, it&#8217;s small and simple enough that we can fix that on our own by taking z and w and putting them into a struct or class.  But before we go down that rabbit hole, let&#8217;s examine what this code is actually doing:</p>
<p>We&#8217;ll start with the MWC macro.  MWC adds the newly-generated Z value to the newly-generated W value.  Fair enough.  What do those do?  The first thing you&#8217;ll notice is that there&#8217;s a pattern to the Z and W updates, so we&#8217;ll take apart the algorithm for the Z/W update:</p>
<ul>
<li>Split off the 32-bit value into two 16-bit values, which we&#8217;ll call L for low and H for high.</li>
<li>Multiply L by the constant C (36969 for Z and 18000 for W).</li>
<li>Add the result to H.  This is your new Z or W value.</li>
<li>Return the bottom 16 bits of the value.  For Z, shift them over into the high 16 bits of the return value.</li>
</ul>
<p>From this, we can determine that Z and W are 32-bit values, each of which represents a 16-bit RNG.  The MWC RNG generates its 32-bit value by combining the two 16-bit RNGs into a single value in the high and low words of the value.  Now that we understand that, what does it mean?  It means that we have to pick *good* values for our initial Z and W, because if we don&#8217;t, then we really only have 16 bits worth of randomness.</p>
<p>It kind of sucks to have to pick two seeds for an RNG.  Can we improve on that?  How can we take Marsaglia&#8217;s original MWC RNG and improve it by just requiring one seed?  Well, let&#8217;s look at what we determined about the Z and W values: each one is a 32-bit value that represents a 16-bit portion of the 32-bit RNG.  Maybe we can extend that concept by selecting a 64-bit value which represents a 32-bit RNG.  We&#8217;ll start by just updating Marsaglia&#8217;s code, then examine the process of making it practical for every-day use:</p>
<pre class="brush:c++">#define ULL unsigned long long
#define vnew  (v=36969*(v&amp;0xFFFFFFFF)+(v&gt;&gt;32))
#define MWC   (vnew&amp;0xFFFFFFFF)
static ULL v=0x159A55E51F123BB5; // 64-bit value compiled from original z and w as z&lt;&lt;32 + w
void settable(ULL i1)
 { v=i1; }</pre>
<p>Beautiful!  It&#8217;s tiny, it&#8217;s fast, it&#8217;s deterministic, it&#8217;s got decently long cycles&#8230;the only problem is the static context.  Fortunately, that one is easy to fix.  Let&#8217;s start by making a structure to hold the V value:</p>
<pre class="brush:c++">struct RAND
{
	unsigned long long v;
};</pre>
<p>Now a function to initialize it:</p>
<pre class="brush:c++">#define DEFAULT_V_VALUE 0x159A55E51F123BB5
inline void RandInit(RAND&amp; tRand, unsigned long long seed)
{
	if(seed == 0)
		seed = DEFAULT_V_VALUE;

	tRand.v = seed;
}</pre>
<p>And finally, a function to actually generate a random number:</p>
<pre class="brush:c++">inline unsigned int RandGetNum(RAND&amp; tRand)
{
	tRand.v = 36969 * (tRand.v &amp; 0xFFFFFFFF) + (tRand.v &gt;&gt; 32);
	return tRand.v &amp; 0xFFFFFFFF;
}</pre>
<p>So there you have it!  A small, fast, deterministic, long-cycled, non-static context RNG.</p>
<p>Next time: Exploring Compiler Optimizations</p>
]]></content:encoded>
			<wfw:commentRss>http://bitflipgames.com/2011/07/21/explorations-on-random-numbers-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Explorations on Random Numbers, Part 1</title>
		<link>http://bitflipgames.com/2011/07/14/explorations-on-random-numbers-part-1/</link>
		<comments>http://bitflipgames.com/2011/07/14/explorations-on-random-numbers-part-1/#comments</comments>
		<pubDate>Thu, 14 Jul 2011 18:03:23 +0000</pubDate>
		<dc:creator>guy</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://bitflipgames.com/?p=474</guid>
		<description><![CDATA[In C, since time immemorial, the easiest way of getting a random number is thus: #include &#60;stdio.h&#62; #include &#60;stdlib.h&#62; #include &#60;time.h&#62; int main() { srand(time(NULL)); int nRandom = rand(); printf("%d\n", nRandom); return 0; } Of course, this only gets you part of the way there. The problems with rand() are well-known and well-documented, but the [...]]]></description>
			<content:encoded><![CDATA[<p>In C, since time immemorial, the easiest way of getting a random number is thus:</p>
<pre class="brush:c++">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;time.h&gt;

int main()
{
    srand(time(NULL));
    int nRandom = rand();
    printf("%d\n", nRandom);
    return 0;
}</pre>
<p>Of course, this only gets you part of the way there.  The problems with rand() are well-known and well-documented, but the brief summary is:</p>
<ul>
<li>rand() only provides you with a random number up to RAND_MAX, which, on many compilers (including Visual Studio), is 0x7FFF.</li>
<li>rand() uses a static context.  That is, I cannot have two separate Random Number Generators (RNGs) running at the same time with different seeds.</li>
<li>Less interestingly for us, but still nonetheless true, rand() is not acceptable for use in cryptography situations</li>
</ul>
<p>I could go on and on, but this post isn&#8217;t about what&#8217;s wrong with rand().  rand() is just a starting point.  What we&#8217;re after is an RNG that is effective and efficient for use in games.  Specifically, we need it to have the following properties:</p>
<ul>
<li>It must be small (memory-wise)</li>
<li>It must be fast</li>
<li>It must be deterministic given the same seed</li>
<li>It must have a long enough cycle that any practical day-to-day use will not experience the cycles</li>
<li>It must have a non-static context</li>
</ul>
<p>Please note:</p>
<ul>
<li>If you need an RNG for cryptographic purposes, <strong>use a library that is cryptographically strong</strong>.  I repeat, <em>none of this subject matter applies to any security or cryptographic subject!</em></li>
</ul>
<p>The quote-unquote &#8220;standard&#8221; wisdom prevalent on the Internet is &#8220;<a href="http://forums.indiegamer.com/showthread.php?9460-Using-C-rand%28%29-isn-t-as-bad-as-previously-thought&amp;p=119219&amp;viewfull=1#post119219" target="_blank">Just use Mersenne Twister and be done with it.</a>&#8221;  Hmmm&#8230;  What is this &#8220;Mersenne Twister&#8221;?  <a href="http://en.wikipedia.org/wiki/Mersenne_twister" target="_blank">Wikipedia</a> to the rescue!  Wikipedia also has a link to the <a href="http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html" target="_blank">Mersenne Twister home page</a>.  So, let&#8217;s examine Mersenne Twister against the above requirements: it&#8217;s deterministic, long-cycled, and has a non-static context.  All good things.  The algorithm is simple and seems fast.  However, we&#8217;re not going to delve into the speed issue, because my eye is immediately drawn to the following line at the very beginning of the pseudocode presented in the Wikipedia page:</p>
<pre>// Create a length 624 array to store the state of the generator
int[0..623] MT
int index = 0</pre>
<p>In other words, the Mersenne Twister context uses up 2500 bytes!  That&#8217;s 2.5K for an RNG!  Granted, a very good one, but still&#8230;2.5K!  Surely we can do better than that.</p>
<p>Next time: how we can do better.</p>
]]></content:encoded>
			<wfw:commentRss>http://bitflipgames.com/2011/07/14/explorations-on-random-numbers-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

