<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" version="2.0">

<channel>
	<title>Jeff On Games</title>
	
	<link>http://www.jeffongames.com</link>
	<description>This is Jeff.  This is Jeff On Games.</description>
	<lastBuildDate>Thu, 12 Apr 2012 18:14:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/JeffOnGames" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="jeffongames" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Finding D3D9 Leaks</title>
		<link>http://www.jeffongames.com/2012/04/finding-d3d9-leaks/</link>
		<comments>http://www.jeffongames.com/2012/04/finding-d3d9-leaks/#comments</comments>
		<pubDate>Thu, 12 Apr 2012 14:45:58 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
		
		<guid isPermaLink="false">http://www.jeffongames.com/?p=384</guid>
		<description><![CDATA[I ran into this problem working in a DirectX 9 application recently, and found it useful enough that I thought I'd share. We were running into an issue where returning from an alt-tab was not recreating the device properly. This is usually caused by a created D3DPOOL_DEFAULT asset not being released and recreated before attempting <a href="http://www.jeffongames.com/2012/04/finding-d3d9-leaks/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I ran into this problem working in a DirectX 9 application recently, and found it useful enough that I thought I'd share. We were running into an issue where returning from an alt-tab was not recreating the device properly. This is usually caused by a created D3DPOOL_DEFAULT asset not being released and recreated before attempting to recover the lost device. As a result, you get this message:</p>
<blockquote><p><span style="color: #222222;"><span style="font-family: Arial; font-size: 10pt;">Direct3D9: (ERROR) :All user created D3DPOOL_DEFAULT surfaces must be freed before ResetEx can succeed. ResetEx Fails.<br />
Direct3D9: (ERROR) :ResetEx failed and ResetEx/TestCooperativeLevel/Release are the only legal APIs to be called subsequently</span><br />
</span></p></blockquote>
<p>One additional thing that was throwing me was this error message:</p>
<blockquote><p><span style="color: #222222;"><span style="font-family: Arial; font-size: 10pt;">Direct3D9: :Window has been subclassed; cannot restore!</span><br />
</span></p></blockquote>
<p>This can probably safely be ignored, and may be a symptom of the back buffer leaking specifically, but generally this whole error set is a sign of leaking D3D objects.</p>
<p>If this is something innocuous, like a single texture, you can sometimes figure it out by simply enabling the DirectX debug libraries, running and exiting your application, which will give you the AllocId of the leaking asset, which you can then break on. However, a large number of leaks indicate that something lower level may be leaking, and potentially a leaking reference to something, like the back buffer (which was our case). How to find it?</p>
<p>Here's what I ended up having to do.</p>
<p>First we did what we need to do for every bug, reduce it to the fewest steps possible.</p>
<p>Next, run PIX and take a full capture, until you've gotten to the point of the leak, then close. If you have a lot of steps to reproduce, you'll want to make sure you've got a lot of hard drive space, and some time on your hands, because it can take a while.</p>
<p>Once you have your full PIX run you can look at this column:</p>
<p><img src="http://www.jeffongames.com/wp-content/uploads/2012/04/041212_1445_FindingD3D91.png" alt="" /></p>
<p>And set it to Never. This will show you every D3D object that's leaking, regardless of how many AllocIds it has (interesting tidbit, a single D3D object can allocate multiple AllocIds). If you move to the last frame (and wait for PIX to catch up, which, again, can take a while) you can even see how many references exist during shutdown. You could even walk each frame and see when the reference counts of your leaking assets go up.</p>
<p>In our case, like I said, we were leaking a reference to the back buffer. Most obvious was to look for calls to IDirect3DDevice9::GetBackBuffer, but none of those were leaking. Less obvious was to look for cases of IDirect3DDevice9::GetDepthStencilSurface and IDirect3DDevice9::GetRenterTarget(0). In our case, a call to GetRenderTarget was leaking as a result of a short circuit in a logic check, resulting in the back buffer reference to dangle in a very specific logic case.</p>
<p>Granted, this leaking does not pose a lost device recovery problem with DirectX 10 or DirectX 11, but since many engines are still DX9 based, I thought I would share.</p>
<img src="http://feeds.feedburner.com/~r/JeffOnGames/~4/C_qETMZ-Omo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.jeffongames.com/2012/04/finding-d3d9-leaks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Debugging Embedded Mono</title>
		<link>http://www.jeffongames.com/2012/03/debugging-embedded-mono/</link>
		<comments>http://www.jeffongames.com/2012/03/debugging-embedded-mono/#comments</comments>
		<pubDate>Fri, 30 Mar 2012 15:16:30 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
		
		<guid isPermaLink="false">http://www.jeffongames.com/?p=372</guid>
		<description><![CDATA[It's been announced that Go Home Dinosaurs will be released using Google's Native Client technology later this year, but what isn't known (as much) is we're using Mono / C# as our "higher level" logic and scripting system. Generally, I'm a huge fan of C# as a language, and the performance benefits just seal the <a href="http://www.jeffongames.com/2012/03/debugging-embedded-mono/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>It's been announced that Go Home Dinosaurs will be released using <a href="https://developers.google.com/native-client/">Google's Native Client</a> technology later this year, but what isn't known (as much) is we're using <a href="http://www.mono-project.com/Main_Page">Mono</a> / C# as our "higher level" logic and scripting system. Generally, I'm a huge fan of C# as a language, and the performance benefits just seal the deal for me. The one issue we have right now, though, is debugging embedded Mono, especially in conjunction with the game running in Visual Studio. There aren't very many instructions on how to do this online, so I thought I'd share our experience.</p>
<p>There are two very weird issues when debugging embedded Mono. First, it currently works exactly opposite of how most debuggers work. In most soft debuggers, the application starts the server and the debugger connects to it. In Mono soft debugging, the debugger creates the server and the client connects to it. Second, the Mono soft debugger uses signals / exceptions to work halt threads. This means that you can't debug both with Visual Studio and Mono Develop, because Visual Studio will pull the signals before they get to the application. This also prevents</p>
<p>However, there are <a href="https://github.com/mono/mono/commit/285f564f14df834fe51ee54af6a602aec4c400d0">changes in the works</a> from the Unity team which fix both of these issues. However, they are not currently part of a stable mono release (or in the Elijah's version for Native Client). Once they are, I may revisit this whole article, but that's where we are right now.</p>
<p>So, with all of that in mind, how do you get this working right now?</p>
<h2>Set Up MonoDevelop</h2>
<p>First up, grab <a href="http://monodevelop.com/">MonoDevelop</a>.</p>
<p>Second up, you will want to add an environment variable to your system called <em>MONODEVELOP_SDB_TEST</em> and set it to 1. This gives you access to the following menu item when you have a solution loaded:</p>
<p><img src="http://www.jeffongames.com/wp-content/uploads/2012/03/033012_1516_DebuggingEm1.png" alt="" /></p>
<p>Which brings up this dialog:</p>
<p><img src="http://www.jeffongames.com/wp-content/uploads/2012/03/033012_1516_DebuggingEm2.png" alt="" /></p>
<p>Now, for some reason, I've never been able to get MonoDevelop to launch the application directly. It always fails attempting to redirect standard out, and then immediately crashes (I could look at the code to figure out why this is, but I haven't had a chance to). We'll come back to this dialog in a minute.</p>
<h2>Prepare Your Code</h2>
<p>There are a few things you need to add to your code to get debugging to work. The first few lines can occur at initialization, regardless of whether you're debugging or not:</p>
<pre class="brush: cpp; title: ; notranslate">
mono_debug_init(MONO_DEBUG_FORMAT_MONO);
mono_debug_domain_create(mMonoDomain);
</pre>
<p>These should be done <strong>before</strong> you load any assemblies.</p>
<p>In addition, if you're running Mono from a background thread (like we are), and <strong>not</strong> running it on your foreground thread, after initialization you need to <strong>detach the foreground thread</strong>. This is because when Mono attempts to halt all threads when it hits a breakpoint, it can only do so when you're executing Mono code. If your main thread never executes any Mono code, it never halts, which means debugging doesn't work. This is good practice regardless, because if the GC needs to halt all of your threads, it will also fail if a non-Mono executing thread is still attached.</p>
<p>Last thing you'll need to do in code is set up the debugger. Here's the code:</p>
<pre class="brush: cpp; title: ; notranslate">
     bool isDebugging = AresApplication::Instance()-&amp;gt;IsDebuggingMono();
     const char* options[] = {
          &quot;--debugger-agent=transport=dt_socket,address=127.0.0.1:10000&quot;
     };
     mono_jit_parse_options(1, (char**)options);
</pre>
<p>This needs to be combined with any other options you may have (I only have one other, which is –soft-breakpoints), and should only be done if you want to start debugging. If the Mono client can't connect to the debugging server when it starts up, it will call exit, which is no good.</p>
<p>Lastly, if you're using the Microsoft C# compiler, instead of the Mono one, you'll need to generate mdbs from all of your pdbs. There's thankfully a utility for this. We actually now perform this step as a post build event, which keeps the mdbs up to date with latest code.</p>
<h2>Put it all together</h2>
<p>Alright, so let's get this party started!</p>
<p>Open MonoDevelop. Set some breakpoints, then open this dialog again.</p>
<p><img src="http://www.jeffongames.com/wp-content/uploads/2012/03/033012_1516_DebuggingEm3.png" alt="" /></p>
<p>Don't change anything, and click "Listen".</p>
<p>Now start your application <strong>outside of Visual Studio</strong> with whatever command line arguments you chose to signal to your app you want to debug in Mono.</p>
<p>Everything should now connect and you should be debugging Mono in your app!</p>
<p>Let me know if you have any issues!</p>
<img src="http://feeds.feedburner.com/~r/JeffOnGames/~4/8jFVcbQXRL8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.jeffongames.com/2012/03/debugging-embedded-mono/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Post GDC 2012 Post</title>
		<link>http://www.jeffongames.com/2012/03/post-gdc-2012-post/</link>
		<comments>http://www.jeffongames.com/2012/03/post-gdc-2012-post/#comments</comments>
		<pubDate>Thu, 15 Mar 2012 19:34:12 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
		
		<guid isPermaLink="false">http://www.jeffongames.com/?p=363</guid>
		<description><![CDATA[I'm back from GDC 2012, which is my 11th GDC straight, and I'm almost fully recovered. This year was certainly better than the last two for sure, but it doesn't take much to top getting minor food poisoning and getting (almost) deathly ill (I still can't top Darius who, three years ago, entirely lost his <a href="http://www.jeffongames.com/2012/03/post-gdc-2012-post/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p><img class="alignright" src="http://www.jeffongames.com/wp-content/uploads/2012/03/031512_1933_PostGDC20121.jpg" alt="" width="359" height="270" align="left" /></p>
<p>I'm back from<a href="http://www.gdconf.com/"> GDC 2012</a>, which is my 11<sup>th</sup> GDC straight, and I'm almost fully recovered. This year was certainly better than the last two for sure, but it doesn't take much to top getting minor food poisoning and getting (almost) deathly ill (I still can't top Darius who, three years ago, entirely lost his voice). I still have yet to find that balance of parties and not-parties, and when to just go hang out at the various hotel bars. I think I did better this year, but I still don't have it quite down.</p>
<p>This year, the high points were definitely the two events I ran. The first was the awesome Pre-GDC board game bash, which hosted probably about 130 people this year. This is always a lot of fun, and way more low-key than most other GDC parties which is why I like it. We're growing again next year, probably to about 150+ people, but I'm also looking for a bigger room with more tables (table space was certainly a problem this year).</p>
<p>In addition to that awesome event, this year I organized a private scotch tasting. This was really really awesome. So awesome, I don't have pictures of it. It was another great, low key, and educational event. Everyone there was really awesome, and I hope everyone had a great time. We'll see if that will happen next year, and if it will grow or not.</p>
<p>So what's up for next year? First, the board game night will certainly be running again. I've already started putting out requests for space the Sunday before GDC (and already been turned down once o_O!). Other events? Maybe the scotch tasting, and potentially a Black Tie Only reception. These last two require a good amount of planning and funding, so they'll probably be maybes until closer to GDC.</p>
<p>What else? I'll be posting more! <a href="http://www.firehosegames.com/">Fire Hose </a>announced that its next game (and the game I'm working on) Go Home Dinosaurs, will be shipping on Chrome Web Store using <a href="https://developers.google.com/native-client/">Native Client</a>. I haven't been able to talk about this too much until now, but now that I can I'll be posting a little bit more on my experiences with Native Client and with <a href="http://www.mono-project.com/Main_Page">Mono</a> (which is what we're using for scripting). So keep an eye out for that!</p>
<img src="http://feeds.feedburner.com/~r/JeffOnGames/~4/V1b-HyTgbV4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.jeffongames.com/2012/03/post-gdc-2012-post/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GGJ 2012: Eat Sheep (and Die)</title>
		<link>http://www.jeffongames.com/2012/01/ggj-2012-eat-sheep-and-die/</link>
		<comments>http://www.jeffongames.com/2012/01/ggj-2012-eat-sheep-and-die/#comments</comments>
		<pubDate>Mon, 30 Jan 2012 17:41:46 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
		
		<guid isPermaLink="false">http://www.jeffongames.com/?p=324</guid>
		<description><![CDATA[This weekend I participated in Global Game Jam for the third time (after taking a hiatus in 2011 to go speak at conference overseas). This year, I was at the UVA site and took part in a 3 person team with my brother in law and an awesome UVA student. The result was an interesting <a href="http://www.jeffongames.com/2012/01/ggj-2012-eat-sheep-and-die/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This weekend I participated in <a href="http://globalgamejam.org/">Global Game Jam</a> for the third time (after taking a hiatus in 2011 to go speak at conference overseas). This year, I was at the UVA site and took part in a 3 person team with my <a href="http://aimiller.blogspot.com/">brother in law</a> and an awesome UVA student. The result was an interesting two player competitive game called <a href="http://globalgamejam.org/2012/eat-sheep-and-die">Eat Sheep (and Die)</a>.</p>
<p>This jam was way less stressful than any other jam I've participated in. We essentially had something fun to play by middle of day 2, and just polished things throughout the end of day 2 and day 3. As a result, this is probably the most complete jam game I've ever worked on. Very little went wrong. It was great.</p>
<p>So what when right?</p>
<ol>
<li><strong>AngelXNA</strong> – Power of Angel combined with the power of XNA! This was the third time I've used Angel in a jam and every time it's improved. We were able to get levels in games quickly, spawn actors, and do all sorts of things quickly and easily. It actually worked really well. Again.</li>
<li><strong>Abandoning Design</strong> – The original point of the game was to have a cyclic back and forth of helping and hurting the other player. On your turn, you would have your goal, and a directive to help or hurt your opponent. On the next turn, you would be given a bonus based on how well or poorly your opponent did. At some point, we realized there was never any reason to help your opponent. It just wasn't worth it. So we abandoned the helping, turn based component, and went with real time versus. This makes it questionable whether we obeyed the theme, but whatever. The game was much better as a result.</li>
</ol>
<p>What went wrong?</p>
<ol>
<li><strong>AngelXNA? –</strong> So, the one thing I don't like about Angel and XNA is that it does have a huge barrier to entry for people playing the game after the Jam. I know I don't bother playing a GGJ game that requires a download unless it comes VERY highly recommended. I will, however, look at pretty much every HTML5 or Flash game. That said, Angel is awesome, so maybe I have to figure out a way to fix this. Native Client maybe?</li>
</ol>
<p>That's it. Not too many lessons this time out because everything went so well. It's a weird feeling. Really looking forward to next year!</p>
<img src="http://feeds.feedburner.com/~r/JeffOnGames/~4/tCR4U3b_n_4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.jeffongames.com/2012/01/ggj-2012-eat-sheep-and-die/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Updates to AngelXNA</title>
		<link>http://www.jeffongames.com/2012/01/updates-to-angelxna/</link>
		<comments>http://www.jeffongames.com/2012/01/updates-to-angelxna/#comments</comments>
		<pubDate>Mon, 23 Jan 2012 03:57:22 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
		
		<guid isPermaLink="false">http://www.jeffongames.com/?p=313</guid>
		<description><![CDATA[One of the tips I gave in my recent talk is to have a tool for GGJ. My tool of choice is AngelXNA, because it combines the power of XNA with the power of Angel. When I was demoing it to the other attendees, I realized I hadn't added a few demo screens that are <a href="http://www.jeffongames.com/2012/01/updates-to-angelxna/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>One of the tips I gave in my recent talk is to have a tool for GGJ. My tool of choice is AngelXNA, because it combines the power of XNA with the power of Angel. When I was demoing it to the other attendees, I realized I hadn't added a few demo screens that are really necessary.</p>
<p>To that end, I've added two demo screens showcasing two features that are in AngelXNA that aren't in Angel. The first is the Editor. While I had a problem with the Editor in the last GGJ, Fire Hose used it a lot for prototyping and I think we've worked out most of the kinks. It's not perfect, but it does make creating levels in Angel super easy. There are shortcuts for cloning, scaling, and rotating actors, which makes the level editing process super quick.</p>
<p>The second feature has several aspects, but comes down to the ability to use sprite sheets and the ability to create named, data driven animations. There are two parts to this. The first part is the Tiling system. By adding a .tileinfo file parallel to any given image file, it will automatically start rendering Actors that use that image as tiled. Here's an example .tileinfo:</p>
<pre class="brush: plain; title: ; notranslate">
IsAnim = true
FrameSize = Vector2(160, 200)
AnimDirection = TiledAnimDirection.Horizontal
StartFrame = Vector2(0, 0)
EndFrame = Vector2(0, 2)
</pre>
<p>It specifies that this file contains an animation, that each frame is 160x200, that the animation frames run left to right, starts at 0,0, and ends at 0,2. You can also use a non-anim and specify a specific tile to render.</p>
<p>Once you have these .tileinfos specified, you can specify animation files. Here's the example anim file:</p>
<pre class="brush: plain; title: ; notranslate">
BeginAnimation(&quot;Idle&quot;, TiledAnimRenderPath.Create())
    AnimDelay = 0.03
    File = &quot;images/devo/devo_idle_strip&quot;
    AnimType = AnimationType.Loop
EndAnimation()

BeginAnimation(&quot;Run&quot;, TiledAnimRenderPath.Create())
    AnimDelay = 0.03
    File = &quot;images/devo/devo_run_strip&quot;
    AnimType = AnimationType.Loop
EndAnimation()

BeginAnimation(&quot;Fall&quot;, TiledAnimRenderPath.Create())
    AnimDelay = 0.03
    File = &quot;images/devo/devo_fall_strip&quot;
    AnimType = AnimationType.OneShot
EndAnimation()
</pre>
<p>This allows you to call just Actor.PlayAnimation("Idle") or Actor.PlayAnimation("Run").</p>
<p>This is still a bit more complicated than I'd like, but does work really well. The only thing I'd like to improve is the specification of the render path. AngelXNA actually generally selects the correct render path automatically, but the data driving system, specifically the animation system, isn't detecting its render path. I can probably fix this, which I'll hopefully do after GGJ.</p>
<img src="http://feeds.feedburner.com/~r/JeffOnGames/~4/IjAf_-V39Ls" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.jeffongames.com/2012/01/updates-to-angelxna/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Up and Coming</title>
		<link>http://www.jeffongames.com/2012/01/the-up-and-coming/</link>
		<comments>http://www.jeffongames.com/2012/01/the-up-and-coming/#comments</comments>
		<pubDate>Tue, 10 Jan 2012 16:20:40 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
		
		<guid isPermaLink="false">http://www.jeffongames.com/?p=307</guid>
		<description><![CDATA[Update: Better late than never, my talk is now on my site. Happy New Year! For those that don't know, in May (or so) I moved from Boston to Charlottesville, VA. Thankfully, the awesome people at Fire Hose have allowed me to stay with them and work remotely, so I haven't moved companies. I have, <a href="http://www.jeffongames.com/2012/01/the-up-and-coming/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p><em>Update: Better late than never, my talk is now <a href="http://www.fuzzybinary.com/talks/GameJamTips.pptz">on my site</a>.</em></p>
<p>Happy New Year!</p>
<p>For those that don't know, in May (or so) I moved from Boston to Charlottesville, VA. Thankfully, the awesome people at <a href="http://www.firehosegames.com/">Fire Hose</a> have allowed me to stay with them and work remotely, so I haven't moved companies. I have, however, moved communities.</p>
<p>Charlottesville isn't a huge center for game development, but I think if could be a great place for game companies in the future. There's a lot of talent to be had from the neighboring universities (UVA, JMU, GMU, Virginia Tech, and William and Mary are all fairly close) and it's just a great place to live. It's not a big city, but that's actually what I like about it.</p>
<p>To try to help this along, I've created the <a href="http://www.meetup.com/Charlottesville-Game-Developers/">Charlottesville Game Developers meet-up group</a>. We've had a few small meetings so far, with mostly me talking, but coming up over the next few months, we're going to have some great talks about starting companies, working with the city of Charlottesville, and maybe more! (By the way, if you'd like to come visit Charlottesville and give a talk, let me know and we'll work something out).</p>
<p>Tonight, I'm giving a talk on tips for game jams. Since UVA has been nice enough (at my urging) to host a <a href="http://globalgamejam.org/">Global Game Jam</a> site this year, I'm making sure everyone comes in prepared. Most of the tips come from my <a href="http://www.jeffongames.com/2009/02/jamming-postmortem/">previous</a> <a href="http://www.jeffongames.com/2010/02/jamming-post-mortem-2010-edition/">post</a> <a href="http://www.jeffongames.com/2010/08/immigration-jam-post-mortem/">mortems</a> of game jams, but there will be some new stuff in there. I'll try to be sure to post the slides tomorrow as well, so everyone can get the benefit.</p>
<p>Anyway, if you're in the Charlottesville area, come out to our meetings! I'm really looking forward to seeing what the Charlottesville community can produce over the next year.</p>
<img src="http://feeds.feedburner.com/~r/JeffOnGames/~4/pEOCnxrzo4Q" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.jeffongames.com/2012/01/the-up-and-coming/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>On Singletons</title>
		<link>http://www.jeffongames.com/2011/09/on-singletons/</link>
		<comments>http://www.jeffongames.com/2011/09/on-singletons/#comments</comments>
		<pubDate>Wed, 14 Sep 2011 15:07:57 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
		
		<guid isPermaLink="false">http://www.jeffongames.com/?p=300</guid>
		<description><![CDATA[Inspired by a Twitter discussion with Liam Devine about my previous blog post, I've decided to take a bit of time to talk about my opinion on Singletons. In my previous post, I used a lot of them, though generally, I'm not a huge fan. In fact, I've been known to dedicate non-trivial amounts of <a href="http://www.jeffongames.com/2011/09/on-singletons/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Inspired by a Twitter discussion with <a href="https://twitter.com/">Liam Devine</a> about my <a href="http://www.jeffongames.com/2011/08/getting-around-indeterminate-initialization/">previous blog post</a>, I've decided to take a bit of time to talk about my opinion on Singletons.  In my previous post, I used a lot of them, though generally, I'm not a huge fan.  In fact, I've been known to dedicate non-trivial amounts of time <a href="http://www.fuzzybinary.com/talks/IntroToArchitecture.ppt">in talks</a> to the subject of why singletons suck. Singletons are just globals under another name, and they have almost all of the same drawbacks as globals, and don't provide too many benefits.  Each singleton is a potential bottleneck, a potential threading nightmare, and almost always creates giant side effects throughout the code base every time they're used.  In addition, if you're doing unit testing, use of singletons / globals requires significant set-up overhead, which can make tests more complicated.</p>
<p>So what gives? Why am I using them here?</p>
<p>Generally, there's nothing intrinsically wrong with a Singletons or globals.  It's their overuse that becomes a problem.  As mentioned above, each singleton needs to be managed carefully because it can become a potential bottleneck across your entire code.  However, when you're working with something that does need to be global, a Singleton is sometimes a better option, since you can insist certain conditions be met before an instance can be returned.</p>
<p>A good example is a Fixed String Table.  If you're unfamiliar with this, here's the idea: every string in your code is translated to a hashed number.  In some cases, this translation is done manually, but for the sake of code readability and simplicity, I do the translation in code any time a FixedString object is created.  In order to make sure that same string always returns the same hash, and to make sure we can translate the hash to a string, we put the string into a table.  This table could be a static member of FixedString, but if you want to, say, tell the table where to allocate its memory from, or how much memory it's allowed to use, you need to initialize said table.  Again, you could use a static method for this, but this is hiding what's actually happening.  Furthermore, if your table class is any amount of complex, or has functions for accessing usage data, you're essentially going to be pushing that all into static methods of FixedString.  It's a pain, when you are, in essence, creating a global interface anyway, since FixedString itself will probably be in global scope.  At least by moving things into a singleton you potentially have the option of creating multiple tables in the future, should you so choose.</p>
<p>But what about all those Factory singletons from my initial post?</p>
<p>First, a point of clarification: in the previous post, I made it look like every factory was a singleton.  I did this for simplicity, and I apologize. It actually isn't true.  My factories aren't singletons.  In reality, the code reads like this:</p>
<pre class="brush: cpp; title: ; notranslate">
Application::Instance()-&gt;GetFactory()-&gt;RegisterComponent(…);
</pre>
<p>Application is one of the other few singletons I have in my engine.  Now, I'll admit that this isn't much better than having the factories themselves be singletons, since they're retrievable from a singleton anyway.  If you look at the code, it looks like my component code is now coupled to both the factory AND the application.</p>
<p>But in reality that's not true.  My factories aren't coded or tested as singletons.  If I wanted to create another factory I could, and all my unit tests will still work.  And the components themselves aren't coupled to the factories or the application at all.  The only thing that couples factories, the components, and the application is the auto-registration system, which serves as a bridge between all three systems.  Each system is still usable stand alone.</p>
<p>This just leaves whether or not the Application as a singleton / manager is a good idea.  The answer is, no.  No it isn't. But since it is one of few, it sticks out like a sore thumb when you type it, and in code review.  Every time you see or type Application::Instance() should be like warning lights going off in your brain that you're potentially doing something dangerous.  BUT, since I'm mostly doing this during initialization, and at no other point, I'm okay with it.</p>
<img src="http://feeds.feedburner.com/~r/JeffOnGames/~4/bEiP1iVVAIU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.jeffongames.com/2011/09/on-singletons/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting Around Indeterminate Initialization</title>
		<link>http://www.jeffongames.com/2011/08/getting-around-indeterminate-initialization/</link>
		<comments>http://www.jeffongames.com/2011/08/getting-around-indeterminate-initialization/#comments</comments>
		<pubDate>Wed, 24 Aug 2011 14:38:32 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
		
		<guid isPermaLink="false">http://www.jeffongames.com/?p=293</guid>
		<description><![CDATA[So, as I'm sure many seasoned veterans of know, the initialization order of static variables is undefined by the C++ standard. While this generally isn't a problem, it can quickly become a problem if you're doing something like overriding the memory manager, as is the case in most games. Any structure that wants to call <a href="http://www.jeffongames.com/2011/08/getting-around-indeterminate-initialization/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>So, as I'm sure many seasoned veterans of know, the initialization order of static variables is undefined by the C++ standard.  While this generally isn't a problem, it can quickly become a problem if you're doing something like overriding the memory manager, as is the case in most games.  Any structure that wants to call out to a custom allocator, must wait for the allocator to be initialized.  One way around this is to have the allocator as a self-instantiating singleton, but what if you're doing something more complicated?</p>
<p>An example is a self-registration system.  This is a fairly common occurrence: you have a factory class that takes care of instantiating other classes based on something data-driven.  In my scenario, this is a component system, but it really could be anything.  Each component needs to register itself with the factory class so the factory can proceed to instantiate them.  You have two options here: one is to have a giant init method that looks something like this:</p>
<pre class="brush: cpp; title: ; notranslate">
void InitFactory()
{
     Factory.RegisterComponent(ComponentA);
     Factory.RegisterComponent(ComponentB);
     Factory.RegisterComponent(ComponentC);
     Factory.RegisterComponent(ComponentD);
     Factory.RegisterComponent(ComponentE);
     // and so on...
}
</pre>
<p>The problem with this is that it requires you #include every component header, and remember to register every component manually.  Not my idea of fun.</p>
<p>The second is to use an auto registration system.  Basically, you create an auto-registration template class:</p>
<pre class="brush: cpp; title: ; notranslate">
template &lt;class Component&gt;
class ComponentAutoRegister
{
public:
	ComponentAutoRegister();
};

template &lt;class Component&gt;
ComponentAutoRegister&lt;Component&gt;::ComponentAutoRegister()
{
     Factory::Instance()-&gt;RegisterComponent(...);
}
</pre>
<p>And then add that to any component class:</p>
<pre class="brush: cpp; title: ; notranslate">
class MyComponent
{
    static ComponentAutoRegister&lt;MyComponent&gt; __AutoRegistration;
};
</pre>
<p>When the static auto-registration template class is constructed, it will automatically register your class with the factory.</p>
<p>The problem is this: If your factory class has any other dependencies, it will need to initialize those first.  If this usually happens post-main, or as part of any other variable being statically initialized, you can't use this auto-registration system. Damn.</p>
<p>Here's my scenario: I have a table of fixed strings that needs to be initialized with a table page size and an allocator before it can be used.  My component factory uses fixed strings as keys for each component.  Instead of attempting to make a long chain of singletons which would only end up coupling all the systems together (something I wanted to avoid) I slightly edited my auto-registration system to auto-register a callback instead, which is then called post initialization:</p>
<pre class="brush: cpp; title: ; notranslate">
template &lt;class Component&gt;
class ComponentAutoRegister
{
public:
	ComponentAutoRegister();

	static void PerformAutoRegister();
};

template &lt;class Component&gt;
void ComponentAutoRegister&lt;Component&gt;::PerformAutoRegister()
{
	Factory::Instance()-&gt;RegisterComponent(...);
}

template &lt;class Component&gt;
ComponentAutoRegister&lt;Component&gt;::ComponentAutoRegister()
{
	Application::AddPostInitHook(&amp;PerformAutoRegister);
}
</pre>
<p>The callbacks are held in an opaque linked list, managed by a zero-overhead pool pulled out of system memory.  It could actually be held in an array as well, but being able to free the memory once post-initialization is complete makes me happy.</p>
<p>And this could easily be extended to support multiple layers of auto-registered post-initialization, so long as the layers are kept free of dependencies.  For now, I only need the one layer, so I'll keep it simple.</p>
<p>This may seem hacky, but it does work pretty well. What are your thoughts?</p>
<img src="http://feeds.feedburner.com/~r/JeffOnGames/~4/M1w2BIW0heI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.jeffongames.com/2011/08/getting-around-indeterminate-initialization/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Thoughts on Crunch</title>
		<link>http://www.jeffongames.com/2011/07/thoughts-on-crunch/</link>
		<comments>http://www.jeffongames.com/2011/07/thoughts-on-crunch/#comments</comments>
		<pubDate>Wed, 27 Jul 2011 18:45:44 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
		
		<guid isPermaLink="false">http://www.jeffongames.com/?p=291</guid>
		<description><![CDATA[Crunch has been coming up in the news again, mostly because of the Team Bondai issues, and generally, I like to avoid talking about issues like this on my blog, but I figured I'd share some of my thoughts and see what people think. As a disclaimer, I have never gone through what anyone would <a href="http://www.jeffongames.com/2011/07/thoughts-on-crunch/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Crunch has been coming up in the news again, mostly because of the <a href="http://www.joystiq.com/2011/07/15/l-a-noire-lead-programmer-defends-team-bondi-admits-developmen/">Team Bondai</a> issues, and generally, I like to avoid talking about issues like this on my blog, but I figured I'd share some of my thoughts and see what people think.  As a disclaimer, I have never gone through what anyone would call a "death march," which is what Team Bondai had to deal with.  I've had to do crunch, but never on a huge magnitude, which I'll get to.  I'm also going to take what some would say is a "controversial" stance on crunch. Here's the not controversial part: crunch is always bad, never required, and always avoidable, and a team should do everything it can to avoid it.  But it's not always that simple.</p>
<h2>Types of Crunch</h2>
<p>The thing is, there are lots of types of crunch.  And they're all different, and affect the team in different ways, and on different levels.  In my mind, there are three major types:</p>
<ol>
<li><strong>Self-imposed crunch</strong>:  This is the crunch that some people in the game industry do on their own accord.  They stay late every night because they want to.  They want to get that one last thing in, they want to polish the hell out of whatever, or get that one last boss battle in.  This is a personal choice, and there's really not much you can do about it.  However, it should be clear to other team members that <strong>this type of behavior is not condoned or required.</strong> Don't reward them for this behavior.  Otherwise you get into the second type of crunch.</li>
<li><strong>Team de-facto crunch</strong>: This is where the team "decides on its own" that it's going to crunch, when the culture necessitates it, or when management does nothing to stop it.  When too many people start self-imposing crunch, other people at the team will start to look down on those that "aren't working as hard," and peer pressure will cause them to stay later, or work longer.  This is particularly true in companies with lots of younger workers who are not only particularly vulnerable to this type or peer pressure (they really want to impress their superiors) and also believe that this is just the way the game industry is.  If this bubbles up to management, there becomes this situation where long hours are expected, and people that don't do them are considered less valuable employees.  <strong>Don't let this happen</strong>. As a manager, it is your job to make sure self-imposed crunch is seen as an anomaly, and to do your best to keep people from doing it.</li>
<li><strong>Mandatory Crunch</strong>: Just what it sounds like.  Management, for some reason, requires longer hours.  This is the most common form of crunch we hear about, and the worst.  To producers / managers out there, just because you do the same hours does not make mandatory crunch okay.  Actually, nothing really makes mandatory crunch okay.  There are no excuses here.  Mandatory crunch is always a failure somewhere down the pipe.</li>
</ol>
<p>The first two types of crunch are cultural and occur at all studios, but can be mitigated once you recognize the warning signs.</p>
<p>In addition there are three levels of crunch:</p>
<ol>
<li><strong>Mitigated crunch</strong>: The increase in hours is not huge, maybe 10 extra hours of work during the week, the length is known and can be planned for.</li>
<li><strong>Long crunch</strong>: The increase in hours is high.  Working 60 to 80 hours during a week with no break.  The length can still be known, but may be a long way off.<strong><br />
</strong></li>
<li><strong>Death march</strong>: The increase in hours is high, and there is no end in sight, or the end is repeatedly pushed back.<strong><br />
</strong></li>
</ol>
<p>A Mandatory Death March is the worst type of crunch, and when we talk about "crunch" we're usually talking about mandatory long crunch or mandatory death march.  There are no excuses for them, but we should take a look at the causes to figure out if they're avoidable.</p>
<h2>Causes of Mandatory Crunch</h2>
<p>Everyone looks at crunch as a failure of management.  I agree, but there are a lot more factors to it than that.  Here, in my mind are the general causes of crunch.</p>
<ol>
<li><strong>Company Policy</strong>: The Epic model.  There are no important deadlines coming up, there's nothing that's actually requiring crunch, but the company has decided to require everyone always work 60 to 80 hour weeks.  Not okay. There is no excuse for this other than management being completely inept.  It affects work quality and general quality of life.  Don't do it.<strong><br />
</strong></li>
<li><strong>Bad Information:</strong> This is what happened to Team Bondai.  They were constantly told (and believed) that the game was almost finished.  In such cases, many team members, believing the end is in sight, will do self-imposed crunch, which eventually will lead to de-facto crunch.  In addition, this is where a death march starts, and tends to never end.<strong><br />
</strong></li>
<li>
<div><strong>Bad Planning:</strong> This is the most common cause of crunch, and management gets rightly blamed for it all the time. But there are two types of bad planning:<strong><br />
</strong></div>
<ol>
<li><strong>Bad Low Level Planning</strong>: Even the best management team can make a mistake, because they can only make decisions based on what they're told by the people below them.  If what they're told is wrong, their planning will be wrong.  So, if you're at the low level, don't fudge your numbers.  Tell management the truth so they can make the right decisions.<strong><br />
</strong></li>
<li><strong>Bad High Level Planning</strong>: Even with all the right information, managers, especially bad managers, will plan incorrectly.<strong><br />
</strong></li>
</ol>
</li>
<li><strong>Shifting Requirements</strong>: Even with good planning and good information, games are a highly creative and highly iterative product, and when something's not working or isn't fun, it has to be changed.  Unlike other industries where you can work "to spec", the "spec" of a game is frequently fluid, which makes planning for the long term almost impossible.  This, unlike the other causes, isn't anyone's fault, per-se, since a team can come to the mutual decision that something needs to be reworked, but it's something that frequently gets ignored while doing planning<strong><br />
</strong></li>
<li><strong>Deadline: </strong>When all is said and done, this is the real cause of crunch.  When a deadline is involved any amount of error in planning or requirements hits a head when the deadline looms.  Some studios are in a position where the deadline can be pushed, but not all, especially when dealing with a multi-game publisher that has to allocate resources at various times (QA, marketing, operations, etc) to make sure the game launches without a hitch, so they can move on to the next one.  In these situations, moving the deadline is impossible.  <strong><br />
</strong></li>
</ol>
<h2>The Myths: Crunch is a Given and Crunch is Always Avoidable</h2>
<p>Both of the above statements are wrong.  If the causes of crunch are listed above, avoiding crunch is as simple as avoiding those mistakes.  Don't make crunch company policy, always give your employees all the information, plan well at all levels, have a solid design document, and don't have a hard deadline.  Simple.  But, if any of those slip, you have to make a hard decision: cut features, cut polish, or crunch.</p>
<p>If your company has a lot of experience or a lot of leeway, you can always avoid crunch.  However, if you're a start-up working for a publisher, on a hard launch deadline, under contract, and you want to make the best game possible, chances are someone, and it's not necessarily management, is going to make a mistake, and that mistake is going to cause some amount of crunch.</p>
<p>Was it avoidable?  Yes, probably at some point it was, and yes someone made a mistake somewhere.  Crunch is always a failure somewhere down the line.  But at some point in the project, it will become obvious that some amount of crunch will be needed.  The next step is to mitigate it.</p>
<h2>Mitigating Crunch</h2>
<p>Crunch does not always mean Quality of Life or Quality of Work has to suffer, it's just that in most circumstances it does, because of the way it's implemented.  I have gone through two sets of crunch, both mandatory, one long, one mitigated, and both sucked.  But there are a few things that I found helped me, and I think would help others, get through any period of crunch</p>
<ol>
<li><strong>Provide All the Information:</strong> Inform everyone how much more you expect them to work, what needs to be done, and where the deadline is.  If ANY of this information changes, make sure the team knows.  I have been in and heard about crunch situations where information about deadlines or cut features was withheld, and this only makes people angry</li>
<li><strong>Allow people to choose their extra hours:</strong> People are different and have different home lives.  Some people work better in the morning, others at night, others over the weekend.  Do not blanket ask everyone to stay late.  Instead, let them choose when to work and they will choose times that will not only make them most productive, but will interfere with their lives the least.</li>
<li><strong>Allow people to work from home:</strong> Set up your infrastructure to let people work from home.  Some people can be just as productive at home as they can be in the office, and this removes the stress of a long commute and improves QoL since they can be around for their loved ones.</li>
<li><strong>Allow people during longer periods of crunch to take some time off:</strong> This is huge for me, and I've never been anywhere that does this.  If your crunch is going to last a long time, or looks like it will need to be lengthened, give people a day off.  Say "Okay, everyone can take a day off free sometime in the next two weeks."  Giving them a time frame allows them to plan for things like short trips, or time with their family.  They'll come back rested, happier and more productive.</li>
<li><strong>Make sure they have and know the reward:</strong> In a start-up, the reward is in the stock, but in larger companies, make sure people know they will be compensated of extra hours, and then compensate them.</li>
</ol>
<p>Hopefully this makes sense.  I don't like crunch either, and it is avoidable for companies that have really experienced teams and a certain amount of give, but some companies do not and will not have the luxury to avoid crunch entirely.  Obviously, great companies will always avoid crunch, usually because they've learned from their mistakes.  But realize that a good company may crunch, but will always find a way to mitigate it when and if it happens, and will learn from their mistakes on their way to becoming a great company.</p>
<img src="http://feeds.feedburner.com/~r/JeffOnGames/~4/_YLvGaHA42I" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.jeffongames.com/2011/07/thoughts-on-crunch/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Cardboard Jam: Best Jam Ever</title>
		<link>http://www.jeffongames.com/2011/04/cardboard-jam-best-jam-ever/</link>
		<comments>http://www.jeffongames.com/2011/04/cardboard-jam-best-jam-ever/#comments</comments>
		<pubDate>Tue, 12 Apr 2011 14:34:33 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
		
		<guid isPermaLink="false">http://www.jeffongames.com/?p=288</guid>
		<description><![CDATA[This weekend Boston Game Jams ran Cardboard Jam, a game jam where everyone made board or card games instead of making digital games. I have to say, I think I had way more fun at this game jam than at almost any other digital jam I've been a part of for a few reasons. First, <a href="http://www.jeffongames.com/2011/04/cardboard-jam-best-jam-ever/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This weekend <a href="http://bostongamejams.com/">Boston Game Jams</a> ran Cardboard Jam, a game jam where everyone made board or card games instead of making digital games.  I have to say, I think I had way more fun at this game jam than at almost any other digital jam I've been a part of for a few reasons.</p>
<p>First, there's no tech choices or learning curve.  At game digital game Jams, the first thing you have to do (once you have a game you want to create) is decide what technology you want to work in.  This can be tough when you have multiple people who all come with different tech backgrounds and make them try to work together.   Either you end up choosing teams based on tech that people know, or a few people end up working in tech they are unfamiliar with.  This can make many digital game jams more about overcoming technical challenges, rather than overcoming design challenges in the game.</p>
<p>Second, other than the theme of the materials, there was no theme for this Jam.  Though originally I thought this was a detriment, I am beginning to think that the lack of theme contributed to making this Jam awesome.  In every game jam I've participated in, the themes have been aesthetic.  They're themes like "immigration," "extinction," or "deception," and although they offer a good constraint on the Jam (and place everyone on equal footing for implementing an idea), they force most Jammers to think in terms of aesthetic first, mechanic last.  This is why most Jammers can't "finish," because they're actually pushing for an aesthetic, rather than mechanical goal.</p>
<p>Last, jamming in board games meant that iteration cycles were really, really fast, which meant that you could focus on and tune the game and the mechanics quickly, which resulted in better games across the board.  The game I worked on took about 10 minutes to play, and after initial discussion, we did nothing but play it, with short discussions in between.  We probably play tested the game 50 times, each time with slightly tweaked rules to attempt to address problems we were seeing in the previous play through.  Iteration times like this not only let you learn more about the game you're creating, but more about game design in general, since you see the results of you actions quickly.  This speed of iteration and learning would have been impossible in a digital game jam, since implementing rule changes requires too many cycles.  In digital game jams, if you get two to three full playtests in before time is up you're lucky, and that's including for teams that use prebuilt engines like Unity.</p>
<p>So in closing, if you get a chance to participate in a board game jam, you absolutely should.  There's less stress, more learning, and way more collaboration.  That, and you end up with an actually complete board game at the end, which is super awesome.</p>
<img src="http://feeds.feedburner.com/~r/JeffOnGames/~4/8bQwmMVatII" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.jeffongames.com/2011/04/cardboard-jam-best-jam-ever/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

