{"id":192,"date":"2017-08-21T13:21:52","date_gmt":"2017-08-21T05:21:52","guid":{"rendered":"http:\/\/49.232.131.197\/?p=192"},"modified":"2017-08-21T13:21:52","modified_gmt":"2017-08-21T05:21:52","slug":"math-for-game-programmers-noise-based-rng","status":"publish","type":"post","link":"http:\/\/www.sourcecool.com\/index.php\/2017\/08\/21\/math-for-game-programmers-noise-based-rng\/","title":{"rendered":"Math for Game Programmers &#8211; Noise Based RNG"},"content":{"rendered":"<p>Squirrel Eiserloh presented strong evidence for using noise functions in place of more traditional RNGs. Random number generators typically are forward-only mutating algorithms; they can&#8217;t be threaded easily, can&#8217;t be rewound or skipped forward efficiently, and may have expensive seed or copy operations. Noise functions are stateless and so solve most of those issues. The most eye-opening bit of the talk were a set of benchmarks and tests showing that noise can outperform even well-regarded RNGs like Mersenne Twister by orders of magnitude,\u00a0<em>and<\/em>\u00a0these fast noise functions can produce a higher quality of randomness! Plus an RNG can be built from a noise function just by adding a generation value, which itself can be used from multiple threads safely via atomic increments, so a noise-based RNG is a very compelling option for game devs.<\/p>\n<p>It all seems obvious in retrospect, but Squirrel&#8217;s talk made a case that perhaps really needed to be made.<\/p>\n<pre class=\"lang:python decode:true \"># ~!~ coding: utf-8 ~!~\r\n\"\"\"\r\n   squirrel3\r\n   ~~~~~~~~~\r\n   Provides a noise function which is fast and had good distribution.  It was\r\n   introduced by Squirrel Eiserloh at 'Math for Game Programmers: Noise-based\r\n   RNG', GDC17.\r\n   :copyright: (c) 2017 by Heungsub Lee.\r\n   :license: BSD, see LICENSE for more details.\r\n\"\"\"\r\nimport random\r\n\r\n\r\n__all__ = ['squirrel3', 'Squirrel3Random']\r\n\r\n\r\n# The base bit-noise constants were crafted to have distinctive and interesting\r\n# bits, and have so far produced excellent experimental test results.\r\nNOISE1 = 0xb5297a4d  # 0b0110'1000'1110'0011'0001'1101'1010'0100\r\nNOISE2 = 0x68e31da4  # 0b1011'0101'0010'1001'0111'1010'0100'1101\r\nNOISE3 = 0x1b56c4e9  # 0b0001'1011'0101'0110'1100'0100'1110'1001\r\n\r\nCAP = 1 &lt;&lt; 32\r\n\r\n\r\ndef squirrel3(n, seed=0):\r\n    \"\"\"Returns an unsigned integer containing 32 reasonably-well-scrambled\r\n    bits, based on a given (signed) integer input parameter `n` and optional\r\n    `seed`.  Kind of like looking up a value in an infinitely large\r\n    non-existent table of previously generated random numbers.\r\n    \"\"\"\r\n    n *= NOISE1\r\n    n += seed\r\n    n ^= n &gt;&gt; 8\r\n    n += NOISE2\r\n    n ^= n &lt;&lt; 8\r\n    n *= NOISE3\r\n    n ^= n &gt;&gt; 8\r\n    # Cast into uint32 like the original `Squirrel3`.\r\n    return n % CAP\r\n\r\n\r\nclass Squirrel3Random(random.Random):\r\n\r\n    _n = 0\r\n\r\n    def seed(self, a=None):\r\n        if a is None:\r\n            a = 0\r\n        self._seed = a\r\n\r\n    def random(self):\r\n        n = self._n\r\n        self._n += 1\r\n        return squirrel3(n, self._seed) \/ float(CAP)<\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Squirrel Eiserl&hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"_links":{"self":[{"href":"http:\/\/www.sourcecool.com\/index.php\/wp-json\/wp\/v2\/posts\/192"}],"collection":[{"href":"http:\/\/www.sourcecool.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.sourcecool.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.sourcecool.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.sourcecool.com\/index.php\/wp-json\/wp\/v2\/comments?post=192"}],"version-history":[{"count":1,"href":"http:\/\/www.sourcecool.com\/index.php\/wp-json\/wp\/v2\/posts\/192\/revisions"}],"predecessor-version":[{"id":193,"href":"http:\/\/www.sourcecool.com\/index.php\/wp-json\/wp\/v2\/posts\/192\/revisions\/193"}],"wp:attachment":[{"href":"http:\/\/www.sourcecool.com\/index.php\/wp-json\/wp\/v2\/media?parent=192"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.sourcecool.com\/index.php\/wp-json\/wp\/v2\/categories?post=192"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.sourcecool.com\/index.php\/wp-json\/wp\/v2\/tags?post=192"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}