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

<channel>
	<title>Bytten</title>
	<atom:link href="http://bytten.net/devlog/feed/" rel="self" type="application/rss+xml" />
	<link>http://bytten.net/devlog</link>
	<description></description>
	<lastBuildDate>Sat, 18 Feb 2012 00:00:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.5</generator>
		<item>
		<title>SSS#5: Fighting Back</title>
		<link>http://bytten.net/devlog/2012/02/18/sss5-fighting-back/</link>
		<comments>http://bytten.net/devlog/2012/02/18/sss5-fighting-back/#comments</comments>
		<pubDate>Sat, 18 Feb 2012 00:00:30 +0000</pubDate>
		<dc:creator>tomc</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[game]]></category>
		<category><![CDATA[lennasinception]]></category>
		<category><![CDATA[screenshots]]></category>

		<guid isPermaLink="false">http://bytten.net/devlog/?p=380</guid>
		<description><![CDATA[<p>This week, I added sword attacks, mob death animations, and player inventory to the game.</p>
<div style="text-align: center"><iframe width="320" height="240" src="http://www.youtube.com/embed/-vkjyrZE1M0" frameborder="0" allowfullscreen></iframe></div>
<p style="text-align: center">
<a href="http://bytten.net/devlog/wp-content/uploads/2012/02/ss11.png"><img alt="screenshot" src="http://bytten.net/devlog/wp-content/uploads/2012/02/ss11-150x150.png"/></a> <a href="http://bytten.net/devlog/wp-content/uploads/2012/02/ss31.png"><img alt="screenshot" src="http://bytten.net/devlog/wp-content/uploads/2012/02/ss31-150x150.png"/></a> <a href="http://bytten.net/devlog/wp-content/uploads/2012/02/ss21.png"><img alt="screenshot" src="http://bytten.net/devlog/wp-content/uploads/2012/02/ss21-150x150.png"/></a>
</p>

<p><a href="http://bytten.net/devlog/?p=380">More inside</a>.</p><p class="read-more"><a href="http://bytten.net/devlog/2012/02/18/sss5-fighting-back/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>This week, I added sword attacks, mob death animations, and player inventory to the game.</p>
<div style="text-align: center"><iframe width="640" height="480" src="http://www.youtube.com/embed/-vkjyrZE1M0" frameborder="0" allowfullscreen></iframe></div>
<p></p>
<p>The sword animation is not as glitchy as the video shows &#8212; all three frames do show every time, but youtube seems to skip them sometimes.</p>
<p>Showing the new inventory that lets you equip other items to the Z, X, and C keys:</p>
<p style="text-align: center"><a href="http://bytten.net/devlog/wp-content/uploads/2012/02/ss11.png"><img alt="screenshot" src="http://bytten.net/devlog/wp-content/uploads/2012/02/ss11-150x150.png"/></a></p>
<p>Swinging the level-2 sword:</p>
<p style="text-align: center"><a href="http://bytten.net/devlog/wp-content/uploads/2012/02/ss31.png"><img alt="screenshot" src="http://bytten.net/devlog/wp-content/uploads/2012/02/ss31-150x150.png"/></a></p>
<p>One frame of a yellow slime&#8217;s death animation:</p>
<p style="text-align: center"><a href="http://bytten.net/devlog/wp-content/uploads/2012/02/ss21.png"><img alt="screenshot" src="http://bytten.net/devlog/wp-content/uploads/2012/02/ss21-150x150.png"/></a></p>
]]></content:encoded>
			<wfw:commentRss>http://bytten.net/devlog/2012/02/18/sss5-fighting-back/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Screenshot Saturday #4</title>
		<link>http://bytten.net/devlog/2012/02/11/screenshot-saturday-4/</link>
		<comments>http://bytten.net/devlog/2012/02/11/screenshot-saturday-4/#comments</comments>
		<pubDate>Sat, 11 Feb 2012 00:33:57 +0000</pubDate>
		<dc:creator>tomc</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[game]]></category>
		<category><![CDATA[lennasinception]]></category>
		<category><![CDATA[screenshots]]></category>

		<guid isPermaLink="false">http://bytten.net/devlog/?p=370</guid>
		<description><![CDATA[<p>No screenshots this week, but I do have a video that demonstrates everything I've done.</p>
<div style="text-align:center; margin-bottom: 1em">
<iframe width="640" height="480" src="http://www.youtube.com/embed/FOA_P-eqKhE" frameborder="0" allowfullscreen></iframe>
</div>
<p><a href="http://bytten.net/devlog/?p=370">More inside</a>.</p><p class="read-more"><a href="http://bytten.net/devlog/2012/02/11/screenshot-saturday-4/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>No screenshots this week, but I do have a video that demonstrates everything I&#8217;ve done.</p>
<div style="text-align:center; margin-bottom: 1em">
<iframe width="640" height="480" src="http://www.youtube.com/embed/FOA_P-eqKhE" frameborder="0" allowfullscreen></iframe>
</div>
<p>Essentially, this week I&#8217;ve focused on networking. I&#8217;ve been aware for a while that if I do want to add networked multiplayer to my game, it would be best to get it in early. Retroactively fitting it would be hugely painful. I don&#8217;t know exactly how multiplayer will fit in, in terms of gameplay, but even if it&#8217;s 80% likely it&#8217;ll never be in the finished game, I still think a week spent on it is a worthwhile investment to avoid the risk of later pain.</p>
<p> In the video, I connect two copies of the game on my desktop in the UK to a server in the US. The game has client-side prediction of NPCs and other players to reduce the apparent effects of lag.</p>
<p>It&#8217;s hard to see in the blurry video, but the terminal at the top is measuring network use of the two games. At the end of the video (after 110 seconds), it shows 1MB total (up and down) for the two players&#8217; sessions. This amounts to roughly 5KB/s per player.</p>
]]></content:encoded>
			<wfw:commentRss>http://bytten.net/devlog/2012/02/11/screenshot-saturday-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Screenshot Saturday #3</title>
		<link>http://bytten.net/devlog/2012/02/04/screenshot-saturday-3/</link>
		<comments>http://bytten.net/devlog/2012/02/04/screenshot-saturday-3/#comments</comments>
		<pubDate>Sat, 04 Feb 2012 00:00:17 +0000</pubDate>
		<dc:creator>tomc</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[game]]></category>
		<category><![CDATA[lennasinception]]></category>
		<category><![CDATA[screenshots]]></category>

		<guid isPermaLink="false">http://bytten.net/devlog/?p=325</guid>
		<description><![CDATA[<p>Most of the work I've done on Lenna's Inception this week has been related to saving and loading games, and as such is invisible. New screenshots are here regardless.</p>

<div style="text-align: center">
<iframe width="320" height="240" src="http://www.youtube.com/embed/e0a_E92UMc4" frameborder="0" allowfullscreen></iframe>
</div>

<p style="text-align: center">
<a href="http://bytten.net/devlog/wp-content/uploads/2012/02/ss1.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/02/ss1-150x150.png" alt="" /></a> <a href="http://bytten.net/devlog/wp-content/uploads/2012/02/ss2.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/02/ss2-150x150.png" alt="" /></a>
<a href="http://bytten.net/devlog/wp-content/uploads/2012/02/ss3.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/02/ss3-150x150.png" alt="" /></a> <a href="http://bytten.net/devlog/wp-content/uploads/2012/02/ss6.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/02/ss6-150x150.png" alt="" /></a>
</p>
<p style="text-align: center">
<a href="http://bytten.net/devlog/wp-content/uploads/2012/02/ss4.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/02/ss4-150x150.png" alt="" /></a> <a href="http://bytten.net/devlog/wp-content/uploads/2012/02/ss8.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/02/ss8-150x150.png" alt="" /></a>
</p>
<p style="text-align: center">
<a href="http://bytten.net/devlog/wp-content/uploads/2012/02/ss5.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/02/ss5-150x150.png" alt="" /></a> <a href="http://bytten.net/devlog/wp-content/uploads/2012/02/ss7.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/02/ss7-150x150.png" alt="" /></a>

</p><p><a href="http://bytten.net/devlog/?p=325">More inside</a>.</p><p class="read-more"><a href="http://bytten.net/devlog/2012/02/04/screenshot-saturday-3/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>Most of the work I&#8217;ve done on Lenna&#8217;s Inception this week has been related to saving and loading games, and as such is invisible. New screenshots are here regardless.</p>
<p style="text-align: center">
<iframe width="640" height="480" src="http://www.youtube.com/embed/e0a_E92UMc4" frameborder="0" allowfullscreen></iframe>
</p>
<h2>Saving and loading</h2>
<p>Selected parts of the game model are serialized into XML with <a href="http://xstream.codehaus.org/">XStream</a>, and zipped up into the &#8220;save file&#8221; when saved. If I was not being so strict about the MVC design, this would be a real mess.</p>
<p style="text-align: center">
<a href="http://bytten.net/devlog/wp-content/uploads/2012/02/ss1.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/02/ss1-150x150.png" alt="" /></a> <a href="http://bytten.net/devlog/wp-content/uploads/2012/02/ss2.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/02/ss2-150x150.png" alt="" /></a><br />
<a href="http://bytten.net/devlog/wp-content/uploads/2012/02/ss3.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/02/ss3-150x150.png" alt="" /></a> <a href="http://bytten.net/devlog/wp-content/uploads/2012/02/ss6.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/02/ss6-150x150.png" alt="" /></a>
</p>
<h4>An aside about the game model</h4>
<p>Like in Zelda games, the current map and current room&#8217;s state is not saved, which means enemies come back to life when you load a save (or re-enter a map).</p>
<p>But it is still possible to make permanent changes to the map data in-game. Examples from Zelda would be blowing up a cracked wall with a bomb or defeating a boss enemy. The wall stays blown up and the boss stays dead, even after you exit and re-enter the map.</p>
<p>In Lenna&#8217;s Inception, this is handled through having multiple levels of persistence, which I&#8217;ve implemented as a hierarchy of mirrored game models. Essentially, changes from higher mirrors propagate to lower mirrors, but not the other way. The highest persistence levels are saved, but not the lowest.</p>
<p>The same technique will also (hopefully) lead to easy client-side prediction in networked games.</p>
<p>I might post more about this another time.</p>
<h2>Status bar</h2>
<p>I added the status bar to the bottom of the screen, which contains the tools the player has equipped to the Z, X and C keys, the amount of money the player has, and their current health.</p>
<p style="text-align: center">
<a href="http://bytten.net/devlog/wp-content/uploads/2012/02/ss4.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/02/ss4-150x150.png" alt="" /></a> <a href="http://bytten.net/devlog/wp-content/uploads/2012/02/ss8.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/02/ss8-150x150.png" alt="" /></a>
</p>
<p>There&#8217;s space for more things on the status bar, but I haven&#8217;t decided what to put there yet. Maybe that 48&#215;16 pixel space could be used to display the keys the player currently holds.</p>
<h2>Health and damage</h2>
<p>Mobs now keep track of how many hearts they have, and are erased from the scene upon reaching zero. Except in the case of the player. There is no player-death yet, because I haven&#8217;t implemented the view components and menus for it yet.</p>
<p>At present, only the player can take damage (by touching orange or green slimes). The code is all there for all kinds of mobs to take damage, there just aren&#8217;t any weapons to inflict the pain.</p>
<p style="text-align: center">
<a href="http://bytten.net/devlog/wp-content/uploads/2012/02/ss5.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/02/ss5-150x150.png" alt="" /></a> <a href="http://bytten.net/devlog/wp-content/uploads/2012/02/ss7.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/02/ss7-150x150.png" alt="" /></a></p>
<h2>Procedural Generation</h2>
</p>
<p>I&#8217;ve done some more thinking about <a href="http://bytten.net/devlog/2012/01/25/procedural-dungeon-generation-part-1-5/">procedurally-generating dungeons</a>, and I think it is possible to add on-off switches to dungeons by keeping track of two preconditions for each room: the set of symbols the player <em>definitely</em> must have to get there, and the set of symbols the player <em>might</em> have when there. No SAT-solver necessary.</p>
<p><a href="http://tvtropes.org/pmwiki/pmwiki.php/Main/InterchangeableAntimatterKeys">Consumable keys</a> are more difficult because they actually modify the environment, not just the player (you can only pick up a key once).</p>
<p>I&#8217;ll post Part II when I have more concrete information.</p>
]]></content:encoded>
			<wfw:commentRss>http://bytten.net/devlog/2012/02/04/screenshot-saturday-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Screenshot Saturday #2</title>
		<link>http://bytten.net/devlog/2012/01/28/screenshot-saturday-2/</link>
		<comments>http://bytten.net/devlog/2012/01/28/screenshot-saturday-2/#comments</comments>
		<pubDate>Sat, 28 Jan 2012 00:29:13 +0000</pubDate>
		<dc:creator>tomc</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[game]]></category>
		<category><![CDATA[lennasinception]]></category>
		<category><![CDATA[screenshots]]></category>

		<guid isPermaLink="false">http://bytten.net/devlog/?p=304</guid>
		<description><![CDATA[<p>This week I've done a few little bits and pieces on <a href="http://bytten.net/devlog/tag/lennasinception/">Lenna's Inception</a>.</p>

<div style="text-align:center">
<a href="http://bytten.net/devlog/wp-content/uploads/2012/01/ss14.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/01/ss14-150x150.png" alt="screenshot" /></a> <a href="http://bytten.net/devlog/wp-content/uploads/2012/01/ss23.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/01/ss23-150x150.png" alt="screenshot" /></a><br />
<a href="http://bytten.net/devlog/wp-content/uploads/2012/01/ss33.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/01/ss33-150x150.png" alt="screenshot" /></a> <a href="http://bytten.net/devlog/wp-content/uploads/2012/01/ss43.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/01/ss43-150x150.png" alt="screenshot" /></a><br />

<iframe width="320" height="240" src="http://www.youtube.com/embed/KHceqwWdLgE" frameborder="0" allowfullscreen></iframe>
</div>

<p><a href="http://bytten.net/devlog/2012/01/28/screenshot-saturday-2/">More inside</a>.</p><p class="read-more"><a href="http://bytten.net/devlog/2012/01/28/screenshot-saturday-2/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>This week I&#8217;ve done a few little bits and pieces on <a href="http://bytten.net/devlog/tag/lennasinception/">Lenna&#8217;s Inception</a>.</p>
<ul>
<li>I brightened the palette a bit, because I thought it looked too gray (the original goal was to make it reminiscent of Gameboy graphics, but in color). It&#8217;s still mostly grayish, but the sprites stick out being more brightly-colored.</li>
<li>I improved the mob movement logic to take hit-detection into account on intermediate positions, so mobs can move faster, and the world update tick rate can be reduced. I also reduced the frame-rate to 30 FPS at the same time.</li>
<li>I drew some tiles. It&#8217;s not visible in the screenshots, but adjacent &#8220;hole&#8221; tiles are joined up on-the-fly.</li>
<li>I added animated text boxes that wrap words correctly. They actually look really nice, and the animation is quite smooth. I also added menus, but that was quite late last night, so I don&#8217;t have any screenshots or videos.</li>
<li>I prototyped the <a href="http://bytten.net/devlog/2012/01/25/procedural-dungeon-generation-part-1-5/">procedural dungeon generation algorithm I designed last week</a>, and the results look good &#8211; <a href="http://bytten.net/devlog/2012/01/25/procedural-dungeon-generation-part-1-5/">screenshots</a>.</li>
</ul>
<div style="text-align:center">
<a href="http://bytten.net/devlog/wp-content/uploads/2012/01/ss14.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/01/ss14-150x150.png" alt="screenshot" /></a> <a href="http://bytten.net/devlog/wp-content/uploads/2012/01/ss23.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/01/ss23-150x150.png" alt="screenshot" /></a><br />
<a href="http://bytten.net/devlog/wp-content/uploads/2012/01/ss33.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/01/ss33-150x150.png" alt="screenshot" /></a> <a href="http://bytten.net/devlog/wp-content/uploads/2012/01/ss43.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/01/ss43-150x150.png" alt="screenshot" /></a></p>
<p><iframe width="640" height="480" src="http://www.youtube.com/embed/KHceqwWdLgE" frameborder="0" allowfullscreen></iframe>
</div>
<p><a href="http://bytten.net/devlog/2012/01/21/screenshot-saturday-1/">Link to Screenshot Saturday #1</a>.</p>
<p><a href="http://www.reddit.com/r/gamedev/comments/p0b13/screenshot_saturday_51_hooray_for_another_passed/">Screenshot Saturday 51 on /r/GameDev</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://bytten.net/devlog/2012/01/28/screenshot-saturday-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Procedural Dungeon Generation &#8211; Part 1.5</title>
		<link>http://bytten.net/devlog/2012/01/25/procedural-dungeon-generation-part-1-5/</link>
		<comments>http://bytten.net/devlog/2012/01/25/procedural-dungeon-generation-part-1-5/#comments</comments>
		<pubDate>Wed, 25 Jan 2012 20:35:07 +0000</pubDate>
		<dc:creator>tomc</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[lennasinception]]></category>
		<category><![CDATA[metazelda]]></category>
		<category><![CDATA[proceduralgeneration]]></category>

		<guid isPermaLink="false">http://bytten.net/devlog/?p=248</guid>
		<description><![CDATA[<p>In <a href="http://bytten.net/devlog/2012/01/21/procedural-dungeon-generation-part-i/">my previous post on procedural generation</a>, I proposed an algorithm for generating dungeons with puzzles including keys and locked doors.</p>
<div style="text-align:center">
<a href="http://bytten.net/devlog/wp-content/uploads/2012/01/ss13.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/01/ss13-150x150.png" /></a> <a href="http://bytten.net/devlog/wp-content/uploads/2012/01/ss32.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/01/ss32-150x150.png" /></a>
</div>
<p>The algorithm took about three hours to implement in Java, including the viewer, and I've <a href="https://github.com/tcoxon/metazelda">uploaded it</a> to github.</p>
<p><a href="http://bytten.net/devlog/?p=248">More inside</a>.</p><p class="read-more"><a href="http://bytten.net/devlog/2012/01/25/procedural-dungeon-generation-part-1-5/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://bytten.net/devlog/2012/01/21/procedural-dungeon-generation-part-i/">my previous post on procedural generation</a>, I proposed an algorithm for generating dungeons with puzzles including:</p>
<ul>
<li>Keys and locked doors;</li>
<li>Switches that must be used to activate pistons that unblock paths;</li>
<li>Items that grant new abilities to the player that permit access to new areas (such as the <a href="http://www.zeldawiki.org/Roc's_Feather">Roc&#8217;s Feather</a> or the <a href="http://www.zeldawiki.org/Power_Bracelet">Power Bracelet</a> in <a href="http://en.wikipedia.org/wiki/The_Legend_of_Zelda:_Link's_Awakening">Link&#8217;s Awakening</a>).</li>
</ul>
<p>These items have very similar properties and an abstraction that treats them all as boolean variables permits levels to be generated in such a way that every room is reachable, and the dungeon is guaranteed to be solvable (see <a href="http://bytten.net/devlog/2012/01/21/procedural-dungeon-generation-part-i/">Part I</a> for the details). Purely random placement of keys and locks cannot achieve this.</p>
<p>Lowering, a post-processing phase over the results of this algorithm, generates the exact layout of walls, floor tiles, items and enemies. As this phase will be different for each game that uses the algorithm, I haven&#8217;t explained this in detail.</p>
<h2>An implementation!</h2>
<p>The algorithm took about three hours to implement in Java, including the viewer, and I&#8217;ve <a href="https://github.com/tcoxon/metazelda">uploaded it</a> to github. All the important data-structures and the algorithm itself are in the package <a href="https://github.com/tcoxon/metazelda/tree/master/src/net/bytten/metazelda/algo">net.bytten.metazelda.algo</a>.</p>
<p>I&#8217;ve added very little tweaking to the probabilities that the algorithm uses, so a lot of the results are garbage, but there are still some very interesting dungeons that come out of it.</p>
<div style="text-align:center">
<a href="http://bytten.net/devlog/wp-content/uploads/2012/01/ss22.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/01/ss22-150x150.png" /></a> <a href="http://bytten.net/devlog/wp-content/uploads/2012/01/ss13.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/01/ss13-150x150.png" /></a><br />
<a href="http://bytten.net/devlog/wp-content/uploads/2012/01/ss32.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/01/ss32-150x150.png" /></a> <a href="http://bytten.net/devlog/wp-content/uploads/2012/01/ss42.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/01/ss42-150x150.png" /></a><br />
<a href="http://bytten.net/devlog/wp-content/uploads/2012/01/ss5.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/01/ss5-150x150.png" /></a>
</div>
<p>How to read these diagrams:</p>
<ul>
<li>Circles are rooms.</li>
<li>The player starts at the &#8220;Start&#8221; room, and tries to get to the &#8220;Goal&#8221; room.</li>
<li>A letter inside a room is an item that the player can get while inside the room.</li>
<li>Arrows are unidirectional edges &#8211; the player can move from one room to another in the direction of the arrow, but not the other way.</li>
<li>Non-arrow edges are bidirectional &#8211; the player can move in both directions.</li>
<li>Both unidirectional and bidirectional edges may have conditions attached, which are a list of items the player must hold to be able to move along the edge.</li>
</ul>
<h2>Tweaks</h2>
<p>There are a lot of ways to improve the implementation without significantly modifying the algorithm, and I intend to keep updating the github project. Here are some ideas I&#8217;ve had:</p>
<ul>
<li>Dungeons can be quite strung out at the moment. I could bias the randomness towards keeping near the start node.</li>
<li>Producing dungeons within a particular shape would be interesting to try. Dungeons in Zelda are often designed into particular shapes, e.g. skulls, keys.</li>
<li>Some dungeons are perhaps too non-linear, and require a lot of backtracking. <a href="http://iameviltom.com/">Tom Vernon</a> linked to an article about <a href="http://www.gamasutra.com/view/feature/6582/learning_from_the_masters_level_.php">level-design in The Legend of Zelda</a> in the <a href="http://bytten.net/devlog/2012/01/21/procedural-dungeon-generation-part-i/#comment-6">comments on Part I</a>. Some ideas could be taken from that. Perhaps if I can design a programmatic way to measure &#8220;linearity&#8221; partway through construction of the dungeon, the algorithm optimized for slight non-linearity.</li>
</ul>
<h2>Bugfixes</h2>
<p>In the original algorithm, there was a flaw in the handling of dead-end branches in &#8220;backedge&#8221;-generation that would allow a player to get trapped in a subset of rooms. It assumed that to reach the current room, all already-placed rooms must have been visited. This is not true for dead-ends, which are optional.</p>
<p>The Java implementation adds unidirectional edges to neighboring rooms in a different way &#8211; it actually computes the preconditions for entering each of the rooms as they&#8217;re generated and later on checks that the new room&#8217;s preconditions imply the neighbor room&#8217;s preconditions. When this implication holds, the player is guaranteed to not get trapped. In addition, by testing the implication the other way we can efficiently find out whether a bidirectional edge can be added without creating a short-cut past a locked door.</p>
<h2>Related work</h2>
<p>I recently came across <a href="http://smartech.gatech.edu/handle/1853/16823?mode=full">Ashmore&#8217;s scientific paper &#8220;Key and Lock Puzzles in Procedural Gameplay&#8221;</a> that covers similar grounds. Although it doesn&#8217;t specify an algorithm that generates solvable key and lock puzzles, it does describe the concept of an evaluator that selects the &#8220;best&#8221; puzzles, and what characteristics might be selected for. Another interesting note from that research is that the puzzle generator cannot be completely divorced from the &#8220;renderer&#8221; (which I called the lowering phase) because not all valid abstract puzzles correspond to rendered games (lowered dungeons).</p>
]]></content:encoded>
			<wfw:commentRss>http://bytten.net/devlog/2012/01/25/procedural-dungeon-generation-part-1-5/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Screenshot Saturday #1</title>
		<link>http://bytten.net/devlog/2012/01/21/screenshot-saturday-1/</link>
		<comments>http://bytten.net/devlog/2012/01/21/screenshot-saturday-1/#comments</comments>
		<pubDate>Sat, 21 Jan 2012 18:28:36 +0000</pubDate>
		<dc:creator>tomc</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[game]]></category>
		<category><![CDATA[lennasinception]]></category>
		<category><![CDATA[screenshots]]></category>

		<guid isPermaLink="false">http://bytten.net/devlog/?p=230</guid>
		<description><![CDATA[<p>Progress on <a href="http://bytten.net/devlog/tag/lennasinception/">Lenna's Inception</a> was slow this week, due to an unrelated software release (<a href="http://bytten.net/devlog/milk-for-dead-hamsters/">M4DH</a>). I did manage to design an algorithm for <a href="http://bytten.net/devlog/2012/01/21/procedural-dungeon-generation-part-i/">procedural Zelda-style dungeon puzzle generation</a>. As nothing visible on the game changed, I have no new screenshots.</p>
<p><a href="http://bytten.net/devlog/?p=230">More inside</a>.</p><p class="read-more"><a href="http://bytten.net/devlog/2012/01/21/screenshot-saturday-1/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>Progress on <a href="http://bytten.net/devlog/tag/lennasinception/">Lenna&#8217;s Inception</a> was slow this week, due to an unrelated software release (<a href="http://bytten.net/devlog/milk-for-dead-hamsters/">M4DH</a>). I did manage to design an algorithm for <a href="http://bytten.net/devlog/2012/01/21/procedural-dungeon-generation-part-i/">procedural Zelda-style dungeon puzzle generation</a>.</p>
<p>As nothing visible on the game changed, I have no new screenshots. Failure at the first hurdle?</p>
<ul>
<li><a href="http://www.reddit.com/r/gamedev/comments/oq0qv/screenshot_saturday_50_evolution/">/r/GameDev&#8217;s 50th Screenshot Saturday</a></li>
<li><a href="http://bytten.net/devlog/2012/01/17/the-inception-of-lennas-inception/">Previous screenshots</a>.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://bytten.net/devlog/2012/01/21/screenshot-saturday-1/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Procedural Dungeon Generation &#8211; Part I</title>
		<link>http://bytten.net/devlog/2012/01/21/procedural-dungeon-generation-part-i/</link>
		<comments>http://bytten.net/devlog/2012/01/21/procedural-dungeon-generation-part-i/#comments</comments>
		<pubDate>Sat, 21 Jan 2012 17:34:52 +0000</pubDate>
		<dc:creator>tomc</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[game]]></category>
		<category><![CDATA[lennasinception]]></category>
		<category><![CDATA[metazelda]]></category>
		<category><![CDATA[proceduralgeneration]]></category>

		<guid isPermaLink="false">http://bytten.net/devlog/?p=140</guid>
		<description><![CDATA[<p>I mentioned in my post, <a href="http://bytten.net/devlog/2012/01/17/the-inception-of-lennas-inception/">The Inception of Lenna's Inception</a>, that I wanted to combine Zelda's game mechanics with roguelike randomization for my game <a href="http://bytten.net/devlog/tag/lennasinception/">Lenna's Inception</a>. <a href="http://en.wikipedia.org/wiki/The_Binding_of_Isaac_(video_game)">The Binding of Isaac</a> went some way towards this, but doesn't contain the item-based puzzles that (to me, at least) characterize Zelda.</p>
<p>In this post, I'll introduce an abstraction for Zelda-like item-based puzzles, and an initial algorithm for generating puzzles procedurally.</p>
<p><a href="http://bytten.net/devlog/2012/01/21/procedural-dungeon-generation-part-i/">More inside</a>.</p><p class="read-more"><a href="http://bytten.net/devlog/2012/01/21/procedural-dungeon-generation-part-i/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>I mentioned in my post, <a href="http://bytten.net/devlog/2012/01/17/the-inception-of-lennas-inception/">The Inception of Lenna&#8217;s Inception</a>, that I wanted to combine Zelda&#8217;s game mechanics with roguelike randomization for my game <a href="http://bytten.net/devlog/tag/lennasinception/">Lenna&#8217;s Inception</a>. <a href="http://en.wikipedia.org/wiki/The_Binding_of_Isaac_(video_game)">The Binding of Isaac</a> went some way towards this, but doesn&#8217;t contain the item-based puzzles that (to me, at least) characterize Zelda.</p>
<p>In this post, I&#8217;ll introduce an abstraction for Zelda-like item-based puzzles, and an initial algorithm for generating puzzles procedurally.</p>
<h2>Item-based puzzles</h2>
<p>Dungeons in <a href="http://en.wikipedia.org/wiki/The_Legend_of_Zelda:_Link's_Awakening">Link&#8217;s Awakening</a> are broken down into discrete rooms of fixed size, laid out in a grid. Some rooms have walls separating them, and some of those walls have doors, which are possibly locked. In these rooms you can find, amongst other items that are unimportant for the sake of this article:</p>
<ul>
<li><em>Keys</em> that unlock a door (and leave the door unlocked, but can only be used once);</li>
<li>A single <em>boss key</em> (aka a big key) that unlocks the door to the boss;</li>
<li><em>Switches</em> that lower and raise piston blocks elsewhere in the dungeon that block your way;</li>
<li>And <em>equipment</em> such as the Roc&#8217;s Feather that allows you to jump over pits that otherwise don&#8217;t let you pass.</li>
</ul>
<p>The following image is an example of what a really minimalist dungeon in Link&#8217;s awakening might look like. (And I mean <em>really</em> minimal. If there was a level like this in a Zelda game, I&#8217;d be getting my money back.) More often there are multiple locked doors, and multiple keys, and a miniboss or two in there. <a href="http://www.zelda-infinite.com/games/zelda4/maps/">For some real examples from real Link&#8217;s Awakening, see the Zelda Infinite website</a>.</p>
<p style="text-align:center"><a href="http://bytten.net/devlog/wp-content/uploads/2012/01/diag1.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/01/diag1.png" alt="Simple example of item-based puzzles, Zelda-style" width="320" height="240"/></a></p>
<p>The player starts (obviously) at the start, and the goal is (obviously) to get to the goal. But: you can&#8217;t go to the goal without first beating the boss; you can&#8217;t get to the boss without jumping over the pit surrounding his door; you can&#8217;t jump the pit without getting the feather; you can&#8217;t get the feather without unlocking the door to it; and you can&#8217;t unlock the door without getting the key. You have to find the right sequence of rooms to go through to get to the goal.</p>
<p>These inter-room puzzles are the kind I want to generate procedurally. There are also intra-room puzzles, where you have to perform some specific action (e.g. killing all the enemies) within the room to get that room&#8217;s item, but they&#8217;re not the focus of this article.</p>
<h2>Puzzling abstraction</h2>
<p>All of the elements of these puzzles &#8212; the keys, switches and equipment &#8212; have one important thing in common: there&#8217;s originally some obstacle you can&#8217;t pass until you find a certain item that eliminates the obstacle. There&#8217;s an abstraction we can make here.</p>
<p>Enter the Legend of Metazelda.</p>
<p>Let&#8217;s forget for now that these items are keys, switches and equipment, and instead think about boolean variables: you either have a key or you don&#8217;t; the switch is either on or off; you either have the equipment or you don&#8217;t. We&#8217;ll give a letter to each of these boolean variables, e.g. K, S, E, etc. Each of these variables is false initially, but goes true when the player collects the key, hits the switch or picks up the equipment. For the sake of simplicity later on, we&#8217;re going to assume these variables never go false again: keys are not consumed by use with a locked door, and the switch does not need to be turned back off to solve a puzzle.</p>
<p>An extension to the algorithm would allow <a href="http://tvtropes.org/pmwiki/pmwiki.php/Main/InterchangeableAntimatterKeys">consumable keys</a> and off-switch puzzles, but is not explored in this post. The extension may not even be necessary for a game to be entertaining: keys and doors can be made colored like in Doom; and the player might not notice that they never need to turn a switch off (especially if there are multiple sets of switches and pistons).</p>
<p>The next thing to abstract is the grid of rooms: it&#8217;s now a graph. Each node in the graph represents a room, and can contain the letter of a boolean variable to set true on entry. Nodes are connected via edges to other nodes. These edges are unidirectional, permitting travel in only one direction, but two edges in opposite directions between the same two nodes can be considered to be one bidirectional node as a useful shorthand. Each edge is optionally labelled by the letters of boolean variables that must all be true for the player to be able to travel along that edge.</p>
<p>Here&#8217;s how the example dungeon looks now:</p>
<p style="text-align:center"><a href="http://bytten.net/devlog/wp-content/uploads/2012/01/diag2.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/01/diag2.png" alt="A Metazelda dungeon map" /></a></p>
<p>In the Legend of Metazelda, the player starts dungeons at the node where the arrow points and by moving along edges to other nodes, collects letters that grant access along other edges to more nodes, eventually reaching the goal node (the double-lined circle in the diagram).</p>
<div style="margin-left: 4em">
<h4>Warning: Computer Science (skippable)</h4>
<p>It&#8217;s interesting to note that Metazelda dungeons are a special case of <a href="http://en.wikipedia.org/wiki/Extended_finite-state_machine">Extended Finite State Machines</a>.</p>
<p>If you don&#8217;t know what a finite state machine is, google it. They&#8217;re used in lots of places, regular expressions for example. If you have a good link that explains them, put it in the comments, and I&#8217;ll include it here.</p>
<p>An <em>extended</em> finite state machine extends the model of a FSM with &#8220;if conditions&#8221; on the transition edges. In a Metazelda dungeon, the EFSM states are our nodes, the transitions are our edges, the input symbols are the movements of the player character, the &#8220;if conditions&#8221; are the boolean variables the edges are labelled with, and the update function implements &#8220;V := true&#8221; where V is the boolean variable name written in the node we move to.</p>
<p>The version of the algorithm in this article produces solvable dungeons by virtue of the fact that the boolean variables only ever transition to true. If you were to add variable transitions to false (e.g. consumed keys, off-switches), you would then need to check that the modified dungeon is still solvable at intermediate steps. Scientifically speaking, you would need to find out whether the goal is still a <em>reachable</em> state. Presburger Engines are used to solve reachability for the general case of EFSMs, but I suspect these boolean-variabled Metazelda dungeons are simple enough to do relatively easily with just a <a href="http://en.wikipedia.org/wiki/Boolean_satisfiability_problem">SAT solver</a> (although I have yet to figure out exactly how).</p>
</div>
<h2>Generating Metazelda dungeons</h2>
<p>How can we generate these dungeons? Purely randomly would not work &#8212; what if it generated a dungeon with a locked door and the only key in the dungeon was behind that door? It would make the dungeon unwinnable. Players don&#8217;t like that. It&#8217;s really bad level design.</p>
<p>I spent a long time looking for algorithms for this that someone had already documented, but I couldn&#8217;t find any. There is a real dearth of concrete information about procedural generation on the web, so in the end I rolled my own algorithm.</p>
<p>The first things to define are the data-structures this algorithm uses. Although the abstract Metazelda dungeons are graphs, we hope to eventually be able to lower them into two-dimensional grids of rooms (or three dimensions, if adding multiple floors). For this reason, we implement the dungeon graph as a two-dimensional array, each slot in the array representing a node (room). Each room has an array of four values that define whether there is an open unidirectional edge in each of the four directions. This is still a graph, it&#8217;s just a specialized one.</p>
<pre>
(N,E,S,W) = (0,1,2,3)
NUM_DIRS = 4

class Edge:
    condition: Letter or None

class Room:
    x,y: Int
    item: Letter or None
    edges[4]: Edge or None    # index with N,E,S,W

type Dungeon:
    # dynamically-extendable 2D array of (Room or None)
    # indexable by the (x,y) coordinates of a room
    # implementation left as an exercise for the reader
</pre>
<p>Following are some utility functions that go with these structures, and are used in the algorithm:</p>
<pre>
def Room.random_free_edge():
    d = random.randint(0,NUM_DIRS)
    tries = 0
    while (this.edges[d] is not None) and (tries < NUM_DIRS):
        d = (d+1)%NUM_DIRS
        tries += 1
    if this.edges[d] is None:
        return d
    return None

def adjacent_coords((x,y),d):
    # Return the coordinates of the next room in the given direction
    if d == N:
        return (x,y-1)
    if d == E:
        return (x+1,y)
    if d == S:
        return (x,y+1)
    if d == W:
        return (x-1,y)

def opposite_dir(d):
    if d == N: return S
    if d == E: return W
    if d == S: return N
    if d == W: return E

def Dungeon.adjacent_space_dir(room):
    # return direction of travel from room to a random adjacent space
    # or None if there are none
    d = random.randint(0,NUM_DIRS)
    tries = 0
    (x,y) = adjacent_coords((room.x,room.y),d)
    while (this[x][y] is not None) and (tries < NUM_DIRS):
        d = (d+1)%NUM_DIRS
        tries += 1
        (x,y) = adjacent_coords((room.x,room.y),d)
    if this[x][y] is None:
        return d
    return None
</pre>
<p>Then adding a room to the dungeon containing a given item can be implemented recursively.</p>
</pre>
<pre>
def Dungeon.add_room(item: Letter or None, enable_backedge: bool):
    # Add a new room to the dungeon containing given item. Conditions to enter
    # the room are randomly generated, and if requiring a new item in the dungeon,
    # will cause other rooms to be added, too.
    #
    # "enable_backedge" controls whether unidirectional edges between new rooms
    # and pre-existing rooms may be added.

    # condition to enter the room
    cond = None
    # make a random choice: either do the "_either:" or one of the "_or:" blocks
    # -- <strong>see note (0)</strong>
    randomly_either:
        # choose new boolean variable that must be true to enter this room
        cond = this.new_unused_letter()
        # add an item for this letter to the dungeon so the room is reachable
        this.add_room(cond, enable_backedge)
    randomly_or:
        # choose a boolean variable with a letter already obtainable in the dungeon
        cond = this.random_preexisting_letter()
    randomly_or:
        # leave cond None, meaning entry always available
        pass

    # choose where to place the new room
    (loc,d) = None
    randomly_either:
        # add padding rooms (and potentially more conditions along the way), but
        # disable backedge generation -- <strong>see note (3)</strong>
        loc = this.add_room(None, False)
        d = this.adjacent_space_dir(loc)
        # add_room can create a room with no adjacent spaces, so d might still be
        # None -- <strong>see note (1)</strong>
    randomly_or:
        pass

    if loc is None or d is None:
        # choose an existing room with a free edge
        (loc,d) = this.random_external_room() # -- <strong>see note (2)</strong>

    # create new room
    room = new Room
    (room.x, room.y) = adjacent_coords((loc.x,loc.y), d)
    room.item = item

    # link new room to loc
    edge = new Edge
    edge.condition = cond
    room.edges[opposite_dir(d)] = edge
    loc.edges[d] = edge

    if enable_backedge:
        randomly_either:
            # add a unidirectional edge into an adjacent room.
            # the conditions to enter our room necessarily imply the conditions to
            # enter the adjacent one -- <strong>see note (3)</strong>
            bd = room.random_free_edge()
            (bx,by) = adjacent_coords((room.x,room.y), bd)
            if this[bx][by] is not None:
                # player can move from our room into the adjacent one, but not the
                # other way
                room.edges[bd] = new Edge
        randomly_or:
            pass

    return room
</pre>
<p>To use the algorithm, initialize the dungeon with a single room (the start room), and use Dungeon.add_room(&#8216;X&#8217;, True) to fill it (where X is the goal).</p>
<h6>Note 0:</h6>
<p>Lots of randomness is used in this algorithm. Probably a lot of the work of implementing it will be tweaking the probabilities to make it design dungeons well. At the very least, you should make the probabilities dependent on the number of rooms already in the dungeon, otherwise the sizes of the generated dungeons are unbounded.</p>
<h6>Note 1:</h6>
<p>This algorithm can generate dead-ends with no useful items in them. It doesn&#8217;t have to be a total waste of time to the player though &#8212; money, health, maps and compasses can be easily added to these dead ends in a post-processing step. These dead ends are easy to search for because they have only one out-going edge attached to them, and no item.</p>
<h6>Note 2:</h6>
<p>When connecting the room to a pre-existing room, it randomly chooses an <em>external</em> room:</p>
<pre>(loc,d) = this.random_external_room()</pre>
<p>This means it picks a room that has a side beyond which no other rooms exist (it also returns that side as a direction). This prevents the algorithm from getting stuck inside a small bounded space delineated by a perimeter of pre-existing rooms. Implementation is left as an exercise to the reader.</p>
<p>A smarter algorithm might pass into Dungeon.add_room how much space is needed by dependent rooms, and then when connecting to pre-existing rooms, chooses a room where there is enough space.</p>
<h6>Note 3:</h6>
<p>I added &#8220;backedge&#8221; generation to make the dungeons less tree-like and more graph-like. It adds a unidirectional edge between the new room and an adjacent pre-existing one, and is the only way cycles are generated in the dungeon graph with this algorithm.</p>
<p>Backedges are generated only when doing so cannot create a short-cut past a pre-existing obstacle. For this reason, backedge generation must be disabled when adding the padding rooms between existing rooms and the new room. This does however mean that the only rooms with backedges are the ones that contain important items &#8212; keys, equipment.</p>
<p>As a modification, you could force the padding rooms to be generated with edges such that cond must be true on a subset of them. Then backedges can be generated for that subset.</p>
<p><strong>Update:</strong> this part of the algorithm can cause the generation of trapped rooms that the player cannot escape. <a href="http://bytten.net/devlog/2012/01/25/procedural-dungeon-generation-part-1-5/">Part 1.5</a> has a fixed implementation the algorithm in Java that fixes this.</p>
<h2>Adding Bosses, Boss Keys, Equipment and Minibosses</h2>
<p>In Zelda, some of the puzzle elements are guaranteed to occur in each dungeon, and usually occur in a certain order:</p>
<ol>
<li>The player first defeats the miniboss.</li>
<li>Defeating the miniboss grants access to the rest of the dungeon where the equipment and the boss key can be found.</li>
<li>The boss is in the room immediately before the goal.</li>
</ol>
<p>This can be implemented by writing specialized versions of add_room for the goal, boss, boss key, and equipment:</p>
<ul>
<li>Placing the goal first places the boss, and then adds a bidirectional edge directly to it.</li>
<li>When adding the boss room, it always has the boss key as a condition. This triggers placement of the boss key.</li>
<li>When adding the boss key room, it always has the equipment as a condition. This triggers placement of the equipment.</li>
<li>Placing the equipment first places the miniboss, and then adds the equipment room with a bidirectional edge directly to it.</li>
</ul>
<h2>Lowering</h2>
<p>Of course, this algorithm hasn&#8217;t dealt with the concrete layout of rooms in the dungeon. It&#8217;s still quite an abstract representation.</p>
<p>&#8220;Lowering&#8221; converts this abstract representation of nodes and edges into something concrete, with specific room layouts, doors, and intra-room puzzles. Some of the characteristics of the rooms are already known (important items, open walls/doors), so this information could be used to select a specific room layout from a library of pre-designed rooms. Or another level of procedural generation could design the rooms.</p>
<h2>Final note</h2>
<p>I&#8217;ve published this algorithm for multiple reasons. The first is that I hope I can get feedback about it from readers. If anyone has implemented something like this before and has some helpful advice, it could speed along development of Lenna&#8217;s Inception.</p>
<p>Secondly, from the point of view of a player, I want to do what I can to help improve games with roguelike procedural generation. If you use this algorithm, let me know so I can play your game!</p>
<h2>Next time</h2>
<p>Part II will go up when (if) I work out how to extend this algorithm to generate dungeons that contain consumable keys, and puzzles requiring turning switches off. I suspect this will require the use of a <a href="http://en.wikipedia.org/wiki/Boolean_satisfiability_problem">SAT solver</a> to check intermediate steps, so it will get a whole lot more mathsy.</p>
<p>I may also post a (short) Part 1.5 when I have a demo implementation of this algorithm.</p>
<p><strong>Update:</strong> <a href="http://bytten.net/devlog/2012/01/25/procedural-dungeon-generation-part-1-5/">Part 1.5</a> is up!</p>
]]></content:encoded>
			<wfw:commentRss>http://bytten.net/devlog/2012/01/21/procedural-dungeon-generation-part-i/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>The Inception of Lenna&#8217;s Inception</title>
		<link>http://bytten.net/devlog/2012/01/17/the-inception-of-lennas-inception/</link>
		<comments>http://bytten.net/devlog/2012/01/17/the-inception-of-lennas-inception/#comments</comments>
		<pubDate>Tue, 17 Jan 2012 23:15:39 +0000</pubDate>
		<dc:creator>tomc</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[game]]></category>
		<category><![CDATA[lennasinception]]></category>

		<guid isPermaLink="false">http://bytten.net/devlog/?p=97</guid>
		<description><![CDATA[<p>I spent a lot of time playing <a href="http://en.wikipedia.org/wiki/The_Legend_of_Zelda:_Link's_Awakening">Link's Awakening</a> over the holidays, and while I was playing it, I couldn't help but pick apart the mechanics of the game. It was like I was Neo in the Matrix: I could see the code (although definitely <em>not</em> in a literal sense, Nintendo). This gave me some ideas...</p>

<p style="text-align: center"><a href="http://bytten.net/devlog/wp-content/uploads/2012/01/ss12.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/01/ss12-150x150.png" alt="" /></a><a href="http://bytten.net/devlog/wp-content/uploads/2012/01/ss21.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/01/ss21-150x150.png" alt="" /></a></p>
<p style="text-align: center"><iframe width="320" height="240" src="http://www.youtube.com/embed/GpfPMVT55Zc" frameborder="0" allowfullscreen></iframe></p>
<p><a href="http://bytten.net/devlog/2012/01/17/the-inception-of-lennas-inception/">More inside</a>.</p><p class="read-more"><a href="http://bytten.net/devlog/2012/01/17/the-inception-of-lennas-inception/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>I spent a lot of time playing <a href="http://en.wikipedia.org/wiki/The_Legend_of_Zelda:_Link's_Awakening">Link&#8217;s Awakening</a> over the holidays, and while I was playing it, I couldn&#8217;t help but pick apart the mechanics of the game. It was like I was Neo in the Matrix: I could see the code (although definitely <em>not</em> in a literal sense, Nintendo).</p>
<p>This gave me some ideas, and I wondered how well some of Zelda&#8217;s game mechanics would work with some of the features of typical roguelikes, particularly randomization. <a href="http://en.wikipedia.org/wiki/The_Binding_of_Isaac_(video_game)">The Binding of Isaac</a> has been described to be a Zelda-like roguelike, but I&#8217;m not sure I really agree with that. To me, Zelda games are characterized by the item-based puzzles and the RPG elements in the overworld between dungeons. The Binding of Isaac plays more like an (awesome) top-down shooter/roguelike that superficially looks like Zelda.</p>
<p>Anyway, from here on I&#8217;m going to avoid saying anything about what I want to do, and talk only about what I have done: I&#8217;ve started coding a game. I have a rough idea of the direction I want to take it, but I&#8217;m aware that could change dramatically (which I am quite prone to do), or I could drop the project entirely to work on something else. For now, I&#8217;ve codenamed the game &#8220;Lenna&#8217;s Inception,&#8221; and the core library/engine running it &#8220;legend.&#8221;</p>
<p>Starting this weekend, I&#8217;m going to try to post a short progress update every Saturday &#8212; coinciding with <a href="http://www.reddit.com/r/gamedev/search?q=screenshot+saturday&#038;restrict_sr=on&#038;sort=relevance">/r/gamedev&#8217;s Screenshot Saturday</a>. It&#8217;ll be fun for me to look back on this in future.</p>
<h2>Progress so far</h2>
<p style="text-align: center"><a href="http://bytten.net/devlog/wp-content/uploads/2012/01/ss12.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/01/ss12-150x150.png" alt="" /></a><a href="http://bytten.net/devlog/wp-content/uploads/2012/01/ss21.png"><img src="http://bytten.net/devlog/wp-content/uploads/2012/01/ss21-150x150.png" alt="" /></a></p>
<p style="text-align: center"><iframe width="640" height="480" src="http://www.youtube.com/embed/GpfPMVT55Zc" frameborder="0" allowfullscreen></iframe></p>
<p>I&#8217;ve spent one week of evenings on this so far. Here&#8217;s where it&#8217;s at now:</p>
<ul>
<li>Awful sprites and font. I&#8217;m really not an artist.</li>
<li>Clean MVC design.</li>
<li>Game object model mostly pinned down. Written in such a way that syncing and mirroring it over a network should be easy.</li>
<li>Reduced-color palette, and sprite recoloring (trying to emulate the feel of NES / Gameboy). Probably still needs some tweaks. I think it&#8217;s too brown.</li>
<li>Mob AI as finite state machine. Slime AI (seen in the video) written in about 20 lines of code.</li>
<li>Written in Java; image manipulation, drawing and controls completely abstracted away so the core of the game will run on Android without any modification.</li>
</ul>
<p>The challenges I faced:</p>
<ul>
<li>Some nasty deadlocks were occurring on the screen transitions, due to the need to lock multiple objects when drawing the object tree. In the end I gave up and put all game logic and drawing on the same thread.</li>
<li>Recoloring sprites efficiently was a hard one to work out. There are still a few things I can do to improve it, but it&#8217;s OK for now.</li>
</ul>
<p>What I need to do next:</p>
<ul>
<li>Hit detection needs some tweaks to be able to correctly handle Mobs moving at any speed.</li>
<li>Add mob health and damage.</li>
<li>Draw some tiles. I&#8217;m fed up of filled rects.</li>
<li>Add more mobs and sprites.</li>
<li>Implement networking and benchmark it to see how much bandwidth multiplayer uses. (I really need to find out if my object model works in this regard soon in case I need to reengineer it for efficiency.)</li>
<li>See if using OpenGL is faster than java.awt.Graphics2D.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://bytten.net/devlog/2012/01/17/the-inception-of-lennas-inception/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>360 Degree Field of View</title>
		<link>http://bytten.net/devlog/2012/01/16/360-degree-field-of-view/</link>
		<comments>http://bytten.net/devlog/2012/01/16/360-degree-field-of-view/#comments</comments>
		<pubDate>Mon, 16 Jan 2012 22:18:30 +0000</pubDate>
		<dc:creator>tomc</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[fishpye]]></category>
		<category><![CDATA[opencl]]></category>
		<category><![CDATA[raytracing]]></category>

		<guid isPermaLink="false">http://bytten.net/testing2/?p=12</guid>
		<description><![CDATA[<p>It was a question that inspired me to start programming <a href="http://github.com/tcoxon/fishpye">fishpye</a> (also known as raycl): what would it look like to be able to see in all directions at once? The answer, it seems, is quite weird:</p>
<p style="text-align:center"><iframe width="320" height="240" src="http://www.youtube.com/embed/TBL7Y7_kCjA" frameborder="0" allowfullscreen></iframe></p><p class="read-more"><a href="http://bytten.net/devlog/2012/01/16/360-degree-field-of-view/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>It was a question that inspired me to start programming <a href="http://github.com/tcoxon/fishpye">fishpye</a> (also known as raycl): what would it look like to be able to see in all directions at once?</p>
<p>The answer, it seems, is quite weird:</p>
<p style="text-align:center"><iframe width="640" height="480" src="http://www.youtube.com/embed/TBL7Y7_kCjA" frameborder="0" allowfullscreen></iframe></p>
<p>The project is written in Python and OpenCL. Enj did <a href="http://enja.org/category/tutorial/advcl/">a fantastic series of PyOpenCL tutorials</a> that are worth reading over if you&#8217;re curious.</p>
<p>If you want to give it a try, install Python and the OpenCL drivers for your graphics card. You will need a beefy graphics card &#8212; I used a NVIDIA GTX 570.</p>
<h2>Ray-tracing and rasterization</h2>
<p>The most common algorithm for rendering 3D graphics is rasterization. It can be executed fast enough on graphics cards to update the screen in real-time, mainly because it transforms 3D vertices into a 2D plane using <em>really</em> fast matrix operations. It&#8217;s also an <a href="http://en.wikipedia.org/wiki/Embarrassingly_parallel">embarrasingly parallel</a> problem.</p>
<p>Another algorithm for rendering 3D graphics is ray-tracing. This algorithm is usually used to produce realistic-looking images. This is made easy by the way it works &#8212; it essentially simulates each ray of light in reverse. A ray is traced from the eye of the viewer outwards, until it hits an object. At that point, more rays are generated for shadows, reflections, and so on. This is not used frequently in games &#8212; some renders can take hours or days to complete (for a single frame!), depending on the resolution and the complexity of the scene.</p>
<p>There&#8217;s another difference between rasterization and ray-tracing that I think doesn&#8217;t get enough attention. Rasterization is stuck with a linear transformation projecting 3D scenes onto a plane, while ray-tracing could be used to project scenes onto any surface. If the camera in the scene was a complete sphere, the field of view (FOV) could range to 360 degrees, yielding the desired fisheye effect.</p>
<h2>Memory considerations</h2>
<p>While ray-tracing is an <a href="http://en.wikipedia.org/wiki/Embarrassingly_parallel">embarrasingly parallel</a> problem, a GPU implementation fast enough to render in real time has not been written yet (to my knowledge). As I understand it, the problem is that to parallelize it, each thread on the GPU has to access the same regions of memory to check what objects exist in a given volume. This can become a major bottleneck. Rasterization does not have this problem because the vertex shader simply computes a function of the vertex coordinates &#8212; it does not have to perform random access on shared memory.</p>
<p>In OpenCL, the memory model is a little different from what you find in typical sequential-programming memory models. There are four address spaces:</p>
<ul>
<li>Global, which all work-items (threads) have read and write access to all of. Random access performance is typically poor, especially when multiple work-items need access to the same bytes of global memory.</li>
<li>Constant, which all work-items have read-only access to all of. Random read performance on this is good, but you usually only have a very small amount of space (32-64kb on high-end graphics cards).</li>
<li>Local, which is shared between groups of work-items.</li>
<li>Private, which is not shared between work-items.</li>
</ul>
<p>To get good performance, I decided to shove the entire scene description into constant memory, which required a compact representation.</p>
<p>In fact, I went with a very density-poor format, a voxel grid, for the sake of simplifying the implementation. But by limiting the dimensions of the scene I could comfortably fit it within the 32kb limit.</p>
<h2>Ray-casting and lighting hack</h2>
<p>For the actual ray-tracing algorithm, I implemented Amanatides and Woo&#8217;s voxel traversal algorithm (<a href="http://www.cs.yorku.ca/~amana/research/grid.pdf">PDF</a>) to find the first objects that the rays from the camera hit. I didn&#8217;t implement secondary rays (shadow, lighting, reflection rays). Instead, I opted to treat the camera as a light source so that the same ray used to find an object could light it. This means surfaces angled away from the camera appear darker than the ones angled towards it. The effect is quite interesting.</p>
<h2>Conclusion and future improvements</h2>
<p>A lot could be improved, really. All the decisions I made were to simplify implementation. If I cared more about efficiency or features, things would have gone differently. Still, this was enough to get a feel for what 360-degree vision would be like at 200 FPS and 512&#215;512 resolution.</p>
<p>A sparse-voxel octree would more efficiently compact the scene description into constant memory, at the cost of greater cognitive overhead.</p>
<p><a href="http://strlen.com/gfxengine/fisheyequake/index.html">Fisheye quake</a> used multiple rasterized images, one for each face of a cube surrounding the camera, and stitched them together on the CPU. One particular improvement to fishpye would be to ditch the voxels and use a technique based on this. Perhaps the rasterized images could be stitched together on GPU by ray-tracing them. This would remove the 32kb limit and allow for much more complex scenes.</p>
<h2>Next time</h2>
<p>Shortly I will write a post about how <a href="https://www.youtube.com/watch?v=krL_vPRofAI">the portals I added to fishpye</a> work.</p>
]]></content:encoded>
			<wfw:commentRss>http://bytten.net/devlog/2012/01/16/360-degree-field-of-view/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

