<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Jonathan Blow&#39;s blog</title>
    <description>Hello.
</description>
    <link>https://number-none.com/blow/blog/</link>
    <atom:link href="https://number-none.com/blow/blog/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Tue, 19 Jul 2016 19:21:47 -0700</pubDate>
    <lastBuildDate>Tue, 19 Jul 2016 19:21:47 -0700</lastBuildDate>
    <generator>Jekyll v3.1.6</generator>
    
      <item>
        <title>Braid Cleanup (part 4)</title>
        <description>&lt;p&gt;I’ve changed a lot of files, and because this is a major change expected to break the game somewhat, I’m doing it in a new repository. I’ve been working on my laptop, so the next step is … download the new repository on my desktop machine and make sure everything compiles and runs and can upload a build to Steam.&lt;/p&gt;

&lt;p&gt;Except wait, we really should install Visual Studio 2015 Update 3 on this computer first. And we know that takes a long time…&lt;/p&gt;

&lt;p&gt;While that is happening, let’s dig out the Braid backup files. I am hoping that I have .bmp versions of all those .jpg files that I just converted back to .bmp (because the conversion to .jpg will have lost data). If I don’t, well, we can always go back to the .psd files, but there are some perils involved there that I will explain when we come to it. (These perils are one of the things that has been buzzing around at the back of my mind for years now, so it will be nice to have them solved).&lt;/p&gt;

&lt;p&gt;The Braid files have been backed up mostly on some random hard drive:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://number-none.com/blow/blog_videos/drive.jpg&quot; /&gt;&lt;/p&gt;

&lt;p&gt;When it comes to the source code and shipping assets, all that is on a server in a hosting facility and gets backed up regularly, so it’s very unlikely to be lost. But when it comes to the higher-resolution source assets, older historical files, and whatever, they only exist here (with the source images also on some DVDs that David Hellman burned that are now sitting in a storage crate in a warehouse).&lt;/p&gt;

&lt;p&gt;Recently, in the office, to back up really big files for The Witness, I set up a Synology backup server (recommended by Jeff Roberts and I am finding it to work quite well). We’ve got a bunch of free disk space:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://number-none.com/blow/blog_videos/storage_manager.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;(It’s a bit more than we need right now, but the hope is that this will last for some years).&lt;/p&gt;

&lt;p&gt;I have made folders to back up all our projects:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://number-none.com/blow/blog_videos/Archive%20Folder.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;So: I am now copying all the Braid backups into there (excluding the backups of the old-style Steam depots, because it used to be a really bad thing if you lost those, but since then Steam has moved to a much less-janky system and these aren’t necessary any more).&lt;/p&gt;

&lt;p&gt;It’s been long enough that I am not really sure what is here any more. I am hoping the source art is really here, and sure enough, there’s a folder “Source Art”, let’s see what’s in it…&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://number-none.com/blow/blog_videos/Old%20Programmer%20Art.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Hmm, what’s this, “Old Programmer Art”?&lt;/p&gt;

&lt;p&gt;Oh, this ought to be fun …&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://number-none.com/blow/blog_videos/claw2_2.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;At first glance I am not finding .bmp files corresponding to the .jpgs; I am hoping they are there somewhere and will do a search when the copy from the slow hard drive is done.&lt;/p&gt;

&lt;p&gt;In the meantime, Visual Studio 2015 Update 3 is done and it of course wants to reboot my computer. Sigh. Reboot. Double-click on the braid.sln. This launches Visual Studio 2013, which is the wrong version, because Microsoft seems to have broken version selection and never bothered to fix it. Close Visual Studio 2013, open 2015, manually drag the project file onto it. Clean solution. Build.&lt;/p&gt;

&lt;p&gt;To nobody’s surprise, the build fails. stb_image.h and stb_image_write.h are missing. Add them on laptop, check in, update on desktop. This time it builds. Set launch options in Visual Studio because those don’t ever get saved anywhere reasonable. The game runs!&lt;/p&gt;

&lt;p&gt;This is in unpackaged mode. Let’s run the package-building thing. Oh, it uses File::Slurp and that is not installed by default with Perl.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ppm install File-Slurp
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;and wait a bit. Then run again. It builds the package in under 10 seconds (this used to take many minutes back in the day!) Go into Package, run braid.exe. Launcher comes up. Press Launch button. Game comes up!&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cd ContentBuilder
run_build
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Steam updates for a few seconds. Then I get Steam Guarded. Go to email, type the code.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ERROR! App build file does not exist: ..\scripts\appbuild_499180.vdf
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;So apparently I forgot to check that in as well. Actually it’s about 7 build config files that are missing (for various platforms, etc). Check in, update.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;run_build
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;It’s getting further now. Scanning content. Uploading content. Then Steam says:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ERROR! Failed to commit build for appid 499180 : Failure
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;I have no idea why it’s failing; also though, I know it really succeeded, because it does this every time. Maybe at some point I will bug Valve about this but ehh. Log into Steam partner site, to check the depot, it takes me a few minutes to find the right page even though I do this all the time, because this site is some in-progress mixture of old UI and new UI and it is remarkably hard to get to the page that actually has the technical stuff on it. The upload succeeded but it wasn’t set live, so I do that. (This is not live to players, just to me, since this is a separate copy of Braid just for experimentation).&lt;/p&gt;

&lt;p&gt;Run Steam, download the modified Braid through Steam. When it’s done downloading, it still isn’t ready to run – it wants to download another 62MB. I guess I downloaded it before the change propagated through the magical internet servers. Second download finished. Run it. Launcher box appears. Press Launch. The game runs.&lt;/p&gt;

&lt;p&gt;Yay! That is always a bit of a hassle, but we caught a couple of problems … &lt;em&gt;always test things end-to-end on a second machine&lt;/em&gt; is a thing that programmers learn pretty early on in development.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Okay, back to the code.&lt;/p&gt;

&lt;p&gt;My next step will be to go back over all the loop changes I did yesterday (when inserting that Each macro) and see if I did anything obviously bad. One example of something that could have happened is deleting an extra line of code that really needs to stay in the loop body. Recall that I was editing a bunch of stuff that looks like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;List *l = get_portables(&amp;amp;ptype_Puzzle_Piece);

Entity_Puzzle_Piece *e;
Foreach(l, e) {
    if (e-&amp;gt;portable_flags &amp;amp; PORTABLE_KILLED) continue;
    if (e-&amp;gt;piece_index == piece-&amp;gt;piece_index) return e;
} Endeach;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;and deleting the references to PORTABLE_KILLED. When cranking through hundreds of examples in a row like that, it feels a little too easy to accidentally also delete some other loop condition. Also, sometimes I needed to rearrange lines before the head of the loop, because other stuff would be inserted between the “List *l” part and the Foreach part. This review will be slightly tedious but probably not nearly so much as performing the actual edits. So here goes…&lt;/p&gt;

&lt;p&gt;It’s going pretty quickly, because a visual diff program (such as the one provided with TortoiseSVN) will highlight the lines that changed, so I just need to look at the highlit lines to see if there’s anything fishy.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://number-none.com/blow/blog_videos/diff.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Aaaand … I caught one!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://number-none.com/blow/blog_videos/andromeda_bug.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;(I accidentally deleted that if (!marker-&amp;gt;label) line!) This does not actually cause a crash, because there are no Markers on this level where label == NULL. But it should be fixed anyway. So I am already glad I am doing this check.&lt;/p&gt;

&lt;p&gt;(In all projects after Braid, since I have found that testing string labels is something I want to do often in gameplay code, I use a function strings_match() that handles NULL and doesn’t have the weird reverse logic of strcmp’s != 0, which greatly simplifies the situation. In the new programming language, you have empty strings instead of NULL pointers, and == works on strings, so this worry does not come up.)&lt;/p&gt;

&lt;p&gt;That’s the only bug I found via this check. Which doesn’t guarantee I didn’t introduce other bugs, but hey. The check only took about 25 minutes, so I think it was a good idea.&lt;/p&gt;

&lt;p&gt;Now that that’s done, I want to revisit this idea from yesterday about safely destroying entities, and why I got so confused about this. Let’s say there is a boss monster, and when he plays certain sounds, you want to stop other sounds of his. Well, you’d like to write this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;void eliminate_prior_voice_sounds() {
    Each(issued, Issued_Sound) {
        if (!strings_match(issued-&amp;gt;label, &quot;gun_boss_voice&quot;)) continue;
        globals.entity_manager-&amp;gt;schedule_for_destruction(issued);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;but if it’s not safe to destroy things while iterating, then I’d have to write this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;void eliminate_prior_voice_sounds() {
    Array &amp;lt;Entity_Issued_Sound *&amp;gt; to_destroy;

    Each(issued, Issued_Sound) {
        if (!strings_match(issued-&amp;gt;label, &quot;gun_boss_voice&quot;)) continue;
        to_destroy.add(issued);
    }

    Entity_Issued_Sound *issued;
    Array_Foreach(&amp;amp;to_destroy, issued) {
        globals.entity_manager-&amp;gt;schedule_for_destruction(issued);
    } Endeach;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;(complete with Array_Foreach macro that is more verbose than it should be, since in C++11 we can infer the type of the iterated value, and I will clean this up later probably, but it’s not so important now).&lt;/p&gt;

&lt;p&gt;The second, longer idiom is being used a lot in the Braid source code; not having worked with it for years, when I saw that idiom repeatedly, I presumed it’s not safe to destroy things while iterating. Well, it is safe, it’s just that after making it safe, I never went back and cleaned up old code. (Braid took 3.5 years to make, and a lot of basic things changed over that time!) The old idiom works, but the problem is, it’s confusing; if it confused me, it is much more likely to confuse people in the future who didn’t write the code in the first place. So it’s time to take care of that.&lt;/p&gt;

&lt;p&gt;I imagine the code will shrink a bit when I do this, so let’s get an updated count beforehand: 69,228 lines.&lt;/p&gt;

&lt;p&gt;Cool, now I will just hope that I named the array in most instances of this pattern “to_destroy”, and search for that, and simplify. That didn’t take long, so I also do a scan of calls to schedule_for_destruction and catch one that I missed. Game still compiles and runs. Line count: 69,180. (Savings: 48 lines plus potential confusion!)&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Okay. I believe it is time to confront the aforementioned peril.&lt;/p&gt;

&lt;p&gt;Yesterday I spent a bunch of time banging on the ‘pieced_image_maker’ tool, but I don’t think I ever said what it does. Basically, the job of that tool is to take a .psd file full of stuff that David drew that represented a bunch of different images we wanted to lay out in a level, and pack those images into texture maps in some kind of not-totally-inefficient way, and also output a listing telling us the name of each layer and a set of rectangles along with the areas of the destination texture that those rectangles represent. Any layer can be broken into multiple rectangles, because we don’t want to store or render too many transparent pixels; just dumping each layer as an individual texture would be very inefficient!&lt;/p&gt;

&lt;p&gt;For an example, let’s look at some pieces from this scene:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://number-none.com/blow/blog_videos/braid_background.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Here’s one of the buildings in the background; it consists of four rectangles.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://number-none.com/blow/blog_videos/pi2.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The rectangle in the upper-right is probably just holding some mostly-transparent pixels that David didn’t mean to be there, but the tool can’t exactly tell what’s a mistake versus what is just subtle, so whereas I put some heuristics in there to trim away things that seem like they are very very transparent, those heuristics are pretty conservative.&lt;/p&gt;

&lt;p&gt;Here’s another piece:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://number-none.com/blow/blog_videos/pi1.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Here, you can see that because the rectangles are always axis-aligned, we have a bunch of empty space near the diagonals.&lt;/p&gt;

&lt;p&gt;Here’s the ramp in front of that, where we fared a little better:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://number-none.com/blow/blog_videos/ramp.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The tool also splits things when they are too big to fit into the maximum texture size. For example, I am pretty sure this bridge was only split because it was too wide:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://number-none.com/blow/blog_videos/long_bridge.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In the source art folder that I dug out of the backups, I have all these psd files. So long as they haven’t been thoroughly corrupted, and so long as I haven’t put too many bugs into pieced_image_maker, I ought to in theory just be able to re-run it on all the .psd files, and it’ll generate all the output .bmp files, and that will be great. I can compress those .bmp files to .dds directly, without coming from the lossy .jpgs. And I’ll keep those .bmp files around for future texture compression and storage adventures.&lt;/p&gt;

&lt;p&gt;However, the peril is this … the Pieced_Image stores the coordinates of its lower-left corner in the .psd image, so that if we have two Pieced_Images we can reason about where they are with respect to each other (the boss monster in the game, for example, consists of many different pieces, and we render them just by making sure the offsets relative to each other are the same as they were in the .psd). However, the coordinates with which a Pieced_Image entity are stored in the game world does not care about this. It’s super crappy. I am pretty sure (I think I am remembering this correctly) that we just render the image by placing its lower-left corner at the coordinates of the entity, which sounds fine if you don’t think about the fact that the lower-left corner is generated by a program and thus somewhat arbitrary. If you were to paint on a psd layer so that you expanded the bounding box of the resulting image downward or two the left, the images in the game world &lt;strong&gt;will move&lt;/strong&gt; by the corresponding amount.&lt;/p&gt;

&lt;p&gt;This is completely terrible, and I am not sure how I ever let this slide, except that David never complained about it much and I always had a lot of other things to worry about.&lt;/p&gt;

&lt;p&gt;When it comes to preserving the game into the future this is a massive timebomb. For example, &lt;em&gt;maybe&lt;/em&gt; when I run pieced_image_maker it will make exactly the same decisions about how to cut up and pack the images as it did before. Or &lt;em&gt;maybe&lt;/em&gt; it won’t. Maybe whatever in Photoshop turned 0xcdcdcd into 0xcecdce will bump the transparency of some pixel below the threshold that my cropping heuristic checks for, and my cropping will change. Maybe I had an uninitialized variable and some arbitrary decisions will come out differently this time.&lt;/p&gt;

&lt;p&gt;Now, if that happens, I can tell, but there isn’t currently a mechanism to do anything about it. Suppose I use the lower-left corner of the image as an anchor when rendering … if David then goes and shifts the layer inside the psd a little bit, because he needs more room on the left to draw, then we have the same problem.&lt;/p&gt;

&lt;p&gt;In 3D modeling we never have this problem because there’s a built-in idea of an origin and modelers just know what that means. I do know that you can set up markers in Photoshop to mark specific points, so we just need to have one that says “here is the origin in this image” (maybe it starts in the middle) and then images will only ever shift if you move them relative to that origin. So if you need more room to draw, you could make the canvas bigger, and because we aren’t using the corners as meaningful reference any more, this has no effect on the output. As for why we didn’t do this before … bleah, you know the story.&lt;/p&gt;

&lt;p&gt;So, here’s what I need to do:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;At least make sure pieced_image_maker runs well enough to generate some meaningful output.&lt;/li&gt;
  &lt;li&gt;Compare this output to the old output to determine whether anything has moved.&lt;/li&gt;
  &lt;li&gt;If nothing has moved, we don’t have to worry about the next step until later, and can do image compression experiments; otherwise,&lt;/li&gt;
  &lt;li&gt;Build in a system for placing the origin, and then write some code to move every Entity_Pieced_Image in the game by the corresponding offset, so that the Entity’s position refers to where the origin is in the game. I say move all the in-game entities, because otherwise I am just complicating things by adding more weird offsets to each other, which will be harder to understand later. I would rather just have things be simple.&lt;/li&gt;
  &lt;li&gt;Animated characters, and entities like gates and keys, are probably a more ‘entertaining’ situation than this but let’s just start with the above and make sure the levels are okay.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Oh, and while looking over all this, I realized there is some old code in pieced_image_maker.cpp for saving the separate rgb + alpha jpeg images! I’ve just gotten rid of that. Line count: 69,146, savings: 34 lines.&lt;/p&gt;

&lt;p&gt;Okay, so I compile and run pieced_image_maker for the first time in years … there is an assert. It’s a dumb mistake where I used the wrong variable during a minor change I made the other day. Rebuild, run … and it runs! It sure goes a lot faster than it did back in the day.&lt;/p&gt;

&lt;p&gt;Unfortunately if you don’t give it the command-line option not to do so, it writes its results into the hardcoded folder, which is /braid/game/run_tree/data/pieces, which is very convenient when you are working on the game all the time since it puts the output where the game wants it for the next run, thus clobbering the old output. But … the copy of Braid I am working in is in a different folder, since this is a massively disruptive refactor. What’s in /braid right now is supposed to be the safe copy … which I just clobbered with images of dubious safety. REVERT!!!&lt;/p&gt;

&lt;p&gt;Trying again. The output looks reasonable, but it is definitely making some different decisions. So I’m going to have to figure out what to do here. First step will be to get an origin placed in the files somehow, and read that from the psd file code. But it’s time to take a break from Braid for a few days…&lt;/p&gt;
</description>
        <pubDate>Tue, 19 Jul 2016 18:15:00 -0700</pubDate>
        <link>https://number-none.com/blow/blog/programming/2016/07/19/braid_cleanup_4.html</link>
        <guid isPermaLink="true">https://number-none.com/blow/blog/programming/2016/07/19/braid_cleanup_4.html</guid>
        
        
        <category>programming</category>
        
      </item>
    
      <item>
        <title>Braid Code Cleanup (part 3)</title>
        <description>&lt;p&gt;In the previous posting I said it “was a good place to stop for the night”. And I had decided to, but as sometimes happens, I changed my mind and worked for about another 45 minutes until I had solved the problem.&lt;/p&gt;

&lt;p&gt;I knew I had a problem in at least some DDS files. I checked the old version of Braid to narrow down one particular file causing a problem. Then I downloaded the DDS plugin for Photoshop, installed that, viewed the DDS file, and … there’s a big gray band across the bottom of every DDS image, just like the gray bands I am seeing in-game. At first I presumed this was a bug in nvdxt and looked into how to use nvcompress, but that doesn’t handle batch files. But then I just clicked on one of the BMP files I had outputted orignally, and saw the gray stripe there too:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://number-none.com/blow/blog_videos/three-general_page_0_bmp_gray_band.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Note that you can see these gray bands very clearly in the file listing from yesterday’s blog post!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://number-none.com/blow/blog_videos/bmps.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;After presuming this was a bug in my BMP saving code (which is going to be deleted in the next step of refactoring anyway, so I didn’t really want to debug it), I tried switching to stb_image_write to save BMP files, and PNG files, and neither of those really did what I want: BMP didn’t save the alpha channel, and put purple everywhere instead:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://number-none.com/blow/blog_videos/leveltwo-cliffsandrocks01_page_3.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;PNG came out all wacky, I don’t even know what is going on:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://number-none.com/blow/blog_videos/c5_page_0.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;But hey, this was an old version of stb_image_write, I should upgrade that to a new version when I am back to a stable point. In the meantime I should just figure out a quick fix…&lt;/p&gt;

&lt;p&gt;Then I got lucky and some asserts started going off because I was repeatedly re-running this image loading stuff in the debugger. And I realized … heyyyy, jpegs are probably loading asynchronously … and I am not waiting for them to be finished loading before I save them. Weird that this would insert the same-sized gray band every time, but let’s switch back to my BMP saving code and try waiting …&lt;/p&gt;

&lt;p&gt;… and it worked perfectly.&lt;/p&gt;

&lt;p&gt;Oops! In Braid there is no such thing as synchronously loading a jpeg, even though the API looks like there is. This is very error-prone which is one reason I want to get rid of it!&lt;/p&gt;

&lt;p&gt;Come to think of it… I bet that gray color is 0xcdcdcd, the pattern that the Windows C Runtime fills uninitialized memory with! (Let’s verify this in Photoshop):&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://number-none.com/blow/blog_videos/cdcdcd.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Well, it’s close enough for government work. I am not sure why it turned into 0xcecdce, but it is probably something to do with gamma correction and something something. I don’t really trust Photoshop to be precise about anything.&lt;/p&gt;

&lt;p&gt;Anyway. I re-save all the BMPs, run nvdxt on them, copy the new DDS files over, and … huge success!&lt;/p&gt;

&lt;p&gt;Whew. So, I am still typing this up “last night”. Time to go to bed. See you tomorrow.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Okay, it’s tomorrow.&lt;/p&gt;

&lt;p&gt;Next task: eliminate all jpeg files from the game’s data so that I can remove jpeg support from the game completely. I’ll get it back later, with the new bitmap loading code, but in the meantime this is a good way to be sure all the threading shenanigans are really gone.&lt;/p&gt;

&lt;p&gt;After removing the jpeg version of the in-game graphics, a search reveals there are 9 small jpegs that are used as icons in the editor. Rather than batch-converting in Photoshop, I just repurpose the bitmap conversion code from yesterday. Delete the jpegs. Open the editor to make sure it works, it does.&lt;/p&gt;

&lt;p&gt;Do searches for .jpeg and .jfif (alternate .jpg extensions) but there aren’t any. Case closed for now.&lt;/p&gt;

&lt;p&gt;Re-disable the bitmap conversion code in main.cpp.&lt;/p&gt;

&lt;p&gt;Remove module_jpeg.cpp. Fix compile errors, modifying pieced_image_maker tool to save bmp instead of jpg. Remove all async_jpeg stuff from the code. (Leaving the concept of unloaded maps in for now, since we may add an asynchronous bitmap processing mechanism back later .. but it will be much better-structured than the jpeg thing was).&lt;/p&gt;

&lt;p&gt;Test the game; it runs! Test in Release also. Still runs.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Now&lt;/em&gt; it’s time to remove the Bitmap_Loader and replace it with the simplified Witness version, as I was trying to do yesterday. Remove the old files, copy over the new files (there are many fewer new files than old files, due to simplified structure and ability to use stb_image to do more).&lt;/p&gt;

&lt;p&gt;Upgrade stb_image_write from 0.92 to 1.02.&lt;/p&gt;

&lt;p&gt;Go to the office, read and deal with Witness-related emails.&lt;/p&gt;

&lt;p&gt;Change usage of stbi_write_png_to_mem (which seems to be deprecated) to stbi_write_png_to_func. Oh wait, no, stbi_write_png_to_mem still exists, it is just not exposed in the header file, and using to_func would be slower. Okay, expose to_mem.&lt;/p&gt;

&lt;p&gt;Change usage of load_bmp_info (get dimensions + number of channels without fully decoding bmp) to stbi_info_from_memory, which is also better since it handles all formats.&lt;/p&gt;

&lt;p&gt;Game now compiles! Doesn’t run properly, though. Wait, it is running fine in Debug, just very slowly in Release and with letterboxing for some reason? Oh joy. Full Rebuild doesn’t help.&lt;/p&gt;

&lt;p&gt;Oh look, I am reloading all texture maps from disk every frame. That would definitely make things slow. When loading bitmaps, flag them as definitely not unloaded. The way the whole ‘unloaded’ thing works will have to be audited later. For now we are happy.&lt;/p&gt;

&lt;p&gt;By the metrics we’ve been using to count code, line count is now 81,086, but a lot of that is enlarged stb_image stuff. Let’s move those out to an external folder so it’s easier not to count them. Also delete a very old stb_image.c that was laying around. New count: 71,654 lines.&lt;/p&gt;

&lt;p&gt;But, I have not ever been counting the source for the pieced_image_maker tool or for the shaders. Whip up a hacky count script to do this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cloc --no3 --by-file-by-lang --force-lang=&quot;C&quot;,fx gamelib_core gamelib_render  game tools game\run_tree\data\shaders
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;(I pretend .fx files are C because cloc doesn’t know about HLSL, or at least, this version of cloc doesn’t.)&lt;/p&gt;

&lt;p&gt;More accurate line count: 80,017.&lt;/p&gt;

&lt;p&gt;Oh, I am still linking to libjpeg and libpng and have the includes and libs hanging out in the external libraries folder. All this stuff is taken care of by stb_image now, so delete all that. (The API to libjpeg is pretty terrible). This stuff doesn’t affect line count since I don’t count the external dependencies. Verify game still compiles and runs.&lt;/p&gt;

&lt;p&gt;While doing the new line counts I had noticed a spurious file puzzle_assembly_screen_sean.cpp that is not compiled into the game and is mostly a copy of puzzle_assembly_screen.cpp. It looks like it was some kind of safety backup I made back in 2008 when I wanted to integrate some of Sean’s changes more closely into the puzzle code. We don’t need this any more, and if we ever do, it’s in source control. Deleted. New line count: 78,830.&lt;/p&gt;

&lt;p&gt;The game still has a copy of BMP saving code, that we can remove in favor of using stb_image; then the pieced_image_maker tool has &lt;em&gt;another&lt;/em&gt; set of BMP saving code, this one written by Casey Muratori in 2002. Let’s get rid of both of these.&lt;/p&gt;

&lt;p&gt;First, on the game side: Delete bmp_save.cpp, bmp_save.h, bmp_internal.h. Actually that was the last stuff in the entire gamelib_core/bitmaps folder, so let’s delete that folder and simplify our file structure, which is a nice win. Make it compile. Now I need to test writing a bmp… In developer mode, the Print Screen key writes out a screenshot, so I try that, and:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://number-none.com/blow/blog_videos/bmp_shot.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Well, it’s flipped vertically, and RGB are byte-reversed. The conventions in our engine are totally opposite of what stb_image expects. Maybe I can figure out how to get stb_image to do this efficiently (looking at the Witness code, we flip everything and byte-swap it when we load it, which isn’t as bad as it sounds since all texture assets are prebuilt for the local platform when running in production so we don’t do this work at runtime). I will ask Sean about this on Twitter, but in the meantime I just write some quick code to do the job:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;bool save_bmp_file(const char *filename, byte *data, int width, int height, int bits_per_pixel) {
    assert(bits_per_pixel % 8 == 0);
    auto bytes_per_pixel = bits_per_pixel / 8;

    // Flip in place, swap byte order. @Cleanup: Can we do this in stb_image?

    for (int y = 0; y &amp;lt;= height/2; y++) {
        auto y_flipped = height - 1 - y;

        for (int x = 0; x &amp;lt; width; x ++) {
            byte *dest   = &amp;amp;data[(y_flipped * width + x) * bytes_per_pixel];
            byte *source = &amp;amp;data[(y         * width + x) * bytes_per_pixel];

            auto tmp0 = dest[0];
            auto tmp1 = dest[1];
            auto tmp2 = dest[2];

            dest[0] = source[2];
            dest[1] = source[1];
            dest[2] = source[0];

            source[0] = tmp2;
            source[1] = tmp1;
            source[2] = tmp0;
        }
    }

    int success = stbi_write_bmp(filename, width, height, bytes_per_pixel, data);
    return success ? true : false;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;and it works:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://number-none.com/blow/blog_videos/bmp_fixed.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update from the next morning:&lt;/strong&gt; Actually there’s a bug, as you can see if you actually look at the image carefully, which I didn’t: There’s a line of pixels across the middle that has been swapped twice, and is therefore the wrong color! Of course I had the sense yesterday that I should stop and think about the loop condition carefully, but I didn’t want to – I wanted to go fast. Changing it to&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;y &amp;lt; height / 2
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;will work for images with even heights, but what about odd heights? Rather than do some weird math that is harder for people to understand in the future, I think the simplest and most robust way is to add&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;if (y &amp;gt;= y_flipped) break;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;to the loop body. &lt;em&gt;Interlude over; now back to yesterday’s post.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So, one redundant copy of BMP code is gone. Check in. Line count: 78,583.&lt;/p&gt;

&lt;p&gt;Ask Sean about this on Twitter.&lt;/p&gt;

&lt;p&gt;Now to the pieced_image_maker tool. Delete pieced_image_maker/image/bmp.h, bmp.cpp, image.h, image.cpp. There is still PSD loading code in there but we’ll ignore that until later. Replace Chris Hecker’s old ‘image’ struct with the Bitmap_Data used everywhere else in the engine. (I had put together pieced_image_maker based on some code Chris sent me waaaaay back when.) Lots of errors because the interface was different. This is feeling like a relatively unrewarding conversion, especially because the old code was very self-contained so the mess of functionality duplication was limited, but let’s stick with it.&lt;/p&gt;

&lt;p&gt;OKAY, after a bit of a slog, pieced_image_maker.cpp compiles, but the psd code does not. Hmm, I can’t substitute stb_image’s psd loading, because we actually are doing a process where we step through the layers and output a file for each layer, so we need to maintain our understanding of layer structure and stb_image does not do that. So instead I get to do more converting of image -&amp;gt; Bitmap_Data, in the psd code this time. Yaaaay. Oh wait actually that didn’t take too long. I’ll have to test this tool a bunch though, later on, but that will happen naturally.&lt;/p&gt;

&lt;p&gt;Current count: 76,178 lines (savings: 2,408 lines). But wait, there is more we can do – because this originally came from someone else’s codebase, there is a bunch of code that I mostly or completely don’t need: utils.h, utils.cpp, math1d.h, math2d.h, math3d.h, math4d.h, image_operations.cpp, image_operations.h, checker_assert.cpp.&lt;/p&gt;

&lt;p&gt;image_operations.* was being compiled in, but apparently was no longer used at all, so that’s gone now. utils and the math stuff was not even being compiled in! (utils.h was being included, but provided no use). So BOOM, all that stuff is gone, along with the ‘misc’ folder. And there’s still an ‘image’ folder, but it only contains psd.cpp,h, so let’s move that out and further simplify our folder structure.&lt;/p&gt;

&lt;p&gt;OH WAIT, psd.cpp actually needed some stuff from math1d and math2d, but because of broken Visual Studio caching, I was still able to compile. Well, I need to bring some of it back, but not much, just defining some basic types, I’ll just put it into psd.h. At first glance it also wants stuff from math2d, but looking more closely, all it wants is the existence of a ‘vector_2’ that it can construct and assign, and I can just do a drop-in replacement with my ‘Vector2’.&lt;/p&gt;

&lt;p&gt;It compiles again. Current source count: 73,612. Savings: another 2,366 lines! That’s a total of 4,714 lines removed, in the approximately two hours I have been banging on pieced_image_maker.cpp. The tool itself is down to 2,123 lines – &lt;em&gt;much&lt;/em&gt; smaller than it was before, which is a really good thing for tools since those are the things most likely to break / rot by the time you need to figure them out years later.&lt;/p&gt;

&lt;p&gt;Sean on Twitter says I have to reformat the data to use stb_image, just as I am doing now. So that’s fine.&lt;/p&gt;

&lt;p&gt;Lunch time, break time!&lt;/p&gt;

&lt;p&gt;Okay, next: “Get rid of Pool, use Isolated_Heap_Pool.” As mentioned in part 1, the only place using the old Pool is the font code. Thing is, I am going to replace the font code at some point later (the newer version used in The Witness uses Harfbuzz to do layout and supports more languages, and has some other modernizations). But this is a small enough change that it probably doesn’t count as wasted work. Font stuff is in gamelib_render, but Isolated_Heap_Pool is in game, which is a higher-level piece, so Font can’t see it. Move Isolated_Heap_Pool down to gamelib_core. Notice in the process that the non-Windows/Xbox ports of Isolated_Heap_Pool (not written by me) do not actually use separate heaps. Yuck. This is not too terrible if they only run on high-end platforms, but it’s not ideal. Comment this. There is an ‘isolated_heap_pool_std’ that is used on other OSs; we will come back to this because it is annoying. (This is one of many reasons why cleanup passes are good; you notice all kinds of things you wouldn’t have noticed otherwise.)&lt;/p&gt;

&lt;p&gt;The switch seems to work the first time (Pool and Isolated_Heap_Pool had the same API, so aside from messing around in the Visual Studio project and moving files, it was just a 1-word change to one file). Game runs great, and it still draws fonts just fine.&lt;/p&gt;

&lt;p&gt;Okay, let’s take a look at isolated_heap_pool_std.cpp,h. It is basically just a separate implementation of Isolated_Heap_Pool with some code changed so it doesn’t use HeapCreate / HeapDestroy. In fact it is basically Pool, just with totally different code because someone at Hothead Games wrote it when he was porting Braid to OS X + PS3 I guess, and I guess he didn’t see Pool because that already did exactly what he did. Well, … let’s just make Isolated_Heap_Pool not try to use separate heaps when #ifndef WIN32, which essentially downgrades it back to Pool. Then we can get rid of Isolated_Heap_Pool_Std.&lt;/p&gt;

&lt;p&gt;Use C++11 initializers in Isolated_Heap_Pool.&lt;/p&gt;

&lt;p&gt;Delete silly global variable&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Isolated_Heap_Pool *the_isolated_heap_pool;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Why was that there? Nobody uses it, thankfully.&lt;/p&gt;

&lt;p&gt;Count: 73,451 LOC. Savings from pool stuff: 161 lines. This feels like it should have been more, but looking at the line counts in scrollback, it roughly checks out. Well, it’s also 4 files gone, that is pretty good!&lt;/p&gt;

&lt;p&gt;Next on the list; there’s a file called byte_reading.h that defines a bunch of stuff like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;inline bool read_u4b(char **data, int *len, int *result) {
    assert(sizeof(int) &amp;gt;= 4);

    if (*len &amp;lt; 4) return false;

    unsigned char *base = (unsigned char *) * data;
    unsigned int sum = 0;

    sum += *(base + 0) &amp;lt;&amp;lt;  0;
    sum += *(base + 1) &amp;lt;&amp;lt;  8;
    sum += *(base + 2) &amp;lt;&amp;lt; 16;
    sum += *(base + 3) &amp;lt;&amp;lt; 24;

    *result = (int)sum;
    *data += 4;
    *len -= 4;

    return true;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;(Reading a 4-byte value from a memory buffer into an integer using application-defined endianness; of course this can be accelerated on platforms with known endianness and known instructions). There’s another file called binary_file_stuff.h that defines a bunch of the same routines, but operating on files. On my list was to check these for redundancy. Well, the functionality is pretty well divided, but I find it a little confusing that they’re two separate files, so I am going to combine them into one. Also, I see some procedures in binary_file_stuff that are no longer used because they represent higher-level transactions that no longer make sense to do that way (stuff like put_vector3, put_quaternion, etc). So, deleting those, putting the rest into byte_reading.h, getting rid of binary_file_stuff.h, change the includes of all using sites.&lt;/p&gt;

&lt;p&gt;[In general the file stuff is not used by high-level code, because in a game you usually want to do data transactions in memory, because you often don’t know where your ‘file data’ came from, and it might come from different places during development and release – for example, during development you might be loading from loose files on disk, but during release you might be looking at a section of a huge pre-loaded package. It simplifies life if you just always deal in memory, and in the cases where you are explicitly loading files, first load the file then pass it to the back-end routines that parse memory. The binary_file_stuff.h is used mainly for … HMMMM ] Hey hold on. After auditing, it looks like put_u4b and the like are only used in one place, and that place could easily go to memory, so quite possibly all this stuff can go away. So before combining the files, I will just get rid of everything in binary_file_stuff.h that I can.&lt;/p&gt;

&lt;p&gt;(Earlier in the history of the game, the file versions of these operations were used pretty heavily, but that changed as I did all the work to make things run with preloaded packages…)&lt;/p&gt;

&lt;p&gt;The one place that still uses the file versions of these routines is in the routine that saves the ‘Type Manifest’ to a file during entity serialization; the type manifest tells us which entity types are in the file (listing them by name), so that we can use indices from then onward in order to make serialization faster and smaller, but also robust (it won’t break if whoever reads the file later on adds or removes entity types).&lt;/p&gt;

&lt;p&gt;Here’s the code:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;void save_type_manifest(File_Handle *f) {
    Portable_Type_Manager *manager = globals.portable_type_manager;
    int num_types = manager-&amp;gt;types.items;

    Fast_Encoder encoder;
    pack_int32_fast(&amp;amp;encoder, num_types);

    Portable_Type *type;
    Array_Foreach(&amp;amp;manager-&amp;gt;types, type) {
        int revision_number = 1;
        if (type-&amp;gt;metadata) revision_number = type-&amp;gt;metadata-&amp;gt;revision_number;

        pack_string_fast(&amp;amp;encoder, type-&amp;gt;name);
        pack_int32_fast(&amp;amp;encoder, revision_number);
    } Endeach;

    unsigned char *data;
    int len;
    encoder.get_result(&amp;amp;data, &amp;amp;len);

    put_u4b(len, f);
    fwrite(data, len, 1, f);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Basically, the only reason we are calling put_u4b to the file is because we don’t know the length until after we finish packing stuff, but the length is supposed to go into the file before the stuff we pack. But that’s fine, this can be handled in a very standard way – we can just pack a 0 and then overwrite that memory when we know the length.&lt;/p&gt;

&lt;p&gt;(Note that this code implies there is even more redundancy here, since the so-called ‘Fast_Encoder’ has routines for packing various kinds of things, and pack_int32_fast is essentially just a wrapper around put_u4b that also ensures space exists. But we won’t worry about that now.)&lt;/p&gt;

&lt;p&gt;So: pack the zero. Overwrite it with put_u4b to memory when done. Test this by opening the editor, editing a level, saving it back out, and making sure we can still play it!&lt;/p&gt;

&lt;p&gt;The code has become:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;void save_type_manifest(File_Handle *f) {
    Portable_Type_Manager *manager = globals.portable_type_manager;
    int num_types = manager-&amp;gt;types.items;

    Fast_Encoder encoder;

    auto poke_position = encoder.output_len; // This will be 0, since we have not packed anything yet, but this could possibly change later, especially if we change this to pass in a Fast_Encoder as an argument rather than writing to a file. -jblow, 18 July 2016.

    pack_int32_fast(&amp;amp;encoder, 0); // This is where the length will go later. 4 bytes.

    pack_int32_fast(&amp;amp;encoder, num_types);

    Portable_Type *type;
    Array_Foreach(&amp;amp;manager-&amp;gt;types, type) {
        int revision_number = 1;
        if (type-&amp;gt;metadata) revision_number = type-&amp;gt;metadata-&amp;gt;revision_number;

        pack_string_fast(&amp;amp;encoder, type-&amp;gt;name);
        pack_int32_fast(&amp;amp;encoder, revision_number);
    } Endeach;

    unsigned char *data;
    int len;
    encoder.get_result(&amp;amp;data, &amp;amp;len);

    char *cursor = (char *)&amp;amp;data[poke_position];
    put_u4b(&amp;amp;cursor, len - 4); // -4 because we don&#39;t include the length itself in the length computation.

    fwrite(data, len, 1, f);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;And testing it, it works just fine. save_type_manifest is also cleaner, since it no longer mixes file and memory operations, so it’d be very easy to factor the file part elsewhere now.&lt;/p&gt;

&lt;p&gt;Use C++11 initializers in Fast_Encoder, Fast_Decoder.&lt;/p&gt;

&lt;p&gt;Finally, delete binary_file_stuff.h, rather than merging it with byte_reading.h.&lt;/p&gt;

&lt;p&gt;Line count: 73,310. Total savings: 141 lines, 1 file!&lt;/p&gt;

&lt;p&gt;I feel a bit tired, let’s take another break.&lt;/p&gt;

&lt;p&gt;Dealing with email.&lt;/p&gt;

&lt;p&gt;It looks like dlmalloc (a malloc implementation by Doug Lea) is still being included in the code. Back around the midway point of Braid development, I included this in the codebase as a way to get faster allocations and fewer problems with fragmentation than with Microsoft’s libc. Then I made the Isolated_Heap_Pool, and dlmalloc gave me a way to portably create separate heaps, and drastically reduce fragmentation. But later I switched on Windows to just using HeapAlloc. These days, dlmalloc is not considered a highly-performing malloc implementation any more, and anyway, all reasonable operating systems now ship with pretty-okay-quality malloc implementations so a substitute is not required (and if we did want a substitute, it would be something newer than dlmalloc!) But the code was still hanging around in case I ever wanted to bring it back. Also, there’s a bunch of overloads of operator new, delete, etc, that call malloc tracking routines so I can graph memory allocations in the profiler; but that stuff is ugly in C++ (at least back then, there was no actual good way of replacing allocators globally; I think there is now?) and I’d probably rather use external tools such as RAD Game Tools’ Telemetry instead (though that particular tool is not free, I am guessing/hoping there is something reasonable that is free now).&lt;/p&gt;

&lt;p&gt;I’m going to delete the dlmalloc stuff, and then just comment out the malloc tracking stuff (but not delete it, just in case). Then delete dlmalloc.c.&lt;/p&gt;

&lt;p&gt;Line count: 70,433. Savings: 2,877 lines, 1 file. (The bulk of this was dlmalloc.c).&lt;/p&gt;

&lt;p&gt;There is still some stuff in the platform-specific code for unix platforms that I haven’t cleaned out (but did on Windows). Also, looks like nobody calls get_year_month_and_day() on any platform. Also, looks like fileutil.cpp,h were added to this folder by Hothead but are not used by anything (maybe it was for their launcher or something but we are using a different launcher now). Delete those.&lt;/p&gt;

&lt;p&gt;Count: 69,842 lines; Savings: 591 lines, 4 files, 1 folder.&lt;/p&gt;

&lt;p&gt;Now it’s time to attack that bullet point from Part 1, “Make Entities_By_Type use Array and not List. Remove List.” Though now that I have been looking around the code some more, maybe it won’t be prudent to remove List since it’s possible someone else uses it. But let’s see. In any case this is going to be kind of ugly because it’s going to involve a lot of search-and-replace and a lot of compiler errors.&lt;/p&gt;

&lt;p&gt;Basically after changing the data structure, I will have to replace tons of little code snippets that look like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;List *l = get_portables(&amp;amp;ptype_Puzzle_Piece);

Entity_Puzzle_Piece *e;
Foreach(l, e) {
    if (e-&amp;gt;portable_flags &amp;amp; PORTABLE_KILLED) continue;
    if (e-&amp;gt;piece_index == piece-&amp;gt;piece_index) return e;
} Endeach;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;with things that look like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Each (Puzzle_Piece) {
    if (it-&amp;gt;piece_index == piece-&amp;gt;piece_index) return it;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;It’s a lot more concise, for sure. Each is a special macro just for iterating over entity types, so it does the check for PORTABLE_KILLED itself, which checks to see if an entity has been destroyed but not yet cleaned up at the end-of-frame. Experience shows that remembering to check this manually is as error-prone as you would expect, so it makes a lot of sense to build it into a macro or iterator.&lt;/p&gt;

&lt;p&gt;This is going to be a big job and I may not finish today. Maybe I could automate this somehow but, ehh, it just seems unlikely. Let’s just see how it goes. A global search finds 230 uses of Foreach, most of which I will want to replace. Oooookay.&lt;/p&gt;

&lt;p&gt;On Entity_Manager, replace&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;List *lists_by_type;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;by&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Array &amp;lt;Entity *&amp;gt; *arrays_by_type;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;And now of course there are tons of errors all over the project. (Visual Studio reports 222 errors but these numbers tend to be unreliable). So, add the Each macro and find a file that only iterates a little bit in order to test it out. Looks like pieced_image.cpp only does it once. So let’s copy Each over from The Witness and modify it cosmetically. Look at this thing of ‘beauty’:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#define Each(_manager, _Type) \
    if (auto _a = get_portables(_manager, &amp;amp;ptype_##_Type)) \
        if (int count##__LINE__ = _a-&amp;gt;items) \
            for (int i##__LINE__ = 0; i##__LINE__ &amp;lt; count##__LINE__; i##__LINE__++) \
                if (auto it = (Entity_##_Type *)((*_a)[i##__LINE__])) \
                    if (it-&amp;gt;portable_flags &amp;amp; PORTABLE_KILLED) continue; else
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;All the &lt;strong&gt;LINE&lt;/strong&gt; stuff is just there to let us name variables in a way that is very unlikely to conflict with anything in the user code that comes after the ‘else’.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update from the next morning:&lt;/strong&gt; The i##&lt;strong&gt;LINE&lt;/strong&gt; stuff is not correct! It is fine in that the code will execute as intended, but &lt;strong&gt;LINE&lt;/strong&gt; will not expand to the current line number unless it is wrapped inside another macro, because the C Preprocessor is a very special flower that way. Ignacio’s original implementation did wrap those in another macro, but I “cleaned that up” for this veresion because I found it hard to read. So the version that actually names the variables properly is:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#define NV_STRING_JOIN2(arg1, arg2) NV_DO_STRING_JOIN2(arg1, arg2)
#define NV_DO_STRING_JOIN2(arg1, arg2) arg1 ## arg2
#define Each(_manager, _Type) \
    if (Auto_Array&amp;lt;Entity *&amp;gt; *_l = get_portables&amp;lt;Entity&amp;gt;(_manager, &amp;amp;ptype_##_Type)) \
        if (int NV_STRING_JOIN2(count,__LINE__) = _l-&amp;gt;count()) \
            for (int NV_STRING_JOIN2(i,__LINE__) = 0; NV_STRING_JOIN2(i,__LINE__) &amp;lt; NV_STRING_JOIN2(count,__LINE__); NV_STRING_JOIN2(i,__LINE__)++) \
                if (Entity_##_Type *it = (Entity_##_Type *)((*_l)[NV_STRING_JOIN2(i,__LINE__)])) \
                    if (it-&amp;gt;portable_flags &amp;amp; PORTABLE_KILLED) continue; else
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Why do we need &lt;em&gt;two&lt;/em&gt; levels of indirection on the substitution? I have no idea. This kind of thing is why I would so much rather build a new programming language than keep working in C++. &lt;em&gt;End of interruption; now back to yesterday.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Note also that we name the iterator variable ‘it’ in case we want to use that. That is my preferred form, but so that I don’t go insane renaming variables, I will also make a version that takes a name. (This version of Each takes an Entity_Manager as an argument, which is good practice, but most of Braid assumes you want to talk about a global entity manager, so it’s more terse; the global variable thing causes bugs sometimes, but that is how it is right now, and it is easy enough to change that later if I want to; one big change at a time please! So mostly I am going to use a version of Each that takes no Entity_Manager but an explicit iterated value name.)&lt;/p&gt;

&lt;p&gt;After a little bit of the usual C++ macro typo hunt, pieced_image.cpp compiles just fine, so now it is time for me to work through all the files having compile errors, one by one:&lt;/p&gt;

&lt;p&gt;cannon.cpp, collisions.cpp, entity_manager.cpp, entity_panel.cpp, game_view.cpp, greeter.cpp, gun_boss.cpp&lt;/p&gt;

&lt;p&gt;(Visual Studio says 182 errors to go!)&lt;/p&gt;

&lt;p&gt;guy.cpp, hud_hints.cpp, key.cpp, levels.cpp, main.cpp, main_menu.cpp, platform.cpp&lt;/p&gt;

&lt;p&gt;(70 errors to go!)&lt;/p&gt;

&lt;p&gt;prefetch.cpp, prince.cpp, princess_level.cpp, puzzle_assembly_screen.cpp, puzzle_frame.cpp, reverse_effect.cpp, rumble.cpp&lt;/p&gt;

&lt;p&gt;(26 errors to go!)&lt;/p&gt;

&lt;p&gt;shaders_common.cpp, sound_player.cpp, story_page.cpp, switch.cpp, text_screens.cpp, world_panel.cpp&lt;/p&gt;

&lt;p&gt;And we’re DONE!! And it runs! And I can play!! And oh wait, when I go onto the story screens there’s a crash, but it takes just a few seconds to fix; there was some unintuitive code that changed meaning when I did the edit, and it’s better to make it more intuitive.&lt;/p&gt;

&lt;p&gt;I wonder how many other bugs I introduced doing that. Hopefully none! I probably averted a few, and took note of a couple of potential issues to look into. Well, this is what testing is for.&lt;/p&gt;

&lt;p&gt;Count: 69,447. Savings: 395 lines.&lt;/p&gt;

&lt;p&gt;While doing that, I noticed that in world_panel.cpp (which is one of the main files for the in-game level editor) there is a bunch of single-use code that I used to batch-convert entities at various times during development, as we made different decisions about how those entities should be. I left the code in so that I would have quick examples to copy and paste when I needed to do new things. This is stuff like, “convert all grass entities that have one particular name to have some other particular name”, and so on. But these specific examples are not going to be useful, and I feel like it’s best to comment them out to show that they are no longer live code that’s of active use. (But as long as I comment it out instead of deleting it, it’ll be there for potential future resurrection). Also if I comment it out, the line count goes down.&lt;/p&gt;

&lt;p&gt;Commenting out: convert_grass, rename_ledges, fix_ledges, move_particles, list_grass, fix_non_unique, fix_image, fix_images, convert_rain, do_detect, detect_and_replace, particles_detect_and_replace, convert_to_star, convert_to_platform.&lt;/p&gt;

&lt;p&gt;Count: 69,213. Savings: 234 lines.&lt;/p&gt;

&lt;p&gt;Hey, I just had an hour-plus-long situation where I wrote a bunch of stuff and it turned out to be wrong because I forgot how things work and &lt;em&gt;of course&lt;/em&gt; I did it better than that.&lt;/p&gt;

&lt;p&gt;It had to do with iterating over entities by type and whether you are allowed to schedule entities for destruction while doing this, or not. In various engines I have had various policies about whether this was okay. In Braid it &lt;em&gt;is&lt;/em&gt; okay, that is part of the point of ‘scheduling’ entities for destruction rather than destroying them immediately. But I forgot it was okay, in part because I saw code in various spots that was not doing this – instead it was making a separate array of entities to destroy, then when done iterating over the array by type, it would then iterate over that to_destroy array and schedule everyone in it for destruction. This confused me so I wrote many paragraphs talking about the problem and how to solve it.&lt;/p&gt;

&lt;p&gt;Well, I just deleted all those paragraphs. But anyway, an example:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;EachName(debris, Debris) {
    if (!debris-&amp;gt;inserted) continue;

    globals.entity_manager-&amp;gt;schedule_for_destruction(debris);
} 
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Is this legal? If you mess with the array of Debris that EachName is implcitly accessing, then it is bad news. But Braid is more robust than this so it’s fine.&lt;/p&gt;

&lt;p&gt;So on my to-do list for later is to go clean up all the times when I buffer a separate array of entities to destroy, which I presume date back to older code. (During development the policy of what is okay changed a few times until I landed on what it is now.)&lt;/p&gt;

&lt;p&gt;This is also a sign that I am getting tired and can use a break / some sleep. Well, that’s fine, it has been a good day of work. So, good night!&lt;/p&gt;

</description>
        <pubDate>Mon, 18 Jul 2016 22:20:00 -0700</pubDate>
        <link>https://number-none.com/blow/blog/programming/2016/07/18/braid-cleanup-part-3.html</link>
        <guid isPermaLink="true">https://number-none.com/blow/blog/programming/2016/07/18/braid-cleanup-part-3.html</guid>
        
        
        <category>programming</category>
        
      </item>
    
      <item>
        <title>Braid Code Cleanup (part 2)</title>
        <description>&lt;p&gt;Here’s what I have done on Braid since the previous blog posting. It’s about a day’s worth of work, maybe a little more (it consists of a few sessions spread out over the weekend). In case you ever wanted to know what it’s like being an indie game developer … …&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;Found and removed about 3kLOC more of unused source files. New source count: 78,127 lines.&lt;/p&gt;

&lt;p&gt;Fixed header file mess (all headers are appropriately registered in the Visual Studio IDE despite the fact that they make that about as hard as possible).&lt;/p&gt;

&lt;p&gt;Put the Visual Studio 2015 redistributable in the file tree and set the Steam installscript to use it. (Steam itself has a method of installing redistributables via server configs, but if I do it this way I at least know I am installing the same thing on Steam, GoG, Humble, wherever else.)&lt;/p&gt;

&lt;p&gt;Visual Studio 2015 / Windows XP Compatibility: Verified that Platform Toolset is set to v140_xp for all project files.
figure out whatever other options I need to turn off to disable telemetry, prevent weird undesired dependencies).&lt;/p&gt;

&lt;p&gt;Visual Studio 2015 / Add notelemetry.obj to link line to reduce Microsoft adware potential.&lt;/p&gt;

&lt;p&gt;Make Launcher compile in VS2015: Delete ‘fl_call_main.obj’ from precompiled dependencies, add fl_call_main.c to source.&lt;/p&gt;

&lt;p&gt;Update Steam scripts so the game packages and uploads to a new test depot.&lt;/p&gt;

&lt;p&gt;Set up the Steam app configuration so that Steam knows how to start the game.&lt;/p&gt;

&lt;p&gt;Due to Visual Studio bugs I am not currently able to run the static code analyzer. (It is not supported on the v140_xp ‘Platform Toolset’ [whatever that is], and the IDE hits a bug whenever I try to change the ‘Platform Toolset’. So if I ever want anything besides v140_xp I am going to be in a tough spot!)&lt;/p&gt;

&lt;p&gt;Use C++11 initializers for all 48 entity types, and remove unneeded methods. Total savings: 658 LOC. (This is just on entities; have not done it to the rest of the code yet!)&lt;/p&gt;

&lt;p&gt;Get rid of goofy copying of gamelib_core/gamelib_render’s headers and libs.&lt;/p&gt;

&lt;p&gt;Delete a few more unused files from gamelib_core. Remove os_net_* from gamelib_core/win32. Savings: 331 LOC.&lt;/p&gt;

&lt;p&gt;Use C++11 initializers in gamelib_core, gamelib_render. Effect of this is intermittent based on the type of code; some just isn’t that way. Find + remove some more routines that aren’t used. Savings: 161 LOC. Current line count: 76,972.&lt;/p&gt;

&lt;p&gt;Refactor pieced_image_maker tool so it now compiles without requiring gamelib_render.&lt;/p&gt;

&lt;p&gt;Fight with the compiler for a while, trying to get Debug builds working post-VS2015 upgrade. “Fix” this by giving up on the idea of linking against debug versions of 3rd party libraries. Deal with confusing brokenness of VS’s “precompiled header” implementation, which has been terrible for decades yet never fixed.&lt;/p&gt;

&lt;p&gt;Remove debug Windows libs from the 3rd party library folder.&lt;/p&gt;

&lt;p&gt;Call SetProcessDPIAware on startup to avoid Windows’ pixel scaling.&lt;/p&gt;

&lt;p&gt;Start stripping out the YCbCr texture formats; still loading jpgs, just into classic ARGB textures now. At some point I see a crash has been introduced (having to do with the parallel universe effect) that I need to debug. Run Debug build. Wait, why can’t I jump or go through doors or skip levels in Debug build?? Oh, I hadn’t properly saved Event_Manager.h after switching it to use C++11 initializers (but after taking them out of the body) so now things were uninitialized. Figure out how to list unsaved buffers in emacs so I can see if I did this anywhere else. (I didn’t, seemingly).&lt;/p&gt;

&lt;p&gt;Realize that an Update 3 for VS2015 was released a couple of weeks ago. Download and install. It won’t install unless I update Windows and reboot. Update Windows and reboot. Install the update – it takes a really long time for some reason (this is on a very fast laptop with SSD – Razer Blade 14” (2015 model)). After about 20 minutes, realize I’m not going to be able to work any time soon, stick laptop in car and start driving across the bridge back to San Francisco, hope it finishes before battery dies. One hour and 5 minutes after start of install, battery is about to die, but progress bar for install is not done (but looks close to done) so I sleep the laptop, but later when I get to the cafe, it seems to have rebooted for some reason. A new install dialog has popped up but the “Update” button is grayed out. I guess I have a mostly-upgraded copy of Visual Studio now. Shrug. It seems to compile Braid okay.&lt;/p&gt;

&lt;p&gt;Finally, go back to trying to debug whatever error I introduced to the World 5 parallel universe effect. It is crashing in calling a method on D3DXEffect, but the pointer looks valid, and of course Microsoft makes everything inside the pointer a completely undebuggable black box because it is a COM object instead of a regular C struct. The number of hours of my life wasted by this would be rage-inducing if I stopped to think about it. The “DirectX Control Panel” used to help you debug this stuff, but now for DirectX9 everything is grayed out and I can do nothing there. Verify that shader is compiling just fine and that everything works as long as both the ‘regular’ shader and parallel universe shader are set to be the same (regardless of which is chosen) but that the problem happens when they are different. Game is 100% reproducibly crashing in ID3DXEffect::Begin whenever I switch from one effect to the other mid-frame.&lt;/p&gt;

&lt;p&gt;It seems I am not allowed to call certain D3DX things in certain orders, but for some reason this worked before. Juggle around the order a bit.&lt;/p&gt;

&lt;p&gt;While running in Debug I got a new crash “Invalid address supplied to RtlValidateHeap” when cleaning up the diffed entities in World 5 – had better look into that later!&lt;/p&gt;

&lt;p&gt;D3DX still seems touchy whereas before it was not. I must have disturbed some delicate balance but since this is no longer supported by Microsoft it is totally undebuggable now. I guess “get the hell off D3DX” is now on the to-do list, but in the meantime I am going to revert back to working code from this morning and re-do everything in smaller steps until I figure out what happened or else just mysteriously succeed this time. (I’ve already wasted 90 minutes - 2 hours on this, reverting will take less time).&lt;/p&gt;

&lt;p&gt;Revert. Re-do the other fixes I did today not having to do with CbCr. Hmm, as soon as I disable the #define SEAN_YCBCR, the crash happens, I just didn’t notice before because I hadn’t been on World 5. This should help narrow it down.&lt;/p&gt;

&lt;p&gt;It takes only 10 minutes to figure out the bug this way, as opposed to the 2 hours I spent of “legitimate” debugging of the horror that is D3DX in 2016. The problem was here:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;inline ID3DXEffect *get_effect() {
#ifdef SEAN_YCBCR
    Display_System_D3D *sys = (Display_System_D3D *)gamelib_render-&amp;gt;winsys;
    return sys-&amp;gt;fx_shader_effect;
#else
    Fx_Shader *shader = get_shader();
    if (shader) return shader-&amp;gt;effect;
    return NULL;
#endif
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;And simply was that this should say #ifdef SEAN, instead of #ifdef SEAN_YCBCR. See, back when Sean worked on Braid, he did basically two layers of stuff: one was a general set of postprocessing effects to make the game look cooler when you rewind; the other was the YCbCr texture handling. The effects came first and were all #ifdeffed SEAN, and the texture thing came later and was #ifdeffed SEAN_YCBCR. Since if you turn off YCBCR but not SEAN, it only crashes in World 5, it is not surprising that neither he nor I ever noticed. (Normal operation of the game is to have both of these turned on). This use of sys-&amp;gt;fx_shader_effect should always be happening if SEAN is turned on, which should be always. But I just turned off SEAN_YCBCR, and, well, it is bad news. This was hard to spot because in the process of stripping out YCbCr stuff I had simplified this routine to:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;inline ID3DXEffect *get_effect() {
    Fx_Shader *shader = get_shader();
    if (shader) return shader-&amp;gt;effect;
    return NULL;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Which is what it would have been before any SEAN changes, but we want the SEAN changes. Ugh.
Well, now I un-revert all my reversions, fix the #ifdef and move on.&lt;/p&gt;

&lt;p&gt;Update from FreeType-2.3.5 to FreeType-2.6.1 (current FreeType seems to be 2.6.5, but hey, I already have 2.6.1 compiled because that is what we shipped in The Witness, so we’ll go with that for now).&lt;/p&gt;

&lt;p&gt;Tweak the level design on that one level to move that one spot up and to the right. (Finally a little bit of actual work!)&lt;/p&gt;

&lt;p&gt;Tried to run Static Analysis again, figured maybe it would work after the update, but I still can’t change the ‘Platform Toolset’ yet; here is what happens every time I try:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://number-none.com/blow/blog_videos/toolset.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Here’s looking forward to the joy of installing some forthcoming Update 4.&lt;/p&gt;

&lt;p&gt;Oh, I should finish taking out remaining CbCr code (in the OpenGL build of the game, which is used for Linux + Mac, and which I am not testing now, but might as well clean it up and take a line count). Current line count is 76,544. Looking up the file, last night’s was 76,972; that’s a savings of 428 lines. I am not sure why it’s not more, but maybe it just seemed like more than it is due to how pervasive the CbCr handling is. (Also, we are not counting LOC in shaders, and we probably saved at least 100 LOC there).&lt;/p&gt;

&lt;p&gt;Update stb_image.h to v2.12 (old version was 1.13 and was not a single-file header!) This appears to have worked perfectly and only took a minute, proving once again that single-file headers are the way to build and distribute libraries in C++.&lt;/p&gt;

&lt;p&gt;Line count went up because I guess I have been counting stb_image this whole time (it is embedded in the code, not tucked into a faraway place like bigger libraries). I guess I will keep counting it. Current count is 78,192.&lt;/p&gt;

&lt;p&gt;Test a while to see if I can repro that RtlValidateHeap thing. It seems to always be happening when deleting a temporary copy of one particular Mimic on one level (the Mimics are the rabbit guys). It’s happening because I took out a hack in the old code where I was setting a Mimic’s texture name to NULL after freeing it in the destructor – which is nonsensical – but it was preventing this bug, so I guess I am double-deleting the entity or just double-freeing the texture_name somehow (ugh!) and somewhat irresponsibly I did not leave a comment about what I was doing before and how bad it was (double ugh!):&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Entity_Mimic::~Entity_Mimic() {
    gamelib_free_string(texture_name);
    texture_name = NULL;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Because of ASLR this is now really hard to debug because I don’t have a way to uniquely identify this guy (in a world with no ASLR I can just set a breakpoint when we allocate that particular guy). If I had a robust time-travelling debugger I could go backward from the double-free to figure out how it happened … but I don’t.&lt;/p&gt;

&lt;p&gt;If it’s a double-free, then this assert should fire, but mysteriously, it doesn’t:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Entity_Mimic::~Entity_Mimic() {
    assert(texture_name != NULL);
    gamelib_free_string(texture_name);
    texture_name = NULL;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;I guess I am going to just log every deleted Mimic and see what I can reconstruct from that.
Wait, when I do that, there’s only one. AHA, the bug is that texture_name was actually a field of Entity, not Entity_Mimic, but Entity_Mimic’s destructor was freeing it, and of course it runs before Entity’s destructor. So the code with ‘texture_name = NULL’ was technically valid, but really not good. Fixed.&lt;/p&gt;

&lt;p&gt;Next appealing item on my list is simpifying Bitmap_Loader as mentioned in the previous posting. Looking through other code … it looks like I already did this for The Witness in October 2009 (the time I was beginning to get 100% serious on the project!) Copying that code over to Braid. Add ‘defer’ implementation to gamelib_core.h, switch weird Witness macros for deferred freeing to better general ‘defer’ implementation. There is no longer a ‘Bitmap_Loader’ class, we just load stuff via flat functions, so change all the calls made by the game to the new format.&lt;/p&gt;

&lt;p&gt;Oh dang, the old Bitmap_Loader had weird stuff for dealing with the loading-jpeg-alpha-layers-into-rgb-textures-all-in-one situation. Even though I am going to get rid of that later (probably some other day), it’s prudent to paste it back in for now and verify everything works. Oh, and yuck, this is snarled up with the async_jpeg stuff, obviously. Red alert, this is going to be nasty. We are going about this in the wrong order. Proper order is to clear out all the async jpeg stuff in game code, ensure the game works, then pull over the Witness bitmap loading code. Revert!!&lt;/p&gt;

&lt;p&gt;Need to load all the jpeg files and their corresponding alpha files, compress them into single DXT5 textures, and save. Installing nvidia texture tools both old and new. I don’t see any obvious way to load multiple source files into different channels with either of these. Maybe there is a way, or maybe I could figure out some tool to download on the internet and learn how it works, or maybe I can break out Photoshop and try to do something with action recording (may be difficult because of the filename correspondences, I don’t really know how to do that, it would take some research) … but absurdly the simplest/easiest path will be for me to just write C++ code to do the put-together – say, I can load the jpegs, save a 4-channel bmp for each jpeg rgb+alpha pair, and then run the NV texture tools on the BMPs.&lt;/p&gt;

&lt;p&gt;Whoops, I reverted the defer implementation along with the Bitmap_Loader stuff, let’s copy that back from the compiler project.&lt;/p&gt;

&lt;p&gt;So I bang out the following totally lovely one-time-use code, right into Braid’s main.cpp:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#include &quot;bitmap_loader.h&quot;
#include &quot;bitmap_data.h&quot;
#include &quot;bmp_save.h&quot;

void do_bmp_craziness() {
    Array &amp;lt;char *&amp;gt; filenames;
    Array &amp;lt;int&amp;gt; sizes;
    bool success = os_get_filenames_and_sizes(&quot;data/pieces&quot;, &amp;amp;filenames, &amp;amp;sizes);
    assert(success);

    Array &amp;lt;char *&amp;gt; rejects;

    for (int i = 0; i &amp;lt; filenames.items; i++) {
        auto name = filenames[i];  // &#39;name&#39; has no directory name info; it is just the filename.
        defer { gamelib_free_string(name); };

        auto s = strstr(name, &quot;.jpg&quot;); // Should be strrstr but Visual Studio doesn&#39;t have it; doesn&#39;t matter for this, eh.
        if (!s) continue;

        auto delta = s - name;
        assert(delta &amp;lt; strlen(name));
    
        auto name_copy = gamelib_copy_string(name);
        defer { gamelib_free_string(name_copy); };

        name_copy[delta] = &#39;\0&#39;;
    
        auto rgb_name = mprintf(&quot;data/pieces/%s.jpg&quot;, name_copy);
        defer { gamelib_free_string(rgb_name); };
    
        auto alpha_name = mprintf(&quot;data/pieces/alpha/%s.jpg&quot;, name_copy);
        defer { gamelib_free_string(alpha_name); };

        Bitmap_Data result;
        auto success = gamelib_core-&amp;gt;bitmap_loader-&amp;gt;load_bitmap(rgb_name, &amp;amp;result, alpha_name);
        assert(success);

        auto result_name = mprintf(&quot;data/pieces/output/%s.bmp&quot;, name_copy);
        defer { gamelib_free_string(result_name); };
    
        auto f = fopen(result_name, &quot;wb&quot;);
        assert(f);
        defer { fclose(f); };

        if (result.format != TEXTURE_FORMAT_ARGB8888) {
            rejects.add(gamelib_copy_string(name));
        } else {
            success = save_bmp_file(f, result.data, result.width, result.height, 32);
            assert(success);
        }
    }

    // Break here to examine rejects.

    int k = 1;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;So that didn’t take long (after fixing a couple of small bugs) and I even found several files that shipped with the game but should not have (they were redundant bitmaps that didn’t have corresponding alpha images, because they had been generated in earlier iterations of running the image-packer tool).&lt;/p&gt;

&lt;p&gt;Now I have a folder full of BMPs:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://number-none.com/blow/blog_videos/bmps.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;And it should be pretty straightforward to use nvdxt (an old program but I know how it works) to convert them to dxt:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;nvdxt -dxt5 -file *.bmp
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;(nvdxt is a bit slow even on today’s computers so I go brush my teeth but not before eating half a Lake Champlain Five Star Peanut Bar oh wait I mean three quarters).&lt;/p&gt;

&lt;p&gt;I come back and the .dds files are done.&lt;/p&gt;

&lt;p&gt;I comment out the beautiful one-time-use code but leave it in the file just in case.&lt;/p&gt;

&lt;p&gt;I move the jpegs to the side, move the .dds files over to where the jpegs were, and the game should just load them fine, fingers crossed, moment of truth …&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://number-none.com/blow/blog_videos/nuts.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Nuts. Well, it loaded them fine. My theory is that they are flipped. nvdxt has a -flip option and I try that quickly just on World 5 images just to see if it works:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;nvdxt -dxt5 -flip -file five*.bmp
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;https://number-none.com/blow/blog_videos/nuts2.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;That looks better! It’s still messed up, but some of the scene looks pretty okay, so it’s possible that everything messed up is just not world-5-specific assets. Let’s flip everything.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://number-none.com/blow/blog_videos/better.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Looking much better! However, there are still some obvious problems. Glancing through the levels, I am not immediately sure what is going on. Will have to A/B this versus older Braid tomorrow sometime to figure out the problem (possibly a file converted incorrectly, possibly I am forgetting some files somewhere, etc!) In the meantime this is a good place to stop for tonight.&lt;/p&gt;

&lt;p&gt;I should point out that these particular dds files that I just generated are temporary; once it is fully working, and the Bitmap_Loader code is simplified, I’ll go back to the Braid archival files and grab images that have not been through jpeg compression and back (provided I saved the post-packed images and don’t have to regenerate them from Photoshop PSDs, which could get hairy for totally other reasons.)&lt;/p&gt;
</description>
        <pubDate>Sun, 17 Jul 2016 22:50:00 -0700</pubDate>
        <link>https://number-none.com/blow/blog/programming/2016/07/17/braid_code_cleanup_2.html</link>
        <guid isPermaLink="true">https://number-none.com/blow/blog/programming/2016/07/17/braid_code_cleanup_2.html</guid>
        
        
        <category>programming</category>
        
      </item>
    
      <item>
        <title>Braid Code Cleanup (part 1)</title>
        <description>&lt;p&gt;I am still puzzling through the right way to think about some ideas in compression, so let’s take a break from that and talk about generally cleaning up the source code.&lt;/p&gt;

&lt;p&gt;To ease the maintainability of the game going into the future, there are many things that could be done. I’ll detail some of those here. I just spent a few hours trying the most obvious of these; I’ll list the completed tasks first, along with their impact on the source code.&lt;/p&gt;

&lt;p&gt;Before this process, the Braid source code was 95,366 lines, counted using:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cloc --no3 --by-file-by-lang
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;As always, the reported number excludes comments and blank lines. This is just counting source from the game, not including third-party libraries, and in fact missing a few pieces of the game like the shaders, scripts for building and installing on various OSs, etc. But it’s a pretty okay measure of the size of the program.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Things Done So Far&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Delete a bunch of unused code from the game: 10,254 lines removed.&lt;/strong&gt; Back at the time, Braid was built using the body of code that had been ‘my game library’; I never knew what code Braid might and might not use, so I just left everything in there in case I might want it. At this point, all that code is old enough that even if I did want to reuse some piece of it, it should be rewritten anyway or at least given a good looking-at.&lt;/p&gt;

&lt;p&gt;Code deleted: Priority queue, timed-average and timed-average-variance, float quantization and encoding, arithmetic coder, networking, byte packing for network packets, mesh and skeletal animation code, triangle intersection, Jenkins hash, crc32, triangle intersection, cubic spline fitting and editing, view frustum, two different proximity grids, Fridge memory allocator, redundant directory navigation code, bit array.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Remove Xbox-360-specific code: 3,694 lines removed.&lt;/strong&gt; Remove a bunch of special-case code surrounded by #ifdef XBOX360. Examples: annoying cert requirements about user profiles, menus, leaderboards, xbox live achievements, special cases for launching Speed Run from Xbox interface. The game was also ported to the PlayStation 3, but this was done by an outside party in a different branch of the source, so I did not have to worry about that now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Get rid of Demo functionality / upgrading to ‘full game’: 319 lines removed.&lt;/strong&gt; Demos are complicated to manage (on systems that don’t support demos well, which is most of them, it multiplies the number of builds you have to manage by 2 and adds lots of complicated details). Also, demos are not really necessary today; if people want to find out about a game, they can look on YouTube or read what many many people have to say about the game on the internet. On platforms like Steam, players can return a game (that’s been played for less than two hours) for a full refund, so a large part of the reason for a demo has been removed (you could view a demo as a way of not getting screwed by paying for something that’s terrible, but refunds do that too). Empirically, on Steam, very few people download the demo any more.&lt;/p&gt;

&lt;p&gt;This only removed 319 lines, but those 319 lines contained a lot of ‘if’ statements and complications around key moments of game flow, so this is a pretty good win.&lt;/p&gt;

&lt;p&gt;Data-wise, this also allowed me to remove 3 game levels that were only used in the demo. There are still some complications hanging out in the game data that could be removed (such as member variables on various entities that help control game flow in the demo). There are also a bunch of strings that can now be deleted.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Get rid of non-Steam PC online publishers that have folded: 31 lines removed.&lt;/strong&gt; Removed ifdefs for GREENHOUSE, IMPULSE, GAMERSGATE. Not a lot of code, nor was it very complicated, but hey, it’s gone now.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;That’s everything I have done so far. We’ve dropped the number of lines of code from 95,366 to 81,068, which is a nice start.&lt;/p&gt;

&lt;p&gt;Here’s the list of clean-ups that are pending. I’ll cover the impact of each of these in future postings as they happen. I’ll certainly also think of more things to clean up.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use C++11 initializers to initialize class members; eliminate constructors where appropriate.&lt;/strong&gt; Prior to C++11, you had to initialize values in a constructor separately from where they are declared. These tend to live in separate files if you care about compile time and readable headers. There’s no good reason for this, and I had long considered it a basic problem in C++, but it was addressed in C++11. In some cases, last I checked, you still can’t do the “right thing” (for example if you want to initialize values in a base class). This should reduce the number of lines of code in the program by a fair amount, and reduce error-proneness (since propensity for failing to initialize things will be reduced) but it will also be very tedious, so I may do it in parts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Eliminate Bitmap_Loader_Module system.&lt;/strong&gt; When I first put together my ‘engine’, I knew I would want to load bitmaps of varying types. So I built a system where there is a Bitmap_Loader, and you tell it what filename you want to load, and it parses off the extension, then looks at each Bitmap_Loader_Module to determine whether it handles that extension. The ‘nice’ thing about this was supposed to be that I could implement support for new formats just by dropping new files into the project, without any other part of the project knowing about them (since the new Bitmap_Loader_Modules would register themselves with the Bitmap_Loader via a constructor on a global variable). This is a very ‘abstracted engine’ way of thinking, and you know what, meh. By which I mean after years of experience this way of structuring the code has turned out to be no more useful than just editing a hardcoded procedure that looks at a file extension and calls the appropriate code. (And while being no more useful, it takes more effort to maintain, and took longer to write – there’s boilerplate code there, and an API that each Bitmap_Loader_Module must conform to, and it’s just not necessary).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Drastically simplify bitmap loading.&lt;/strong&gt; Originally, bitmap loading in Braid was pretty simple. But then, toward the end of the project, it became clear that the game would not fit in memory on the Xbox 360 (which had 512MB of physical RAM, but of course a game could not use all of that), even if all the bitmaps were compressed as DDS. One option would have been to introduce dynamic bitmap streaming, and pause as you enter each level until bitmaps are loaded. But the Xbox 360 was slow, and the file format that Xbox Live games had to use was &lt;em&gt;extra&lt;/em&gt; slow, and this just seemed like it would complicate a lot of things and negatively impact the player’s experience. Instead, I chose to make the game fit into RAM. Jpeg gets much better compression than dds, so I stored most bitmaps as jpeg (in two different files, one for color and one for alpha, because jpeg did not handle 4-channel images in practice at that time). But we also needed to keep things small on the GPU, so the jpegs would be decoded and uploaded to the GPU as two different textures, one for the Y channel, and one for the CbCr channels, with CbCr downsampled just as it is in jpeg. But we kept the character animation sheets in DXT because these needed sharp edges. So all shaders needed to have two variants, one for a DXT texture and one for a combination of Y/CbCr textures; all game-level logic about setting textures and applying shaders needed to understand this too. It complicated things by a lot. (Fortunately, Sean Barrett did all this stuff as we were getting close to ship time, so I was able to focus on meeting the Xbox 360’s certification requirements). Finally, because jpeg decompression was not particularly fast on an xbox 360, the game asynchronously decompresses jpegs with a primitive job system; and because none of this was foreseen by the ‘Bitmap Loader Module’ system mentioned above, ability to work with this was hacked into that system in an ugly way.&lt;/p&gt;

&lt;p&gt;It all works, but it is not very nice going into the future. Furthermore, there are performance implications (the Y and CbCr textures are stored on the GPU with LINEAR layouts, which becomes increasingly less fast with each generation of GPUs.) So I plan to simplify back to a scheme where we use DXT or whatever other natively compressed format the GPU understands, possibly employing a transcoder library such as the one from &lt;a href=&quot;http://binomial.info&quot;&gt;binomial.info&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Frame rate and fullscreen-mode stuff.&lt;/strong&gt; This one is going to be &lt;em&gt;interesting&lt;/em&gt;. During development, I was very conscious that I wanted Braid to have consistent physics, regardless of platform or frame rate (on a console, varying frame rate was not really a problem, but on PCs broadly, you have no idea how fast you are going to be able to run on some random unknown machine.) It seemed reasonable to say, 60Hz is the target frame rate, and we design for that, and we won’t ever run faster. (“60Hz should be enough for anyone”). I wrote a physics routine that was meant to run every 1/60sec, which I figured was enough to prevent tunneling. On consoles, we would always run at 60; on PCs, we would run at even multiples of 1/60 sec, the idea being that we would just run the same physics step multiple times, which gives results consistent with just having run it once per frame for many frames. This restricted us on the PC to frame rates that evenly divide 60: 60Hz, 30Hz, 20Hz, 15Hz, 12Hz, 10Hz, etc.&lt;/p&gt;

&lt;p&gt;On the PC, I needed to pick one of these frame rates and stick to it, so at startup, the game spends 0.7 seconds rendering a moderately heavy test scene, and seeing how quickly it is able to do that (throwing away the first few frames to discard any effects of non-resident texture maps or cold memory). The game then sets its frame rate to the highest rate it thinks it can consistently hit. If during gameplay it ever starts missing that frame rate, it then drops to the next stable frame rate.&lt;/p&gt;

&lt;p&gt;It’s actually more complicated than this, because there is an option to remove visual effects to gain speed, so this startup sequence tries both quality levels, too. And there’s an option to drop resolution to half, so the startup sequence tries that, too (if necessary).&lt;/p&gt;

&lt;p&gt;On Windows, because the scheduler is coarse and not meant for what we would today consider solid multimedia applications, it is pretty hard to page-flip your game at exactly 60Hz unless you are synced to a 60Hz display signal. Because Braid uses DirectX9, syncing the display at 60Hz meant going into fullscreen exclusive mode (because you couldn’t vsync in windowed mode). And the problem there is that fullscreen exclusive mode in Windows has always, &lt;em&gt;always&lt;/em&gt; been a complete disaster, and very high up the list of support issues. It triggers driver bugs, it makes your game look distorted and ugly (because for some reason monitor and TV vendors decided that if you switch to an aspect ratio different than the one supported by the display, the right thing to do is to STRETCH THE IMAGE NON-PROPORTIONALLY TO FILL EVERY PIXEL OF THE DISPLAY, &lt;strike&gt;FFFFFUUUUUUUUUCK YOOUUUUUUUUUUUU you assholes&lt;/strike&gt;). It causes Windows to lock up sometimes. It makes your monitor go black and flail for an awkward few seconds. Whatever happens, it is almost never good.&lt;/p&gt;

&lt;p&gt;Because all of this is so terrible, games these days tend to render at whatever frame rate and resolution the desktop was already in – just not monkeying with the video mode at all. This often requires rendering many more pixels than before, or else rendering to an offscreen surface and upscaling, but GPUs are fast these days, so it’s not that big a deal. However, Braid can’t necessarily do this in a straightforward way (even after switching to a newer DirectX that allows us to vsync in windowed mode), because if the player’s desktop refresh rate is not one of the frame rates listed above, we can’t vsync! So we would have to tear (which looks bad) or change the display frequency (which may cause a lot of problems).&lt;/p&gt;

&lt;p&gt;The assumption that “60Hz should be enough for anyone” also, of course, is no longer valid. 144Hz monitors are very popular, G-SYNC is sort of a thing (even though nobody I know understands how to properly render on a G-Sync monitor) and who knows what is going to happen in the future. So, the following stuff needs to happen:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Rewrite the physics system to produce consistent results at arbitrary frame rates&lt;/li&gt;
  &lt;li&gt;Change the display code to run at desktop resolution and frame rate&lt;/li&gt;
  &lt;li&gt;Change the DX version to support vsync in windowed mode (maybe by using DXGI, though that is scary and problem-causing, so maybe by upgrading to DX11, which, also yuck).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All this said, it’s worth pointing out that in world 4 (where time moves as you move) we had to simulate for arbitrary amounts of time based on how quickly you were moving, and whereas I did not do anything super dumb here (for example, I subdivide the timestep to try and produce somewhat-consistent results), as the code is structured now, there’s no way to make the results fully consistent with the rest of the game, because you are by necessity seeing results in-between the 1/60 sec official physics samples. This doesn’t seem to have caused problems that anyone notices, so it might be that so long as the physics timestep is below a certain size, nobody will ever complain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Complete upgrade to Visual Studio 2015; fix header file mess.&lt;/strong&gt; Yesterday I switched to Visual Studio 2015. The launcher no longer compiles, for mysterious reasons, but everything else works fine. Need to fix the launcher. Need to set up the Visual Studio 2015 redist for the Steam install. Need to figure out whatever timebombs Microsoft has put into Visual Studio 2015 this time that make software harder to reliably distribute (figure out Windows XP compatibility situation, figure out whatever other options I need to turn off to disable telemetry, prevent weird undesired dependencies). Fix header files that have been missing from the project file forever, which makes global-search-and-replace in Visual Studio not effective.&lt;/p&gt;

&lt;p&gt;In my newer work the goal is to get away from Visual Studio forever, but that won’t happen for Braid any time too soon, so I might as well keep it nice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Get rid of Pool, use Isolated_Heap_Pool.&lt;/strong&gt; Pool is a simple fast allocator, the default flavor of which just uses the C runtime’s malloc on the back end. Isolated_Heap_Pool is a variant of this that creates a separate heap per Pool, which means you can create a bunch of Pools and then destroy them and not worry about causing fragmentation. This was done because on consoles, fragmentation had been a big problem. I might as well keep things this way, since it’s cleaner, but the old Pool is still used by my font code. So if I change the font code (should be a trivial change) I can remove pool.cpp and pool.h.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Make Entities_By_Type use Array and not List. Remove List.&lt;/strong&gt; List is a linked-list data sturcture. In Braid, every kind of entity has an array of all instances of that entity type. Often gameplay code iterates over such a list (“for every monster in the level, do the following.”) The problem is that linked lists are not very good for cache behavior in this kind of use case (where the collection is seldom modified, and traversed very frequently). So, I want to change this to use an array structure. It’ll be tedious since a lot of sites traverse the lists, and even though they use macros to do it, the list-ness pokes its head into user code sometimes. But it won’t be too bad. We already made this change on The Witness, and it was very helpful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Remove add_color and weird use of multiply_color.&lt;/strong&gt; Back during development, I knew I wanted the screen to fade to black sometimes, and to white at other times. However, GPUs were slow enough that it was not clear we could afford a postpass on most machines. So fade-to-black is achieved by a per-entity multiplicative color that goes down to 0, and fade-to-white is achieved by a per-entity additive color that goes up to 1. This does not give exactly the same effect as a full-screen fade but it is ‘close enough’ and nobody has ever noticed or complained. However, this prevents us from doing more-sophisticated transitions, and passing those extra colors around has speed implications. The code will get simpler if I just enact all these fades in a post-pass. Then, after that, we can work on doing something more interesting with them.&lt;/p&gt;
</description>
        <pubDate>Sat, 16 Jul 2016 16:50:00 -0700</pubDate>
        <link>https://number-none.com/blow/blog/programming/2016/07/16/braid_code_cleanup_1.html</link>
        <guid isPermaLink="true">https://number-none.com/blow/blog/programming/2016/07/16/braid_code_cleanup_1.html</guid>
        
        
        <category>programming</category>
        
      </item>
    
      <item>
        <title>Braid Particle System Revision (part 2)</title>
        <description>&lt;p&gt;Previously, discussed the particle systems in Braid. They need to be generated differently from the way most games do it; this created more difficulty with regard to random number generation than games usually have.&lt;/p&gt;

&lt;p&gt;Back when Braid shipped, I had determined that a more-random seed would give me better behavior; so I got a more-random seed by pre-generating a table of high-quality random numbers and indexing that table based on the ID of a particle source. This seemed messy, so a couple of weeks ago I replaced the existing LCG random number generator with PCG, which is higher-quality but slower. This resulted in code that was more elegant, but the solution seems like overkill. So now I want to go back and re-solve the quality issue in a way that is elegant but also fast.&lt;/p&gt;

&lt;p&gt;Here are a few possible approaches:&lt;/p&gt;

&lt;p&gt;(A) Go back to BCPL’s LCG as the random-generation scheme, and just find a simpler way to generate a seed that produces better results, essentially by hashing the particle index in some way. Such a hash should be fast and simple. (You can think of the table full of Mersenne Twister-generated numbers as a precomputed hash; it’s a little weak due to the limited table size, and it also involves storage. We should be able to come up with something simpler.)&lt;/p&gt;

&lt;p&gt;(B) PCG provides the feature of being able to fast-forward some number of steps. In the PCG paper, it is mentioned that all LCGs have this property, it’s just not commonly appreciated. This means we could figure out how to implement fast-forwarding for our old LCG, which then means we would not have to re-seed it per particle; we just seed it once per source, then fast-forward to the particular particle we want. Since we are no longer re-seeding, this should eliminate the associated quality loss.&lt;/p&gt;

&lt;p&gt;(C) Use a different scheme for generating random-ish numbers that is more amenable to arbitrary seeking within the stream. For example, &lt;a href=&quot;http://marc-b-reynolds.github.io/shf/2016/04/19/prns.html&quot;&gt;Marc Reynolds wrote this simple library for random-access pseudorandom numbers using Weyl sequences&lt;/a&gt;. At first glance, this looks like it could be applicable.&lt;/p&gt;

&lt;p&gt;I tried option (A), and it worked great. In the next blog post, I’ll go over details of what I did there. But let’s explore our options more fully, and talk about (B) and (C).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option (B): Fast-Forwarding&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In &lt;a href=&quot;../../../2016/07/08/fabian-on-lcg-fast-forward.html&quot;&gt;Fabian’s guest post&lt;/a&gt; we get a pretty good idea of what would be involved in a fast-forwarding scheme. He goes way beyond the basics; for the purposes of understanding how to use this in Braid, you can stop around the middle of the posting. It’s clear: we don’t have to re-seed the LCG for every particle; instead, we could start at a known good seed and then fast-forward to a particular particle index. The downside is that fast-forwarding is going to be more complicated than seeding (the iteration to calculate the right exponent is a little complicated, and the table-lookup requires the existence of the table which is also a complication). You might think that performance here would also be bad, but we only need to fast-forward once per particle source; after that, we just step once per particle. So the cost of the fast-forward is amortized across the average number of particles per source. Also, you’re reading from a table, but that table is small and constant for all particle sources, so if you process all your particle sources at once, the performance hit from this table should be very small.&lt;/p&gt;

&lt;p&gt;Fast-forwarding invites code fragility, though. The number of steps by which you’d want to skip forward is the index of a particle times the number of random numbers generated for each particle. Because code changes over time, you can be almost guaranteed that some new random numbers will be added to per-particle generation eventually, which will badly break the appearance of particles in a way that will confuse anyone who isn’t intimately familiar with the technique. To prevent this, we can be conservative and reserve more random numbers per particle than we actually need right now; say, 100. We probably won’t ever reach that limit, but now that limit has to be documented in the code, and that’s a complication. If we ever do exceed that limit, we probably aren’t going to detect the situation automatically (because adding code to check this at runtime is going to be slow, and there’s no good way to check it at compile time in C++), so again, the symptom is that our particles mysteriously break in a confusing way.&lt;/p&gt;

&lt;p&gt;Also, suppose I want to extrapolate a particle system backward in time to before its time of creation. With the current per-particle seeds, this just works automatically. With a fast-exponentiation scheme, we would have to handle negative exponents somehow; maybe that can be done quickly, but at first glance it seems shaky. This would also complicate the code. So instead we can say that all particle sources begin, not at particle #0, but at particle number one million or something, and we can go backward in time up to one million particles earlier than that source’s official t = 0. But again this creates a limit in the code that we might one day exhaust unexpectedly. These kinds of limits are prominent reason why software is often overcomplicated and broken.&lt;/p&gt;

&lt;p&gt;For these reasons, I decided not to implement a fast-forwarding scheme. I regard fast-forwarding as useful to understand for my own personal edification, but undesirable as a way to implement anything for Braid (unless other approaches end up causing bigger problems, somehow!)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option (C): Generators That Support Constant-Time Seeking&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If we really needed random-access navigation through a stream of pseudorandom numbers, the Marc Reynolds code linked above would be an interesting thing to try. However, if option (A) works (which, again, it did, as we’ll see next time), then we would only want to adapt this method if it offers benefits for this particular application.&lt;/p&gt;

&lt;p&gt;Browsing through the code, it’s clear that it is slower than our LCG (which is not surprising, since LCGs are fairly minimal). This code performs 64-bit integer operations, rather than the 32-bit operations we are using now, so it is going to be slower (or possibly just use more ALU resources, generating more heat or increasing battery usage, etc). Also, the mixing step is more expensive than the mixing step from our LCG.&lt;/p&gt;

&lt;p&gt;Looking at the math here, the reason this generator is easily seekable is just because each step only changes the state by adding one constant to it, so moving N steps is the equivalent of adding N times that constant. Note that LCGs have two constants, a multiplicative and an additive constant. So this is equivalent to an LCG where the multiplicative constant is 1. Thus this generator seems like it could be strictly lower-powered in its ability to generate random-seeming results. As Reynolds says in the documentation for this code,&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The state update is so simple that the burden of producing a sequence with statistical random properties is on the shoulders of the bit finalizing function.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Essentially, the stepping part of the generator is just adding a really really big number with a scattered bit pattern as a way of giving us reasonably-well differing bit patterns to feed into the mixing step, and the mixing step is doing most of the work. This explains why it’s more expensive than a typical mixing step for an LCG.&lt;/p&gt;

&lt;p&gt;If you were to carry this idea further: with a good enough mixing function (say in the extreme a cryptography-grade hash function), you wouldn’t even need the Weyl sequence – you could just feed in the particle index and get out a very random-seeming sequence of bits. This is conceptually simple but in practice is going to be much more expensive. Part of the magic of an LCG is that it gives you something so random-seeming with so little work. Cryptographic hashes, on the other hand, are willing to do a great deal of work in order to make sure things are as close to random as possible.&lt;/p&gt;

&lt;p&gt;Anyway, since we don’t really need to seek to arbitrary indices, I did not see a justification in going this way. It is good to keep in mind, though, since it may come in handy at some point!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next Time&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As I mentioned, I solved the quality problem by improving the quality of the seed fed to the LCG.
Next time we’ll look at the implementation details.&lt;/p&gt;
</description>
        <pubDate>Wed, 13 Jul 2016 17:32:00 -0700</pubDate>
        <link>https://number-none.com/blow/blog/programming/2016/07/13/braid_particles_2.html</link>
        <guid isPermaLink="true">https://number-none.com/blow/blog/programming/2016/07/13/braid_particles_2.html</guid>
        
        
        <category>programming</category>
        
      </item>
    
      <item>
        <title>Fast-Forwarding LCGs</title>
        <description>&lt;p&gt;&lt;em&gt;This is a guest post by Fabian Giesen. Actually it’s an off-the-cuff email, so please tolerate that it may be a little sketchy. In the next post about working with Braid’s particle systems, I want to visit the idea of fast-forwarding LCGs. Fabian really ran with the idea here, and since I am going to summarize the idea in the next post, it felt best to have the full piece here for reference.  -J. Blow, 8 July 2016&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Just realized an interesting (maybe?) twist on this. So the basic idea for the fast-forward is just that a LCG-style update&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;x_{k+1} = a*x_k + b
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;has&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;x_{k+2} = a*x_{k+1} + b = a*(a*x_k + b) + b
        = (a^2)*x_k + (a*b+b)
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;so if you describe a LCG by its coeffs (a,b), then stepping it at twice the rate yields another LCG with coeffs (a^2, (a+1)*b). (This is the direct approach, but of course you can also just do it by writing the LCG update in homogeneous matrix from and multiplying it out as Jon suggests). You’re back in the same form you started with and now have coeffs for a LCG that proceeds twice as fast as the source LCG.&lt;/p&gt;

&lt;p&gt;So the basic fast-forward is just the fast-exponentiation style:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;uint cur_a = a;
uint cur_b = b;
uint x = x0;

while (n) {
    if (n &amp;amp; 1)
        x = cur_a*x + cur_b;
    cur_b *= cur_a + 1;
    cur_a *= cur_a;
    n &amp;gt;&amp;gt;= 1;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Okay, that’s background.&lt;/p&gt;

&lt;p&gt;But we don’t generally have “a” and “b” different for every invocation; usually we pick one set of LCG coeffs and stick with them as our RNG, which means the sequence of “cur_a” and “cur_b” values is completely predetermined.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;// init (or just bake into table ahead of time)
// good for 32-bit &quot;n&quot;
uint lcg_a_bit[32], lcg_b_bit[32];
uint cur_a = a, cur_b = b;

for (int i = 0; i &amp;lt; 32; ++i) {
    lcg_a_bit[i] = cur_a;
    lcg_b_bit[i] = cur_b;
    cur_b *= cur_a + 1;
    cur_a *= cur_a;
}

// runtime eval
uint x = x0;
for (int bit = 0; (n &amp;gt;&amp;gt; bit) != 0; ++bit)
    if ((n &amp;gt;&amp;gt; bit) &amp;amp; 1)
        x = lcg_a_bit[bit]*x + lcg_b_bit[x];
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;So here’s the actual realization: if you’re willing to live with a bit of precomputation, there’s really no need to limit yourself to binary steps. You might as well do multiple bits at a time, something like:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;// runtime eval only this time
uint x = x0;
for (int i = 0; n != 0; ++i, n &amp;gt;&amp;gt;= 4)
    x = lcg_a_tab[i][n &amp;amp; 15]*x + lcg_b_tab[i][n &amp;amp; 15];
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;where lcg_?_tab[i][j] contains the coeffs to step the LCG (j&lt;em&gt;16^i) times; this particular choice of parameters needs (32/4) * (2^4) = 8&lt;/em&gt;16 = 128 table entries (so 256 uint32s for a 32-bit LCG).&lt;/p&gt;

&lt;p&gt;This is still O(log N), but it’s a log to a larger base, so the constant factor is smaller. You can get relatively far with a moderate table size, which is fine as long as all those calcs happen in a relatively tight loop so the table stays warm in L1. For example, 8 bits at a time needs (32/8) * 2^8 = 1024 table entries working out to 8KB for a 32-bit LCG, which then allows you to step the LCG to an arbitrary position in exactly 4 (serial) multiply-adds.&lt;/p&gt;

&lt;p&gt;-&lt;/p&gt;

&lt;p&gt;That part I think is kinda cool and still reasonably simple. This is the part where it gets a bit rambly.&lt;/p&gt;

&lt;p&gt;The computation above is very serial because we funnel everything directly into x. There’s more latent parallelism if we manipulate the generators directly. At this point it probably &lt;em&gt;is&lt;/em&gt; easier to switch to matrix form for clarity: (ASCII art, view with fixed-width font)&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;     x_1 = a*x_0 + b

-&amp;gt; [x_1]   [a  b] [x_0]
   [ 1 ] = [0  1] [ 1 ]
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;the stuff we’ve been doing so far is raising the matrix (let’s call it A) to the n’th power. I’ll also call the RHS vector ([x_0; 1]) just “x” (hopefully not too confusing).&lt;/p&gt;

&lt;p&gt;So what I’ve described so far is basically splitting&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;n = ... + n_2 + n_1 + n_0
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;and then computing&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  A^n * x
= A^(... + n_2 + n_1 + n_0) * x
= ... * (A^(n_2) * (A^(n_1) * (A^(n_0) * x))).
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;In the binary split, the n_i are just (i’th bit of n)*2^i.&lt;/p&gt;

&lt;p&gt;Computing it this way (immediately applying the matrices to the vector) is cheaper in terms of op count, but you can break the dependency chain up somewhat if you use associativity and set the parens differently. Say we have:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;n = n_3 + n_2 + n_1 + n_0
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;then we can compute it as&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;((A^(n_3) * A^(n_2)) * (A^(n_1) * A^(n_0))) * x
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The n3-by-n2 and the n1-by-n0 matrix mult can be done in parallel in this version, which is why this can help.&lt;/p&gt;

&lt;p&gt;If we write down “LCG arithmetic” for convenience:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;struct LCG {
    uint mul, add;
};

// this is just the matrix multiply
LCG mul_lcg(LCG a, LCG b)
{
    LCG x = { a.mul*b.mul, a.mul*b.add + a.add };
    return x;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Then we can have an alternative version of the fast exponentiation loop that is left-associative rather than right-associative (i.e. multiplies out all the matrices and then multiplies the result by the vector in the end:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;LCG combined = { 1, 0 }; // identity
LCG cur = base_lcg;

// accumulate LCG matrix
while (n) {
    if (n &amp;amp; 1)
        combined = mul_lcg(cur, combined);
    cur = mul_lcg(cur, cur);
    n &amp;gt;&amp;gt;= 1;
}

// final eval
x = combined.mul*x0 + combined.add;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;So far, not very appealing; as-is, this does more work. But it allows splitting into several dependency chains and/or vectorization within a single LCG evaluation; e.g. you can do stuff like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;LCG combined_lo = { 1, 0 };
LCG combined_hi = { 1, 0 };
LCG cur_lo = base_lcg;
LCG cur_hi = base_lcg_pow16; // precomputed

// accumulate &quot;low&quot; and &quot;high&quot; halves in parallel
// split at bit 16 of n (no early out this time)
for (int i = 0; i &amp;lt; 16; ++i) {
    if (n &amp;amp; (1&amp;lt;&amp;lt; 0)) combined_lo = mul_lcg(cur_lo, combined_lo);
    if (n &amp;amp; (1&amp;lt;&amp;lt;16)) combined_hi = mul_lcg(cur_hi, combined_hi);
    cur_lo = mul_lcg(cur_lo, cur_lo);
    cur_hi = mul_lcg(cur_hi, cur_hi);
    n &amp;gt;&amp;gt;= 1;
}

// final eval
x = combined_hi.mul*(combined_lo.mul * x0 + combined_lo.add) + combined_hi.add;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;here this is written scalar, but the (lo,hi) pair calcs could be SIMDed, and you can do more than 2 of these at a time. If you’re going wider, you probably want to do the “final eval” part using a reduction tree of matrix mults.&lt;/p&gt;

&lt;p&gt;…that said, all of this is interesting &lt;em&gt;strictly&lt;/em&gt; when viewed in isolation; i.e. you have individual “gimme LCG state at point n” calls.&lt;/p&gt;

&lt;p&gt;If they are in a loop, you don’t need any heroics to extract parallelism; multiple iterations of the loop can overlap all by themselves. (And e.g. SIMDing over iters is gonna work a lot better than making that stuff I just wrote work.)&lt;/p&gt;

&lt;p&gt;But I think it’s definitely cute.&lt;/p&gt;
</description>
        <pubDate>Fri, 08 Jul 2016 13:00:00 -0700</pubDate>
        <link>https://number-none.com/blow/blog/programming/2016/07/08/fabian-on-lcg-fast-forward.html</link>
        <guid isPermaLink="true">https://number-none.com/blow/blog/programming/2016/07/08/fabian-on-lcg-fast-forward.html</guid>
        
        
        <category>programming</category>
        
      </item>
    
      <item>
        <title>Braid Particle System Revision (part 1)</title>
        <description>&lt;p&gt;The game Braid originally shipped to the world in 2008, and after some ports in 2009, I have only worked significantly with the code on a few occasions. But I want to maintain this game indefinitely into the future; in the back of my mind, there have always been some clean-ups that I have wanted to perform on the code. Often when shipping a game, the best answer to a problem isn’t evident, and we are under time pressure, so we solve the problem in some way that is sufficient but sub-optimal. Other times, we need to design the game to meet technical constraints of systems we want to deploy on, but as the years go on, these systems become irrelevant, so the code can be cleaned up. I figured it would be interesting to talk about some of these things in a blog (and the blog will help motivate me to think about these situations and clean some of them up!)&lt;/p&gt;

&lt;p&gt;So, let’s talk about particle systems and random number generators.&lt;/p&gt;

&lt;p&gt;On the night of July 4th, instead of watching patriotic USA fireworks, I dug out the Braid code and replaced the random number generator. The old generator was the LCG used in BCPL. “LCG” stands for “Linear Congruential Generator”, which is a simple and efficient method of generating pseudorandom numbers. BCPL is a programming language from the 1960s (https://en.wikipedia.org/wiki/BCPL) that provided in its standard library an LCG with a particular set of constants. When starting the development of Braid, I was looking for a good random number generator, and a friend recommended this one to me, but it was sort of a guess on both our parts. You can find a list of LCGs and the constants used &lt;a href=&quot;https://en.wikipedia.org/wiki/Linear_congruential_generator&quot;&gt;in this Wikipedia article&lt;/a&gt;, and &lt;a href=&quot;http://random.mat.sbg.ac.at/results/karl/server/node4.html&quot;&gt;a more comprehensive list here&lt;/a&gt;. I will refer to this particular LCG as “BCPL” even though BCPL is really the name of the programming language.&lt;/p&gt;

&lt;p&gt;When using the BCPL random number generator to generate particles, I had needed to add some ugly workarounds to get good-looking results. These results are not necessarily the BCPL’s fault; it may just have to do with the way I was using it. So perhaps the proper initial step would be to figure out the way in which I was using BCPL incorrectly. But I was also motivated to experiment with PCG, a newly-invented random number generator that sounds really good. So I chose that as my first approach.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Like many games, Braid has particle sources, where the properties of each particle (position, velocity, size, rate of change of size, initial color, rate of change of color, etc) are produced by a pseudorandom number generator. Most games just generate these properties once when a particle is created, then simulate the particle forward in time once per frame, which is computationally inexpensive. But in Braid, one of the player’s primary actions is time manipulation, causing time to go forward and backward. The game needs particles to appear consistent as the notion of “current time” changes; if time goes forward so that a bunch of particles die, but then goes backward again, you want to see those very same particles fade back in and live their lives in reverse.  You could do this by using a classical particle system and storing the state of every particle, and restoring that state when time goes backward, but that would use a lot of memory very quickly. So the problem statement for Braid was, given the settings for a particular particle source, to be able to generate the state of the particles spawned by that source at any given time t, in a way that is relatively efficient with both computation and storage.&lt;/p&gt;

&lt;p&gt;I solve this problem by re-seeding the random number generator for every particle every frame – essentially undergoing the creation process for every particle every time it is rendered, and then simulating that particle to the current time. As long as the particle source knows exactly which particles will be active at a given time (which requires a constant emission rate, a fixed maximum lifetime, and other such constraints), then we don’t need to store the state of any of the particles. As long as the logic to evolve a particle through time is a simple closed-form function or other small piece of relatively straightforward code, that’s not too expensive computationally either (much cheaper than simulating forward N fixed timesteps from the starting state of the particle, where N can easily be in the hundreds or thousands).&lt;/p&gt;

&lt;p&gt;In most games, particles work something like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;to spawn N particles:
    for 1..N {
        generate position, size, color, rotation, etc of this particle,
            using a global random number generator that we don&#39;t think much about.
        add particle to simulation buffer
    }

at render time:
    N = dt * emission_rate
    spawn N new particles
    
    for each particle in each source {
        if particle has exceeded its lifetime, kill it, continue.
        
        simulate particle values incrementally by dt
            (position = old_position + velocity * dt, etc).
            
        store renderable values into the output buffer.
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;In Braid, the code for rendering particles is something like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;for each particle source in the current level {
    figure out index_first and index_last, the bounds on particle indices
        emitted by this source at this particular time (for example,

        index_last = floor(current_time * emission_rate);
        index_first = index_last - max_particles;
        
        (particle lifetimes are constant, so max_particles is constant; if
        you want a particle to die early, it just fades out completely, but
        still exists).

    for index_first..index_last {
        seed a per-source random number generator by this particle&#39;s index
            (multiplied by a large number or two, to make the seed seem more random).
        generate position, size, color, rotation, etc of this particle
            as they would be at spawn time.
        simulate the aforementioned values forward to current time,
            preferably using closed-form equations so it&#39;s cheap (if everything
            is closed-form, then this is just like the update step for a
            normal game, but using (current_time - spawn_time) for the dt.)
        store renderable values into the output buffer.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The reason you have to seed for each particle, rather than only once per source, is that the range of starting and ending particle indices will be changing every frame, so there isn’t any sensible starting point in time for your seed to designate. But by seeding for each particle, you suddenly don’t care about time any more.&lt;/p&gt;

&lt;p&gt;To my surprise, when I first implemented this, particles often looked bad. Correlations were visible between different particle attributes: for example, the X and Y components of each particle’s velocity were correlated, which biased particles to travel in some directions but not others; particle size was correlated in weird ways with speed, and so on.&lt;/p&gt;

&lt;p&gt;It did not surprise me that seeding for every particle made the numbers less random, but I had not expected the decreased randomness to be so visually objectionable. Of course I tried several of the obvious solutions, like only using the upper bits of the LCG’s output, but they didn’t seem to matter much.&lt;/p&gt;

&lt;p&gt; &lt;br /&gt;&lt;/p&gt;
&lt;video controls=&quot;&quot;&gt;
&lt;source src=&quot;https://number-none.com/blow/blog_videos/braid_unfixed.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;
&lt;p&gt;&lt;strong&gt;Braid particles with undesired correlations.&lt;/strong&gt; (See the patterns in the triangular particles that fade in as the character visits each podium.)&lt;br /&gt;
 &lt;br /&gt;&lt;/p&gt;
&lt;video controls=&quot;&quot;&gt;
&lt;source src=&quot;https://number-none.com/blow/blog_videos/braid_fixed.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;
&lt;p&gt;&lt;strong&gt;Braid particles after fixes have been applied.&lt;/strong&gt;
 &lt;br /&gt;
 &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;I did not know a lot about the practical usage of random number generators (I still don’t!), but I needed to fix this problem, so I’ll now explain the solution I arrived at.&lt;/p&gt;

&lt;p&gt;It seemed clear that seeding for each particle was causing the problem. This would be very unsurprising if I were just using each particle’s index as the seed (since these indices are small integers in sequence), but I had been multiplying the index by some large number in an attempt to make it seem more random, and to give it many more bits for the LCG to work with. Apparently this had not been enough. So, what if I generated some table of higher-quality random numbers at startup (using a scheme that would be too slow to use when rendering particles), and then I indexed that table per-particle to retrieve a good random number that I would use to seed the LCG for each particle? As mentioned, I didn’t know too much about random number generation, but I knew the Mersenne Twister was supposed to be “high-quality but slow”, so I used that. The code is shown below. (Note: I am not recommending that this is a good solution; it is just how I got things working at that time. It is interesting, though, in that it solved the problem in a shipping game that’s been played by a million or two people.)&lt;/p&gt;

&lt;p&gt;Here’s how I set up the table of higher-quality random numbers:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;const int NUM_NUMBERS = 127;
globals.particle_randomization_table_size = NUM_NUMBERS;
globals.particle_randomization_table = new unsigned long[NUM_NUMBERS];

Random_Generator_Mersenne mersenne;

// (This is me writing this comment in 2016):
// The seed number below is a traditional way of initializing the Mersenne Twister, 
// but M.E. O&#39;Neill makes the case that you can&#39;t well-seed this RNG with only 32 bits:
//           [http://www.pcg-random.org/posts/cpp-seeding-surprises.html](http://www.pcg-random.org/posts/cpp-seeding-surprises.html)
// I chose a fixed seed so that successive runs of the game are identical.
// Thus I could have just replaced this init code with an array literal containing
// pre-generated output numbers, but I think I figured the impact on startup time was small
// and that I preferred the flexibility of keeping this code live so I could change it at will.

mersenne.seed(19650218UL);

for (int i = 0; i &amp;lt; NUM_NUMBERS; i++) {
    globals.particle_randomization_table[i] = mersenne.get();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;When computing the particles during each frame, the table was used in this way:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    int randomization_cursor = (first_particle_index + num_particles - 1) % globals.particle_randomization_table_size;
    if (randomization_cursor &amp;lt; 0) randomization_cursor += globals.particle_randomization_table_size;

    for (int i = num_particles-1; i &amp;gt;= 0; --i) {  // We iterate backwards because we draw new particles beneath older particles, as this just looks better; and most-obscured particles draw first, for Painter&#39;s Algorithm reasons.
        int particle_index = first_particle_index + i;

        // The next two lines are an optimization to avoid using a modulus operator per particle.
        // We really want to do: particle_index % globals.particle_randomization_table_size;
        // Note that particle_randomization_table_size is not a power of two, intentionally. (It&#39;s close though!)
        // I am presuming the &#39;if&#39; gets compiled into a CMOV.
        
        int randomization_index = randomization_cursor;
        if (--randomization_cursor &amp;lt; 0) randomization_cursor = globals.particle_randomization_table_size-1;

        unsigned int number_a = globals.particle_randomization_table[randomization_index];

        // &#39;gen&#39; is the random number generator.
        gen.seed(number_a * particle_index * big_number);

        // The rest of the particle generation logic goes here, for example:
        p.lifetime  = lerp(lifetime0, lifetime, gen.get_zero_to_one());
        p.size      = gen.get_within_range(size_scale_0, size_scale_1);
        p.dtheta_dt = gen.get_within_range(scaled_dtheta_dt_0, scaled_dtheta_dt_1);
        p.theta0    = lerp(theta0, theta1, gen.get_zero_to_one());
        ...
        // Including a lot more code that does the simulation part.
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;You’ll note here the presence of a variable ‘big_number’ inside the seed argument. big_number is computed in the following way, once per particle system (not once per particle):&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    gen.seed(source-&amp;gt;portable_id * 13482034981);  // @Hack: This number is meaningless, I just banged on the keyboard.  It could be a really bad number.
    gen.get();
    gen.get();
    gen.get();
    gen.get();
    gen.get();
    gen.get();
    unsigned int big_number = gen.get();
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;For context, gen.get() looks like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;inline u32 Random_Generator::get() {
    state = state * 2147001325 + 715136305; // BCPL generator
    // Shuffle non-random bits to the middle, and xor to decorrelate with seed.
    return 0x31415926 ^ ((state &amp;gt;&amp;gt; 16) + (state &amp;lt;&amp;lt; 16));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Note my continuing commitment to quality there where I call gen.seed for the particle source (yes, that comment is from the original source code). I suppose I should have investigated whether that number is pathologically bad for BCPL.&lt;/p&gt;

&lt;p&gt;So, per particle system, I am seeding once by the ID of the particle system (so this is constant per-particle system), then generating 6 ‘random’ numbers and throwing them away, then using the seventh. I throw 6 away because I was finding this necessary to keep the visual appearance of randomness, even using the Mersenne Twister starting table. After 6 numbers, things looked random enough.&lt;/p&gt;

&lt;p&gt;I did not feel great about this. Sure, these extra generations were happening only once per particle system, rather than per particle, but in Braid a lot of particle systems contain relatively few particles, and speed was at a premium. (On the Xbox 360 I’d had to write a SIMD version of the particle generation code in order for the game to hit 60fps everywhere).&lt;/p&gt;

&lt;p&gt;But when you’re shipping a game, you have so much to worry about that some things just fall off the table. The disciplined approach would have been to stop trying to mix a bunch of numbers together in a bowl and hope it magically works, and instead learn more about random number generators, and find a simpler and cleaner solution. But if I had done that, the game would have come out later (or not at all; I was having a hard time psychologically by the time the game was finally done, 3.5 years into the project, and many independent game development efforts collapse long before the game is done).&lt;/p&gt;

&lt;p&gt;So instead, I mixed a bunch of numbers together in a bowl, and after trying a few things it worked well enough.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Of course, it wasn’t quite that simple, because there were 4 variants of the particle-generation code that were mostly copies of each other: (1) the slow path to fill out to seed the initial state of a particle system, (2) to iterate the state of those particles forward quickly every frame, (3) to implement the special case of particles along a line (for the sun only), and (4) to implement the particles for the Ring in world 6 (the calling site is actually ifdeffed out, but this code is still hanging around for some reason, presumably because I thought it might come back at some point).  (3) and (4) were factored into their own implementations so that they would not slow down the particle evaluation in (2) with extra conditionals.&lt;/p&gt;

&lt;p&gt;What is extra fun is that (1) and (2) need to compute exactly the same result, otherwise you’ll get discontinuities when particle systems wrap or when rewind is engaged. I had forgotten this when I started doing this particle system revision, and I spent about 20 minutes trying to figure out what was going on before I saw how things are structured.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;This clumsy randomization hack has been sticking in the back of my mind as one of the things I am vaguely unhappy with in the Braid code. (It is not nearly the worst, because this one isn’t visible to the user; there’s other stuff, like the camera handling and occasional collision detection weirdness, that upset me more because you feel them when you play).&lt;/p&gt;

&lt;p&gt;For some reason, this week I decided to fix it. As it turns out, simply by using PCG instead of BCPL, I was able to strip out the hacks, leaving only the “straightforward” system of re-seeding for each particle based on its index.&lt;/p&gt;

&lt;p&gt;I was able to remove the Mersenne Twister completely from the codebase (two files containing 79 lines of code (not including blank lines and comments)). Then, after simplifying away all the extra code that generated and used that precomputed table, I saved another 62 lines of code, for a total of 141. Most of the code in the listings above has been removed.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;So, at the end of the day, I removed a bunch of ugly hacks and ended up with shorter, more-elegant code. So this was a win, right?&lt;/p&gt;

&lt;p&gt;Not clearly. One reason is that PCG is slower than BCPL, and there’s not really a good reason for us to be paying that cost. Again, here’s what BCPL number generation looks like:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;inline u32 Random_Generator::get() {
    // state is 32 bits.
    state = state * 2147001325 + 715136305;
    return 0x31415926 ^ ((state &amp;gt;&amp;gt; 16) + (state &amp;lt;&amp;lt; 16));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;and here’s what PCG looks like:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;inline u32 Random_Generator::get() {
    // state, inc are both 64 bits!

    u64 oldstate = state;
    state = oldstate * 6364136223846793005ULL + (inc|1);

    u32 xorshifted = ((oldstate &amp;gt;&amp;gt; 18u) ^ oldstate) &amp;gt;&amp;gt; 27u;
    u32 rot = oldstate &amp;gt;&amp;gt; 59u;
    return (xorshifted &amp;gt;&amp;gt; rot) | (xorshifted &amp;lt;&amp;lt; ((-rot) &amp;amp; 31));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;PCG is doing substantially more arithmetic, &lt;em&gt;and&lt;/em&gt; it’s doing it on numbers that are twice as wide, &lt;em&gt;and&lt;/em&gt; the arithmetic has some unhappy dependencies (for example, shifting by the variable number of bits ‘rot’, which is pretty bad on some architectures).&lt;/p&gt;

&lt;p&gt;If this were some kind of cryptographic application, paying this cost might be warranted. But we’re just trying to generate some visuals; we don’t need to pass rigorous statistical tests!&lt;/p&gt;

&lt;p&gt;But the real reason this isn’t a win is that I didn’t increase my knowledge in any deep way. I learned some surface stuff about random number generators by skimming the PCG paper, but really so far I have been lazy. I don’t even have the conceptual tools yet to reason about what the best solution for this problem would look like; so long as that is the case, I am doomed to just keep trying random things.&lt;/p&gt;

&lt;p&gt;Fortunately, in the light reading I have done so far, I’ve learned enough to get a little bit of traction, and I see several potential directions in which to go to improve this situation.&lt;/p&gt;

&lt;p&gt;It seems like we ought to be able to go back to BCPL and do something simple to increase the quality of our seeding. At the same time, though, from what I am learning about PCG, LCGs, and other types of random number generators, there are a few possibilities that should at least be discussed. We’ll continue this in part 2, in which I actually start learning real things about random number generators, and stop treating them like magical black boxes.&lt;/p&gt;
</description>
        <pubDate>Thu, 07 Jul 2016 17:30:00 -0700</pubDate>
        <link>https://number-none.com/blow/blog/programming/2016/07/07/braid_particles_1.html</link>
        <guid isPermaLink="true">https://number-none.com/blow/blog/programming/2016/07/07/braid_particles_1.html</guid>
        
        
        <category>programming</category>
        
      </item>
    
      <item>
        <title>John Carmack on Inlined Code</title>
        <description>&lt;p&gt;&lt;em&gt;(Here begins a comment written by John Carmack in 2014, about an email he sent to a programmers’ mailing list in 2007.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In the years since I wrote this, I have gotten much more bullish about pure functional programming, even in C/C++ where reasonable: &lt;a href=&quot;http://gamasutra.com/view/news/169296/Indepth_Functional_programming_in_C.php&quot;&gt;(link)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The real enemy addressed by inlining is unexpected dependency and mutation of state, which functional programming solves more directly and completely. However, if you are going to make a lot of state changes, having them all happen inline does have advantages; you should be made constantly aware of the full horror of what you are doing. When it gets to be too much to take, figure out how to factor blocks out into pure functions (and don.t let them slide back into impurity!).&lt;/p&gt;

&lt;p&gt;As an additional confirmation of the point of the article, a couple years later when I was working on the Doom 3 BFG edition release, the exactly predicted off-by-one-frame-of-latency input sampling happened, and very nearly shipped. That was a cold-sweat moment for me: &lt;em&gt;after all of my harping about latency and responsiveness, I almost shipped a title with a completely unnecessary frame of latency&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;To make things more complicated, the &lt;em&gt;do always, then inhibit or ignore&lt;/em&gt; strategy, while a very good idea for high reliability systems, is less appropriate in power and thermal constrained environments like mobile.&lt;/p&gt;

&lt;p&gt;John Carmack&lt;br /&gt;
September 26, 2014&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;From: John Carmack &lt;a href=&quot;&amp;#109;&amp;#097;&amp;#105;&amp;#108;&amp;#116;&amp;#111;:&amp;#106;&amp;#111;&amp;#104;&amp;#110;&amp;#099;&amp;#064;&amp;#105;&amp;#100;&amp;#115;&amp;#111;&amp;#102;&amp;#116;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#099;&amp;#111;&amp;#109;&quot;&gt;&amp;#106;&amp;#111;&amp;#104;&amp;#110;&amp;#099;&amp;#064;&amp;#105;&amp;#100;&amp;#115;&amp;#111;&amp;#102;&amp;#116;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#099;&amp;#111;&amp;#109;&lt;/a&gt;&lt;br /&gt;
Date: Tue, Mar 13, 2007 at 4:17 PM&lt;br /&gt;
Subject: inlining code&lt;/p&gt;

&lt;p&gt;This is going to be an unusual email – I want to talk about coding style. I’m not going to issue any mandates, but I want everyone to seriously consider some of these issues. I’m not talking about petty things like spaces around operators, bracing styles, or pointers by type or variable (although we probably should settle that one), but about larger organization of code. There aren’t any silver bullets, but months can be shaved off of a development project with a few percent improvement in productivity.&lt;/p&gt;

&lt;p&gt;This email was getting too long, so I am going to follow up with some other thoughts later. I have a lot of general things to discuss, but there is a specific tactical direction that I want to advocate.&lt;/p&gt;

&lt;p&gt;A year ago I was involved in a discussion about writing extremely reliable software for aerospace applications, as I have been several times over the years. Typically I am there to rail against the people that talk about using threads and an RTOS for such things, when a simple polled loop that looks like a primitive video game is much more clear and effective. However, this particular discussion brought up a new wrinkle for me:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Indeed, if memory serves (it’s been a while since I read about this)…&lt;/p&gt;

  &lt;p&gt;The fly-by-wire flight software for the Saab Gripen (a lightweight
fighter) went a step further.  It disallowed both subroutine calls and
backward branches, except for the one at the bottom of the main loop.
Control flow went forward only.  Sometimes one piece of code had to leave
a note for a later piece telling it what to do, but this worked out well
for testing:  all data was allocated statically, and monitoring those
variables gave a clear picture of most everything the software was doing.
The software did only the bare essentials, and of course, they were
serious about thorough ground testing.&lt;/p&gt;

  &lt;p&gt;No bug has ever been found in the “released for flight” versions of that
code.&lt;/p&gt;

  &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;                                                     Henry Spencer
                                                  henry@spsystems.net
&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, a great deal of stuff that goes on in the aerospace industry should not be emulated by anyone, and is often self destructive. Most of you have probably read various popular articles about the development process that produces the space shuttle software, and while some people might think that the world would be better if all software developers were that “careful”, the truth is that we would be decades behind where we are now, with no PC’s and no public internet if everything was developed at that snail’s pace.
This particular anecdote seemed to have some practical value, so I decided to give it a try. The flight control code for the Armadillo rockets is only a few thousand lines of code, so I took the main tic function and started inlining all the subroutines. While I can’t say that I found a hidden bug that could have caused a crash (literally…), I did find several variables that were set multiple times, a couple control flow things that looked a bit dodgy, and the final code got smaller and cleaner.&lt;/p&gt;

&lt;p&gt;After living with the code in that style for quite some time, I haven’t found any drawbacks to it, and I have started applying the general approach to my code at Id. In lots of places there is a choice between organizing code a few ways:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
------- style A:
 
void MinorFunction1( void ) {
}
 
void MinorFunction2( void ) {
}
 
void MinorFunction3( void ) {
}
 
void MajorFunction( void ) {
        MinorFunction1();
        MinorFunction2();
        MinorFunction3();
}
 
--------- style B:
 
void MajorFunction( void ) {
        MinorFunction1();
        MinorFunction2();
        MinorFunction3();
}
 
void MinorFunction1( void ) {
}
 
void MinorFunction2( void ) {
}
 
void MinorFunction3( void ) {
}
 
 
---------- style C:
 
void MajorFunction( void ) {
        // MinorFunction1
 
        // MinorFunction2
 
        // MinorFunction3 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I have historically used “style A” to allow for not prototyping in all cases, although some people prefer “style B”. The difference between the two isn’t of any consequence. Michael Abrash used to write code in “style C”, and I remember actually taking his code and converting it to “style A” in the interest of perceived readability improvements.
At this point, I think there are some definite advantages to “style C”, but they are development process oriented, rather than discrete, quantifiable things, and they run counter to a fair amount of accepted conventional wisdom, so I am going to try and make a clear case for it. There isn’t any dogma here, but considering exactly where it is and isn’t appropriate is worthwhile.&lt;/p&gt;

&lt;p&gt;In no way, shape, or form am I making a case that avoiding function calls alone directly helps performance.&lt;/p&gt;

&lt;p&gt;An exercise that I try to do every once in a while is to “step a frame” in the game, starting at some major point like common-&amp;gt;Frame(), game-&amp;gt;Frame(), or renderer-&amp;gt;EndFrame(), and step into every function to try and walk the complete code coverage. This usually gets rather depressing long before you get to the end of the frame. Awareness of all the code that is actually executing is important, and it is too easy to have very large blocks of code that you just always skip over while debugging, even though they have performance and stability implications.&lt;/p&gt;

&lt;p&gt;C++ is no friend of this goal, with operator overloading, implicit constructors, and so on. A lot of things done in the name of flexibility are somewhat misguided, and at the root of a lot of development problems. Games, with the continuously recurring real time tic structure, also have some goals and constraints that encourage a programming style somewhat different than, say, a content creation application or transaction processor.&lt;/p&gt;

&lt;p&gt;If something is going to be done once per frame, there is some value to having it happen in the outermost part of the frame loop, rather than buried deep inside some chain of functions that may wind up getting skipped for some reason. For example, our usercmd_t generation code is buried off of asyncServer, and it really should be in the main common loop. Related to this is a topic of hardware versus software design – it is often better to go ahead and do an operation, then choose to inhibit or ignore some or all of the results, than try to conditionally perform the operation. The usercmd_t generation relates to this (and other messes related to the interaction with game over bindsets), where the usercmd_t are only generated when they “need to be”.&lt;/p&gt;

&lt;p&gt;The way we have traditionally measured performance and optimized our games encouraged a lot of conditional operations – recognizing that a particular operation doesn’t need to be done in some subset of the operating states, and skipping it. This gives better demo timing numbers, but a huge amount of bugs are generated because skipping the expensive operation also usually skips some other state updating that turns out to be needed elsewhere.&lt;/p&gt;

&lt;p&gt;We definitely still have tasks that are performance intensive enough to need optimization, but the style gets applied as a matter of course in many cases where a performance benefit is negligible, but we still eat the bugs. Now that we are firmly decided on a 60hz game, worst case performance is more important than average case performance, so highly variable performance should be looked down on even more.&lt;/p&gt;

&lt;p&gt;It is very easy for frames of operational latency to creep in when operations are done deeply nested in various subsystems, and things evolve over time. This can lay hidden as a barely perceptible drop in input quality, or it can be blatantly obvious as a model trailing an attachment point during movement. If everything is just run out in a 2000 line function, it is obvious which part happens first, and you can be quite sure that the later section will get executed before the frame is rendered.&lt;/p&gt;

&lt;p&gt;Besides awareness of the actual code being executed, inlining functions also has the benefit of not making it possible to call the function from other places. That sounds ridiculous, but there is a point to it. As a codebase grows over years of use, there will be lots of opportunities to take a shortcut and just call a function that does only the work you think needs to be done. There might be a FullUpdate() function that calls PartialUpdateA(), and PartialUpdateB(), but in some particular case you may realize (or think) that you only need to do PartialUpdateB(), and you are being efficient by avoiding the other work. Lots and lots of bugs stem from this. Most bugs are a result of the execution state not being exactly what you think it is.&lt;/p&gt;

&lt;p&gt;Strictly functional functions that only read their input arguments and just return a value without examining or modifying any permanent state are safe from these types of errors, and the nice ability to formally speak about them makes them a good ivory tower topic, but very little of our real code falls into this category. I don’t think that purely functional programming writ large is a pragmatic development plan, because it makes for very obscure code and spectacular inefficiencies, but if a function only references a piece or two of global state, it is probably wise to consider passing it in as a variable. It would be kind of nice if C had a “functional” keyword to enforce no global references.&lt;/p&gt;

&lt;p&gt;Const parameters and const functions are helpful in avoiding side effect related bugs, but the functions are still susceptible to changes in the global execution environment. Trying to make more parameters and functions const is a good exercise, and often ends in casting it away in frustration at some point. That frustration is usually due to finding all sorts of places that state could be modified that weren’t immediately obvious – places for bugs to breed.&lt;/p&gt;

&lt;p&gt;C++ object methods could be thought of as almost-functional, with an implicit overwriting assignment on return, but with larger objects that contain lots of variables you don’t have much awareness of what is modified by the method, and again, there is no guarantee that the function isn’t running off and doing something horribly global, like parsing a decl.&lt;/p&gt;

&lt;p&gt;The function that is least likely to cause a problem is one that doesn’t exist, which is the benefit of inlining it. If a function is only called in a single place, the decision is fairly simple.&lt;/p&gt;

&lt;p&gt;In almost all cases, code duplication is a greater evil than whatever second order problems arise from functions being called in different circumstances, so I would rarely advocate duplicating code to avoid a function, but in a lot of cases you can still avoid the function by flagging an operation to be performed at the properly controlled time. For instance, having one check in the player think code for health &amp;lt;= 0 &amp;amp;&amp;amp; !killed is almost certain to spawn less bugs than having KillPlayer() called in 20 different places.&lt;/p&gt;

&lt;p&gt;On the subject of code duplication, I tracked all the bugs (problems that surfaced after I thought everything was working correctly) I fixed for a while, and I was quite surprised at how often copy-paste-modify operations resulted in subtle bugs that weren’t immediately obvious. For small vector operations on three or four things, I would often just past and modify a few characters like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;v[0] = HF_MANTISSA(*(halfFloat_t *)((byte *)data + i*bytePitch+j*8+0));
v[1] = HF_MANTISSA(*(halfFloat_t *)((byte *)data + i*bytePitch+j*8+1));
v[2] = HF_MANTISSA(*(halfFloat_t *)((byte *)data + i*bytePitch+j*8+2));
v[3] = HF_MANTISSA(*(halfFloat_t *)((byte *)data + i*bytePitch+j*8+3));
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;I now strongly encourage explicit loops for everything, and hope the compiler unrolls it properly. A significant number of my bugs related to things like this, and I am now rethinking even two dimensional cases where I commonly use discrete _X, _Y or _WIDTH, _HEIGHT variables. I find that much easier to read than a two element array, but it is difficult to argue with my data on how often it made me screw up.
Some practical Matters —&lt;/p&gt;

&lt;p&gt;Using large comment blocks inside the major function to delimit the minor functions is a good idea for quick scanning, and often enclosing it in a bare braced section to scope the local variables and allow editor collapsing of the section is useful. I know there are some rules of thumb about not making functions larger than a page or two, but I specifically disagree with that now – if a lot of operations are supposed to happen in a sequential fashion, their code should follow sequentially.&lt;/p&gt;

&lt;p&gt;Enclosing pages of code inside a conditional or loop statement does have readability and awareness drawbacks, so leaving that code in a separate function may still be justified, but in some cases it is still possible to move the code to another place where its execution wouldn’t be conditional, or just execute it at all times and inhibit the results in some way with a very small conditional block. An execute-and-inhibit style usually takes more absolute time, but it reduces the variability in frame times, and eliminates a class of bugs.&lt;/p&gt;

&lt;p&gt;Inlining code quickly runs into conflict with modularity and OOP protections, and good judgment must be applied. The whole point of modularity is to hide details, while I am advocating increased awareness of details. Practical factors like increased multiple checkouts of source files and including more local data in the master precompiled header forcing more full rebuilds do need to be weighed. Currently I am leaning towards using heavyweight objects as the reasonable break point for combining code, and trying to reduce the use of medium sized helper objects, while making any very lightweight objects as purely functional as possible if they have to exist at all.&lt;/p&gt;

&lt;p&gt;To sum up:&lt;/p&gt;

&lt;p&gt;If a function is only called from a single place, consider inlining it.&lt;/p&gt;

&lt;p&gt;If a function is called from multiple places, see if it is possible to arrange for the work to be done in a single place, perhaps with flags, and inline that.&lt;/p&gt;

&lt;p&gt;If there are multiple versions of a function, consider making a single function with more, possibly defaulted, parameters.&lt;/p&gt;

&lt;p&gt;If the work is close to purely functional, with few references to global state, try to make it completely functional.&lt;/p&gt;

&lt;p&gt;Try to use const on both parameters and functions when the function really must be used in multiple places.&lt;/p&gt;

&lt;p&gt;Minimize control flow complexity and “area under ifs”, favoring consistent execution paths and times over “optimally” avoiding unnecessary work.&lt;/p&gt;

&lt;p&gt;Discussion?&lt;/p&gt;

&lt;p&gt;John Carmack&lt;/p&gt;
</description>
        <pubDate>Fri, 26 Sep 2014 19:43:31 -0700</pubDate>
        <link>https://number-none.com/blow/blog/programming/2014/09/26/carmack-on-inlined-code.html</link>
        <guid isPermaLink="true">https://number-none.com/blow/blog/programming/2014/09/26/carmack-on-inlined-code.html</guid>
        
        
        <category>programming</category>
        
      </item>
    
  </channel>
</rss>
