<?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>Tiny Subversions &#187; Spelunky</title>
	<atom:link href="http://tinysubversions.com/category/games-i-love/spelunky/feed/" rel="self" type="application/rss+xml" />
	<link>http://tinysubversions.com</link>
	<description></description>
	<lastBuildDate>Tue, 24 Jan 2012 16:30:43 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Heresy</title>
		<link>http://tinysubversions.com/2010/11/heresy/</link>
		<comments>http://tinysubversions.com/2010/11/heresy/#comments</comments>
		<pubDate>Tue, 02 Nov 2010 17:04:17 +0000</pubDate>
		<dc:creator>Darius Kazemi</dc:creator>
				<category><![CDATA[design]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[Games I Love]]></category>
		<category><![CDATA[indie]]></category>
		<category><![CDATA[Spelunky]]></category>

		<guid isPermaLink="false">http://tinysubversions.com/?p=1712</guid>
		<description><![CDATA[Spelunky would make a great Facebook game. Stop laughing. I am serious. Well, I am half-serious. Think about it. Core gameplay happens in short chunks. Most Spelunky runs are maybe 1 to 5 minutes, and a full standard playthrough takes about 20 minutes. There are valuable items, and there&#8217;s a huge social motivation to tell [...]]]></description>
			<content:encoded><![CDATA[<p><a class="post_image_link"  href="http://tinysubversions.com/2010/11/heresy/"  title="Permanent link to Heresy" ><img class="post_image alignnone"  src="http://tinysubversions.com/wp-content/uploads/2010/11/wall2.png"  width="641"  height="109"  alt="Post image for Heresy" /></a>
</p><div id="attachment_1713"  class="wp-caption aligncenter"  style="width: 300px" >
	<a href="http://tinysubversions.com/wp-content/uploads/2010/11/main.png" ><img class="size-medium wp-image-1713"  title="Spelunky on Facebook"  src="http://tinysubversions.com/wp-content/uploads/2010/11/main-300x256.png"  alt="Spelunky on Facebook"  width="300"  height="256" /></a>
	<p class="wp-caption-text" >Spelunky on Facebook. Click to embiggen.</p>
</div>
<p><a href="http://www.spelunkyworld.com" >Spelunky</a> would make a great Facebook game.</p>
<p>Stop laughing. I am serious. Well, I am half-serious.</p>
<p>Think about it. Core gameplay happens in short chunks. Most Spelunky runs are maybe 1 to 5 minutes, and a full standard playthrough takes about 20 minutes. There are valuable items, and there&#8217;s a huge social motivation to tell your friends about your individual runs. Spelunky for Facebook could be based on the <a href="http://apps.facebook.com/bejeweledblitz/" >Bejeweled Blitz</a> model: a really fun game you play in short bursts and compete with your friends on a daily/weekly/monthly/all-time leaderboard.</p>
<h3>Core Gameplay</h3>
<p>Core gameplay of Spelunky would remain completely unchanged from classic Spelunky, but Facebook would provide a framework around the game to allow for competition, sharing of stories, and yes indeed, monetization.</p>
<h3>Monetization</h3>
<p>At first I was wondering how monetization would work, but I realized that it would be relatively easy.</p>
<p>Items in Spelunky are intrinsically valuable and qualitatively differentiated, far more so than in most Facebook games. For example, the difference between a pistol and a shotgun in a Mafia Wars clone is basically one of attack power. In Spelunky, the pistol and the shotgun do have different damage values but they also interact with the physical simulation in unique ways: bullet spread, recoil, and range come to mind. And I can&#8217;t even recall playing a Facebook game with items as varied as the jetpack, the pickaxe, and the rope.</p>
<p>If you&#8217;ve ever played Spelunky at any length, think about a situation where I tap you on the shoulder while you&#8217;re playing and offer you a shotgun on your next run for the low low price of a dime. You might actually pay me that dime.</p>
<p>The intrinsic value of items in Spelunky also makes them prime gift fodder. The fact that many items are skill-based could add another dimension to gift-giving. &#8220;Hey Jane, here&#8217;s a teleporter. I thought you could use some practice &#8212; they&#8217;re pretty useful once you figure out how they work! Some tips: _____&#8221;</p>
<p>If I were designing Spelunky for Facebook, I would only allow item purchases or gifts to be applied at the beginning of a run. I would also limit it to one item used at a time. (Maybe two?) One of the great things about items in Spelunky is that while starting with an item like the shotgun does give the  player a distinct advantage, having such an item does not by any means ensure the player will do better. While being able to buy a shotgun on demand would probably make the game trivial, simply making it so that a player will start with the shotgun doesn&#8217;t guarantee anything.</p>
<p>I would also add some kind of inventory system where you can accumulate items that you buy or are gifted, to deploy or regift as desired. I would probably allow players the option of putting an item away in their inventory when in-game acquisition occurs. For example, if you&#8217;re playing and you come across a cape, but you hate playing with the cape, you can store it in your inventory and give it away to a friend.</p>
<h3>Virality</h3>
<div id="attachment_1719"  class="wp-caption aligncenter"  style="width: 641px" >
	<a href="http://tinysubversions.com/wp-content/uploads/2010/11/wall1.png" ><img class="size-full wp-image-1719"  title="Spelunky Wall Post"  src="http://tinysubversions.com/wp-content/uploads/2010/11/wall1.png"  alt="Spelunky Wall Post"  width="641"  height="180" /></a>
	<p class="wp-caption-text" >Spelunky Wall Post</p>
</div>
<p>If you&#8217;ve been following me for more than a couple years you might recall that I once <a href="http://twitter.com/darius_spelunks" >hacked Spelunky to automatically post my in-game exploits to Twitter</a>. What excites me most about this whole silly idea is the prospect of doing something similar on Facebook. It would involve writing some rather tricky code to track not just events that occur, but the context in which they happened. Having worked on a primitive version of this system for <a href="http://tinysubversions.com/my-projects/spelunkytweet/" >SpelunkyTweet</a>, I can say that it&#8217;s not a trivial problem but also not capital-H Hard.</p>
<p>One issue that I have with Facebook games is that when they ask me to post about something that just happened on my wall, the event is trivial. Most of the time, I don&#8217;t give a crap. Oh yay, I reached level 21. Nobody cares. But if the game could synthesize a short, funny, <em>unique</em> narrative based on the success or failure of my problem-solving attempts and the context in which they occur&#8230; that would be awesome. I would post those all the time, because they&#8217;d be interesting to my friends.</p>
<p>Imagine a generated wall post like, &#8220;I can&#8217;t believe it. Nine levels deep into the cave, full health, I&#8217;m lucky enough to get a shotgun&#8230; and then I fall to my death. Butterfingers can be brutal.&#8221; I would be all over that. I would probably limit the moments that in-game wall post requests appear to moments when the player is not at any immediate risk. The post logic would be something like:</p>
<ul>
<li>If a notable thing happens
<ul>
<li>Generate a wall post</li>
<li>If within the next 60 seconds the player is not moving and no enemies are on the screen
<ul>
<li>Pop up the wall post request</li>
<li>Else, throw away the wall post</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>Wall post requests would always appear following player death. There would probably also be some way for the player to request a wall post manually.</p>
<h3>Leaderboard</h3>
<p>I&#8217;m not going to bother describing the leaderboard system in detail. I see it working along the lines of the one in <a href="http://apps.facebook.com/bejeweledblitz/" >Bejeweled Blitz</a>, which you can check out for yourself. You can compete against friends and worldwide for daily, weekly, monthly, and all-time best runs.</p>
<h3>Conclusion</h3>
<p>Someone needs to make this. Derek? Please?</p>
]]></content:encoded>
			<wfw:commentRss>http://tinysubversions.com/2010/11/heresy/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Tutorial: Adding a New Inventory Item to Spelunky</title>
		<link>http://tinysubversions.com/2010/01/tutorial-adding-new-inventory-spelunky/</link>
		<comments>http://tinysubversions.com/2010/01/tutorial-adding-new-inventory-spelunky/#comments</comments>
		<pubDate>Wed, 20 Jan 2010 18:58:28 +0000</pubDate>
		<dc:creator>Darius Kazemi</dc:creator>
				<category><![CDATA[modding]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[Spelunky]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://tinysubversions.com/?p=1423</guid>
		<description><![CDATA[Here&#8217;s another Spelunky modding tutorial I posted over on the Mossmouth Forums. This shows how you might add a third inventory element to the game, something that behaves like a bomb or a rope in terms of always having a limited number of it in your inventory. This can even be modified slightly to provide [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>Here&#8217;s another Spelunky modding tutorial I <a href="http://mossmouth.com/forums/index.php?topic=703.0" >posted over on the Mossmouth Forums</a>. This shows how you might add a third inventory element to the game, something that behaves like a bomb or a rope in terms of always having a limited number of it in your inventory. This can even be modified slightly to provide you with something like an ammo count.</p>
<h3>Overview</h3>
<p>So let&#8217;s say you want to add a new inventory item to Spelunky &#8212; something like bombs and ropes, but different. For the sake of this tutorial, let&#8217;s have you be able to hold up to 99 rocks in your pockets. We&#8217;ll make it so that rocks behave kind of like bombs: if you run across one, you can pick it up and it is added to your inventory when you switch away from it.</p>
<p>What we&#8217;re going to do in this mod is: set the appropriate global variable, figure out how to switch to the new inventory item, and set up the new HUD element so we know how many rocks we have.</p>
<h3>Setting the Global Variable</h3>
<p>The amount of bombs and ropes you have are stored as global variables. The game sets them in the scrClearGlobals. This script is run at the beginning of every game, and it sets every global to false/0, except for bombs, ropes, and plife (player life), which all get set to 4. So in scrClearGlobals you want to make the following change at line 109:</p>
<blockquote>
<pre>else
{
    global.plife = 4;
    global.bombs = 4;
    global.rope = 4;
    // ADD THIS LINE (we're starting the player out with 1 rock)
    global.rocks = 1;
}</pre>
</blockquote>
<h3>Switching to Our Rocks</h3>
<p>Here&#8217;s where we change the code so that pressing the &#8220;switch item&#8221; button will put a rock in our hands if we have more than 0 rocks. We also want to put in some code so that when we have the rock equipped, our global.rocks is reduced by 1 (so it works the same way bombs and ropes do).</p>
<p>Let&#8217;s look at the code from oPlayer1 Step, in the second Action Block, line 952:</p>
<blockquote><p><span style="font-family: Consolas, Monaco, 'Courier New', Courier, monospace; font-size: small;" >
<pre>else if (inGame and kItemPressed and not whipping)
{
    // switch items
    if (holdItem)
    {

// If we're holding a bomb and it's armed, we can't switch away.

        if (holdItem.sprite_index == sBombArmed)
        {
            // do nothing
        }

// If we're holding a bomb and it's not armed, then put it back in your
// inventory (increment the global), and then destroy it so you're not
// holding it anymore. Then, if there's more than 0 ropes, switch to
// ropes. Otherwise, switch to what you're holding (or nothing if
// you're not holding anything.)

        else if (holdItem.sprite_index == sBomb)
        {
            with holdItem
            {
                global.bombs += 1;
                instance_destroy();
            }

            if (global.rope &gt; 0)
            {
                holdItem = instance_create(x, y, oRopeThrow);
                holdItem.held = true;
                global.rope -= 1;
                whoaTimer = whoaTimerMax;
            }
            else
            {
                scrHoldItem(pickupItemType);
            }
        }

// If we're holding a rope then put it back in your inventory
// (increment the global), and then destroy it so you're not
// holding it anymore. Then switch to what you're holding
// (or nothing if you're not holding anything.)

        else if (holdItem.sprite_index == sRopeEnd)
        {
            with holdItem
            {
                global.rope += 1;
                instance_destroy();
            }            

            scrHoldItem(pickupItemType);
        }

// If we're holding an item that's not heavy (damsel or Idol)
// and we have a bomb or a rope, then store it away as
// pickupItemType for later. If we have bombs, switch
// to bombs, if not, then switch to ropes.

        else if (not holdItem.heavy and holdItem.cost == 0)
        {
            if (global.bombs &gt; 0 or global.rope &gt; 0)
            {
                pickupItemType = holdItem.type;
                if (holdItem.type == "Bow" and bowArmed)
                {
                    scrFireBow();
                }
                with holdItem
                {
                    breakPieces = false;
                    instance_destroy();
                }
            }

            if (global.bombs &gt; 0)
            {
                holdItem = instance_create(x, y, oBomb);
                if (global.hasStickyBombs) holdItem.sticky = true;
                holdItem.held = true;
                global.bombs -= 1;
                whoaTimer = whoaTimerMax;
            }
            else if (global.rope &gt; 0)
            {
                holdItem = instance_create(x, y, oRopeThrow);
                holdItem.held = true;
                global.rope -= 1;
                whoaTimer = whoaTimerMax;
            }
        }
    }
// If you're not holding anything, switch to bombs if available.
// Otherwise switch to ropes if available.
    else
    {
        if (global.bombs &gt; 0)
        {
            holdItem = instance_create(x, y, oBomb);
            if (global.hasStickyBombs) holdItem.sticky = true;
            holdItem.held = true;
            global.bombs -= 1;
            whoaTimer = whoaTimerMax;
        }
        else if (global.rope &gt; 0)
        {
            holdItem = instance_create(x, y, oRopeThrow);
            holdItem.held = true;
            global.rope -= 1;
            whoaTimer = whoaTimerMax;
        }
    }
}</pre>
</blockquote>
<p>It&#8217;s a little complex so you should read through my comments there. Basically, we take this structure and extend it so we have the logic for switching to rock. It&#8217;s a good exercise to read through this code and figure out why I made the changes I did:</p>
<blockquote><p><span style="font-family: Consolas, Monaco, 'Courier New', Courier, monospace; font-size: small;" ></p>
<pre>else if (inGame and kItemPressed and not whipping)
{
    // switch items
    if (holdItem)
    {
        if (holdItem.sprite_index == sBombArmed)
        {
            // do nothing
        }
        else if (holdItem.sprite_index == sBomb)
        {
            with holdItem
            {
                global.bombs += 1;
                instance_destroy();
            }

            if (global.rope &gt; 0)
            {
                holdItem = instance_create(x, y, oRopeThrow);
                holdItem.held = true;
                global.rope -= 1;
                whoaTimer = whoaTimerMax;
            }
            else
            {
                scrHoldItem(pickupItemType);
            }
        }
        else if (holdItem.sprite_index == sRopeEnd)
        {
            with holdItem
            {
                global.rope += 1;
                instance_destroy();
            }

            if (global.rocks &gt; 0)
            {
                holdItem = instance_create(x, y, oRock);
                holdItem.held = true;
                global.rocks -= 1;
                whoaTimer = whoaTimerMax;
            }

            else
            {
                scrHoldItem(pickupItemType);
            }
        }
        else if (holdItem.sprite_index == sRock)
        {

//           global.plife = 0;

            with holdItem
            {
                global.rocks += 1;
                instance_destroy();
            }

            if (pickupItemType == "Rock") pickupItemType = "";
            scrHoldItem(pickupItemType);
        }

        else if (not holdItem.heavy and holdItem.cost == 0)
        {
            if (global.bombs &gt; 0 or global.rope &gt; 0 or global.rocks &gt; 0)
            {
                pickupItemType = holdItem.type;
                if (holdItem.type == "Bow" and bowArmed)
                {
                    scrFireBow();
                }
                with holdItem
                {
                    breakPieces = false;
                    instance_destroy();
                }
            }

            if (global.bombs &gt; 0)
            {
                holdItem = instance_create(x, y, oBomb);
                if (global.hasStickyBombs) holdItem.sticky = true;
                holdItem.held = true;
                global.bombs -= 1;
                whoaTimer = whoaTimerMax;
            }
            else if (global.rope &gt; 0)
            {
                holdItem = instance_create(x, y, oRopeThrow);
                holdItem.held = true;
                global.rope -= 1;
                whoaTimer = whoaTimerMax;
            }
            else if (global.rocks &gt; 0)
            {
                holdItem = instance_create(x, y, oRock);
                holdItem.held = true;
                global.rocks -= 1;
                whoaTimer = whoaTimerMax;
            }
        }
    }
    else
    {
        if (global.bombs &gt; 0)
        {
            holdItem = instance_create(x, y, oBomb);
            if (global.hasStickyBombs) holdItem.sticky = true;
            holdItem.held = true;
            global.bombs -= 1;
            whoaTimer = whoaTimerMax;
        }
        else if (global.rope &gt; 0)
        {
            holdItem = instance_create(x, y, oRopeThrow);
            holdItem.held = true;
            global.rope -= 1;
            whoaTimer = whoaTimerMax;
        }
        else if (global.rocks &gt; 0)
        {
            holdItem = instance_create(x, y, oRock);
            holdItem.held = true;
            global.rocks -= 1;
            whoaTimer = whoaTimerMax;
        }
    }
}</pre>
<p></span>
</p></blockquote>
<h3>Adding Rocks to the UI</h3>
<p>Next we want to add a new UI element to the top of the screen that shows how many rocks we have. To do this, open up scrDrawHUD and you&#8217;ll see this:</p>
<blockquote><p><span style="font-family: Consolas, Monaco, 'Courier New', Courier, monospace; font-size: small;" ></p>
<pre>if (global.drawHUD and instance_exists(oPlayer1))
{
    lifeX = 8;
    bombX = 64;
    ropeX = 120;
    moneyX = 176;
    draw_set_font(global.myFont);
    draw_set_color(c_white);
    draw_sprite(sHeart, -1, lifeX, 8);
    life = global.plife;
    if (life &lt; 0) life = 0;
    draw_text(lifeX+16, 8, life);
    if (global.hasStickyBombs) draw_sprite(sStickyBombIcon, -1, bombX, 8);
    else draw_sprite(sBombIcon, -1, bombX, 8);
    draw_text(bombX+16, 8, global.bombs);
    draw_sprite(sRopeIcon, -1, ropeX, 8);
    draw_text(ropeX+16, 8, global.rope);
    draw_sprite(sDollarSign, -1, moneyX, 8);
    draw_text(moneyX+16, 8, global.money);</pre>
<p></span>
</p></blockquote>
<p>What you&#8217;ll want to do is create rockX, which is the X offset of the new rock UI element. I would put it in between rope and money, because money is variable length so you want it at the far right hand side. Then you just add the draw_text() and draw_sprite() functions. I used the sprite for the rock in the example below:</p>
<blockquote><p><span style="font-family: Consolas, Monaco, 'Courier New', Courier, monospace; font-size: small;" ></p>
<pre>if (global.drawHUD and instance_exists(oPlayer1))
{
    lifeX = 8;
    bombX = 64;
    ropeX = 120;
    rockX = 176;
    moneyX = 232;
    draw_set_font(global.myFont);
    draw_set_color(c_white);
    draw_sprite(sHeart, -1, lifeX, 8);
    life = global.plife;
    if (life &lt; 0) life = 0;
    draw_text(lifeX+16, 8, life);
    if (global.hasStickyBombs) draw_sprite(sStickyBombIcon, -1, bombX, 8);
    else draw_sprite(sBombIcon, -1, bombX, 8);
    draw_text(bombX+16, 8, global.bombs);
    draw_sprite(sRopeIcon, -1, ropeX, 8);
    draw_text(ropeX+16, 8, global.rope);
    // I messed around with the Y value until I  got something I liked
    draw_sprite(sRock, -1, rockX, 16);
    draw_text(rockX+16, 8, global.rocks);
    draw_sprite(sDollarSign, -1, moneyX, 8);
    draw_text(moneyX+16, 8, global.money);</pre>
<p></span>
</p></blockquote>
<p>And we end up with this:</p>
<p style="text-align: center;" ><img class="aligncenter"  src="http://tinysubversions.com/spelunky/s7.PNG"  alt="s7.PNG"  width="483"  height="376" /></p>
]]></content:encoded>
			<wfw:commentRss>http://tinysubversions.com/2010/01/tutorial-adding-new-inventory-spelunky/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My First Public Spelunky Mod: Spelunky B-Ball!</title>
		<link>http://tinysubversions.com/2010/01/my-first-public-spelunky-mod-spelunky-b-ball/</link>
		<comments>http://tinysubversions.com/2010/01/my-first-public-spelunky-mod-spelunky-b-ball/#comments</comments>
		<pubDate>Fri, 08 Jan 2010 17:30:26 +0000</pubDate>
		<dc:creator>Darius Kazemi</dc:creator>
				<category><![CDATA[mod]]></category>
		<category><![CDATA[modding]]></category>
		<category><![CDATA[Spelunky]]></category>

		<guid isPermaLink="false">http://tinysubversions.com/?p=1401</guid>
		<description><![CDATA[I just posted my first publicly released (very small) mod for Spelunky: Spelunky B-Ball. It adds a basketball object that is spawned from crates! (The basketball is Derek Yu&#8217;s creation, he just never put it in the final game.) You can see how I created the mod over at the Mossmouth forums.]]></description>
			<content:encoded><![CDATA[<p><a class="post_image_link"  href="http://tinysubversions.com/2010/01/my-first-public-spelunky-mod-spelunky-b-ball/"  title="Permanent link to My First Public Spelunky Mod: Spelunky B-Ball!" ><img class="post_image alignnone"  src="http://tinysubversions.com/spelunky/bball/spelunkybball.png"  width="276"  height="228"  alt="Post image for My First Public Spelunky Mod: Spelunky B-Ball!" /></a>
</p><p>I just posted my first publicly released (very small) mod for Spelunky: <a href="http://tinysubversions.com/spelunkybball/" >Spelunky B-Ball</a>. It adds a basketball object that is spawned from crates! (The basketball is Derek Yu&#8217;s creation, he just never put it in the final game.)</p>
<p>You can see how I created the mod <a href="http://mossmouth.com/forums/index.php?topic=629.0" >over at the Mossmouth forums</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://tinysubversions.com/2010/01/my-first-public-spelunky-mod-spelunky-b-ball/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Tutorial: Modding Spelunky&#8217;s Level Generator</title>
		<link>http://tinysubversions.com/2010/01/tutorial-modding-spelunkys-level-generator/</link>
		<comments>http://tinysubversions.com/2010/01/tutorial-modding-spelunkys-level-generator/#comments</comments>
		<pubDate>Fri, 08 Jan 2010 02:19:26 +0000</pubDate>
		<dc:creator>Darius Kazemi</dc:creator>
				<category><![CDATA[design]]></category>
		<category><![CDATA[hacking]]></category>
		<category><![CDATA[modding]]></category>
		<category><![CDATA[Spelunky]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://tinysubversions.com/?p=1377</guid>
		<description><![CDATA[So at the request of a member of the Spelunky forums, I wrote up a tutorial on modding Spelunky and posted it there. It&#8217;s based off a blog post I did back in September, but has a lot more detail about actually modifying it. It ended up taking me about an hour to write, and it [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>So at the request of a member of the Spelunky forums, I <a href="http://mossmouth.com/forums/index.php?topic=628.0" >wrote up a tutorial on modding Spelunky and posted it there</a>. It&#8217;s based off <a href="http://tinysubversions.com/2009/09/spelunkys-procedural-space/"  target="_blank" >a blog post I did back in September</a>, but has a lot more detail about actually modifying it. It ended up taking me about an hour to write, and it seems like the kind of thing I&#8217;d want to see indexed by search engines (which suck at indexing forums), so I&#8217;m putting it here for posterity.</p>
<h3>Overview</h3>
<p>This tutorial will teach you how to mod Spelunky so that its level generator creates a ridiculous number of spikes, mostly in places that make sense!</p>
<p>The high-level view of how Spelunky generates levels is that each level is divided into a 4×4 grid of 16 rooms. Each room consists of 80 tiles, 10 tiles wide and 8 tiles high. In the source code, rooms are structured as 80-character strings. Here’s an example:</p>
<p>“00000000110060000L040000000P110000000L110000000L11000000001100000000111112222111″</p>
<p>If we add line breaks every ten characters to create our 10&#215;8 room, we can begin to see the way rooms are laid out:</p>
<blockquote>
<pre>0000000011
0060000L04
0000000P11
0000000L11
0000000L11
0000000011
0000000011
1112222111</pre>
</blockquote>
<p>The game does some neat stuff in terms of figuring out how to create a path through the level and make sure there&#8217;s a way through every time, but I&#8217;m not going to discuss that in this post.</p>
<h3>How Basic Rooms Are Generated</h3>
<p>There are 4 basic room generation scripts, one for each area of the game.</p>
<ul>
<li>scrRoomGen: basic cave</li>
<li>scrRoomGen2: jungle</li>
<li>scrRoomGen3: yeti</li>
<li>scrRoomGen4: temple</li>
</ul>
<p>I&#8217;m going to focus on scrRoomGen, which generates rooms for the first four levels of the game.</p>
<p>A room layout generally contains walls, ladders, pushblocks, and obstacles. Let&#8217;s look at our first example:</p>
<blockquote>
<pre>0000000011
0000000L04
0000000P11
0000000L11
5000000L11
0000000011
0000000011
1112222111</pre>
</blockquote>
<p>&#8220;1&#8243; means wall/floor, &#8220;2&#8243; means there&#8217;s a 1 in 10 chance of a pushblock, otherwise it&#8217;s a brick, &#8220;L&#8221; means ladder, &#8220;P&#8221; means top platform of a ladder, &#8220;4&#8243; means a 1in 4 chance of a pushblock, otherwise it&#8217;s empty. &#8220;5&#8243; is special and I&#8217;ll explain it in a bit. This is an example of a room where there&#8217;s a solid floor of bricks and maybe pushblocks, there&#8217;s a wall to right with a ladder going up to the top, and there might be a pushblock at the top of the wall where it blocks you from getting to the other side. (Note: svenski posted <a href="http://mossmouth.com/forums/index.php?topic=516.msg11769#msg11769"  target="_blank" >a partial guide to these symbols</a> that might come in handy.)</p>
<h3>How Obstacles Get Added</h3>
<p>&#8220;5&#8243; is our special case here. It&#8217;s an obstacle. An obstacle is a 5&#215;3 block of tiles which gets overlaid onto the map wherever there&#8217;s a 5 (in this case). 5 is used to signify ground obstacles, like spikes, so this is the one we care about.</p>
<p>If we go to line 265 in the scrRoomGen script, we see this:</p>
<blockquote>
<pre>else if (tile == "5") // ground
 {
 switch(rand(1,16))
 {
 case 1: { strObs1 = "11111"; strObs2 = "00000"; strObs3 = "00000"; break; }
 case 2: { strObs1 = "00000"; strObs2 = "11110"; strObs3 = "00000"; break; }
 case 3: { strObs1 = "00000"; strObs2 = "01111"; strObs3 = "00000"; break; }
 case 4: { strObs1 = "00000"; strObs2 = "00000"; strObs3 = "11111"; break; }
 case 5: { strObs1 = "00000"; strObs2 = "20200"; strObs3 = "17177"; break; }
 case 6: { strObs1 = "00000"; strObs2 = "02020"; strObs3 = "71717"; break; }
 case 7: { strObs1 = "00000"; strObs2 = "00202"; strObs3 = "77171"; break; }
 case 8: { strObs1 = "00000"; strObs2 = "22200"; strObs3 = "11100"; break; }
 case 9: { strObs1 = "00000"; strObs2 = "02220"; strObs3 = "01110"; break; }
 case 10: { strObs1 = "00000"; strObs2 = "00222"; strObs3 = "00111"; break; }
 case 11: { strObs1 = "11100"; strObs2 = "22200"; strObs3 = "00000"; break; }
 case 12: { strObs1 = "01110"; strObs2 = "02220"; strObs3 = "00000"; break; }
 case 13: { strObs1 = "00111"; strObs2 = "00222"; strObs3 = "00000"; break; }
 case 14: { strObs1 = "00000"; strObs2 = "02220"; strObs3 = "21112"; break; }
 case 15: { strObs1 = "00000"; strObs2 = "20100"; strObs3 = "77117"; break; }
 case 16: { strObs1 = "00000"; strObs2 = "00102"; strObs3 = "71177"; break; }
 }
 }</pre>
</blockquote>
<p>What it does is this. After the game builds all the basic, and trap-free, rooms, it goes through every tile and checks if there&#8217;s an obstacle. (5, 6, and 8 count as obstacles for the first four levels of the game.) If it hits a 5, it runs the above code. It then picks one of the 16 possible 5&#215;3 obstacle setups at random. Let&#8217;s assume it picked number 6.</p>
<p>If we take case number 6 and &#8220;stack&#8221; the different strings with strObs1 on top and strObs3 on the bottom, we get this:</p>
<blockquote>
<pre>00000
02020
71717</pre>
</blockquote>
<p>What that means is this:</p>
<ul>
<li>The top row of tiles won&#8217;t modify the tiles they&#8217;re on top of. So if the 5 in our room had a 1 next to it, that 1 would stay a 1 (probably solid ground) no matter what.</li>
<li>The second row has two tiles in it that have a 1 in 2 chance of being a brick (with a small chance of being a pushblock)</li>
<li>The third row goes like this: spike-block-spike-block-spike (a 7 means spike)</li>
</ul>
<p>It&#8217;s not *exactly* that, though. Spelunky loves to pile randomization upon randomization. If we look down in the code a little bit, we see this:</p>
<blockquote>
<pre>else if (tile == "7" and rand(1,3) == 1) instance_create(xpos, ypos, oSpikes);</pre>
</blockquote>
<p>Turns out there&#8217;s only a 1 in 3 chance of a spike appearing whenever there&#8217;s a 7!</p>
<h3>Finally, Adding Some Spikes!</h3>
<p>So the first thing we can do is increase the chances of spikes appearing. Let&#8217;s go totally crazy and make it a 1 in 1 chance: that is, whenever there&#8217;s a 7, there&#8217;s a spike. What happens?</p>
<blockquote>
<pre>else if (tile == "7" and rand(1,1) == 1) instance_create(xpos, ypos, oSpikes);</pre>
</blockquote>
<p style="text-align: center;" ><img border="0"  class="aligncenter"  src="http://tinysubversions.com/spelunky/s3.PNG"  alt=""  width="482"  height="376" /></p>
<p>Hmm, it&#8217;s definitely spikier than usual but not what I would call ridiculously spikey. The reason for this is that if we look at the 16 different cases up above, only about half of them have any spikes at all! So even when a &#8220;7&#8243; means &#8220;definitely put a spike here,&#8221; it&#8217;s not going to help us when there are no 7&#8242;s at all! So let&#8217;s modify things a little!</p>
<p>We&#8217;ll add a crapload more 7&#8242;s to the strObs3 of each of the 16 cases. (The reason we only do it to strObs3 is that it&#8217;s the one that&#8217;s always going to be on the ground. Otherwise we end up with floating spikes.)</p>
<blockquote>
<pre>else if (tile == "5") // ground
 {
 switch(rand(1,16))
 {
 case 1: { strObs1 = "11111"; strObs2 = "00000"; strObs3 = "77707"; break; }
 case 2: { strObs1 = "00000"; strObs2 = "11110"; strObs3 = "07770"; break; }
 case 3: { strObs1 = "00000"; strObs2 = "01111"; strObs3 = "70707"; break; }
 case 4: { strObs1 = "00000"; strObs2 = "00000"; strObs3 = "11111"; break; }
 case 5: { strObs1 = "00000"; strObs2 = "20200"; strObs3 = "17177"; break; }
 case 6: { strObs1 = "00000"; strObs2 = "02020"; strObs3 = "71717"; break; }
 case 7: { strObs1 = "00000"; strObs2 = "00202"; strObs3 = "77171"; break; }
 case 8: { strObs1 = "00000"; strObs2 = "22200"; strObs3 = "11177"; break; }
 case 9: { strObs1 = "00000"; strObs2 = "02220"; strObs3 = "71110"; break; }
 case 10: { strObs1 = "00000"; strObs2 = "00222"; strObs3 = "77111"; break; }
 case 11: { strObs1 = "11100"; strObs2 = "22200"; strObs3 = "77007"; break; }
 case 12: { strObs1 = "01110"; strObs2 = "02220"; strObs3 = "70077"; break; }
 case 13: { strObs1 = "00111"; strObs2 = "00222"; strObs3 = "77777"; break; }
 case 14: { strObs1 = "00000"; strObs2 = "02220"; strObs3 = "21112"; break; }
 case 15: { strObs1 = "00000"; strObs2 = "20100"; strObs3 = "77117"; break; }
 case 16: { strObs1 = "00000"; strObs2 = "00102"; strObs3 = "71177"; break; }
 }
 }</pre>
</blockquote>
<p style="text-align: center;" ><img class="aligncenter"  src="http://tinysubversions.com/spelunky/s4.PNG"  alt=""  width="483"  height="376" /></p>
<p>Hmm, pretty good but still not quite there. The reason we&#8217;re STILL not seeing a lot of spikes is because it only goes through those 16 cases if it runs happens to run into a 5 tile! For example, the room you see in the above picture, in the center-left, just didn&#8217;t have a 5 tile so there are no spikes.</p>
<h3>The Hard Part</h3>
<p>This is where the modding gets hard. You&#8217;re going to need to go through each one of the 80-character room strings (there are about 30 of them) and break them into their 8&#215;10 blocks, figure out where you want to put an extra 5 tile, and then put them back together. For example, let&#8217;s go with this one:</p>
<p>&#8220;60000600000000000000000600000000000000000000000000000222220000111111001111111111&#8243;</p>
<p>We break it out into 8 rows of 10:</p>
<blockquote>
<pre>6000060000
0000000000
0006000000
0000000000
0000000000
0002222200
0011111100
1111111111</pre>
</blockquote>
<p>Hey, it looks like a pretty empty room. Let&#8217;s add a 5. Since the 5 is a 5&#215;3 block of tiles, 3 blocks tall, we need to put the 5 somewhere in the fourth row from the bottom. Otherwise our spike tiles will be floating in air, or worse!</p>
<blockquote>
<pre>6000060000
0000000000
0006000000
0000000000
5000050000
0002222200
0011111100
1111111111</pre>
</blockquote>
<p>Which then becomes this:</p>
<p>&#8220;60000600000000000000000600000000000000005000050000000222220000111111001111111111&#8243;</p>
<p>I added two 5&#8242;s to the room. Combined with my super spikey obstacle set, this is probably going to have a lot of spikes in it!</p>
<p>I don&#8217;t have the time to go through and artfully place all these obstacles (this is where the art of level design comes in handy!), but as a quick hack I just added a crapton of 5&#8242;s in places that I was pretty sure ahead of time would *probably* be safe.</p>
<p style="text-align: center;" ><img border="0"  class="aligncenter"  src="http://tinysubversions.com/spelunky/s5.PNG"  alt=""  width="483"  height="376" /></p>
<p>Now that&#8217;s what I call spikey! You can see from the screenshot that there are a few places where spikes are randomly hanging in mid-air. That&#8217;s why you need to do what I showed above, and for every room, painstakingly take it apart and replace the obstacle tiles <strong>where appropriate</strong> and stitch them back together. This is really hard, and this is one of the many reasons why Derek is a game design genius!</p>
<p>Anyway, if you want the source code that generated my super-spikey cave, you can find it <a href="http://tinysubversions.com/spelunky/scrRoomGen.txt"  target="_blank" >here</a>. Just replace scrRoomGen in the Spelunky source code with that script and you&#8217;ll be in spike city. (Be sure to back up your old script first!)</p>
]]></content:encoded>
			<wfw:commentRss>http://tinysubversions.com/2010/01/tutorial-modding-spelunkys-level-generator/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>How to Squander Your 15 Minutes By Repeatedly Shooting Yourself In Both Feet: An Instruction Manual</title>
		<link>http://tinysubversions.com/2009/12/how-to-squander-your-15-minutes-by-repeatedly-shooting-yourself-in-both-feet-an-instruction-manual/</link>
		<comments>http://tinysubversions.com/2009/12/how-to-squander-your-15-minutes-by-repeatedly-shooting-yourself-in-both-feet-an-instruction-manual/#comments</comments>
		<pubDate>Tue, 15 Dec 2009 22:54:49 +0000</pubDate>
		<dc:creator>Darius Kazemi</dc:creator>
				<category><![CDATA[indie]]></category>
		<category><![CDATA[marketing]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[networking tips]]></category>
		<category><![CDATA[Spelunky]]></category>

		<guid isPermaLink="false">http://tinysubversions.com/?p=1327</guid>
		<description><![CDATA[Gamasutra recently published a good interview with Derek Yu, the creator of Spelunky. But wait! This is not another blog post where I&#8217;m talking about how Spelunky is the best game ever. I wanted to draw your attention instead to the comment thread for the post. (Update Aug 19, 2011: looks like Adam Coate&#8217;s profile [...]]]></description>
			<content:encoded><![CDATA[<p></p><p><span class="drop_cap" >G</span>amasutra recently published <a href="http://web.archive.org/web/20100712225107/http://www.gamasutra.com/view/feature/4213/pondering_indie_spirit_derek_yu_.php" >a good interview with Derek Yu</a>, the creator of <em>Spelunky.</em> But wait! This is not another blog post where I&#8217;m talking about how Spelunky is the best game ever. I wanted to draw your attention instead to <a href="http://web.archive.org/web/20100712225107/http://www.gamasutra.com/view/feature/4213/pondering_indie_spirit_derek_yu_.php#comments" >the comment thread for the post</a>. <em>(Update Aug 19, 2011: looks like Adam Coate&#8217;s profile has been removed from Gamasutra, which nukes all his comments. 1) <a href="http://web.archive.org/web/20100712225107/http://www.gamasutra.com/view/feature/4213/pondering_indie_spirit_derek_yu_.php" >here is an archive of the original thread</a> so you can read the whole thing. 2) Gamasutra, you should change your policy so that comments are preserved on threads when accounts are removed/deleted. 3) I have replaced every link in this article with a link to the archive, so individual comment references should hold.)</em></p>
<p>There was a fair amount of discussion about the thread on Twitter recently. It is a prime example of how to be an ungracious person and a how to <a href="http://tinysubversions.com/2006/05/effective-networking-dont-badmouth-people/" >badmouth people</a> and<a href="http://tinysubversions.com/2009/04/effective-networking-dont-be-this-guy/" > be that guy</a>. He&#8217;s an indie developer with serious entitlement issues. You should definitely read the whole thread, as it is equal parts entertaining and irritating, but I&#8217;ve included the gist of it here with some commentary of my own.</p>
<p>This guy Adam Coate posted <a href="http://web.archive.org/web/20100712225107/http://www.gamasutra.com/view/feature/4213/pondering_indie_spirit_derek_yu_.php#comment37427" >the following comment</a>:</p>
<blockquote><p>[Being a suffering artist is the s]tory of my life right there. And once the game&#8217;s done, even more suffering comes from the lack of exposure certain gaming-related websites are willing to give us unknowns, yet are perfectly willing to run full-blown features on Boulder Dash clones, just because they&#8217;ve already been featured on TIGSource. Feel free to take a bit of a risk by giving some press to a game that actually deserves it, Gamasutra (oh, I don&#8217;t know, Flytrap, maybe?).</p></blockquote>
<p>So he criticized the proprietors of the website he&#8217;s posting on (which is okay if a little dickish) and insulted the developer being interviewed in the article he&#8217;s commenting on (totally not okay). Kris Graft, who works for Gamasutra, <a href="http://web.archive.org/web/20100712225107/http://www.gamasutra.com/view/feature/4213/pondering_indie_spirit_derek_yu_.php#comment37448" >responded by asking</a>:</p>
<blockquote><p>Maybe people would consider talking to you about your game if you had a better attitude? Or emailed editors of certain gaming-related websites for consideration, maybe? Don&#8217;t make yourself suffer more than you have to.</p></blockquote>
<p>Adam went on to complain that he tried emailing the editors and didn&#8217;t get a response. Fair enough. There some more back-and-forth, mostly people trying to tell him that Spelunky actually isn&#8217;t a piece of crap, and then <a href="http://web.archive.org/web/20100712225107/http://www.gamasutra.com/view/feature/4213/pondering_indie_spirit_derek_yu_.php#comment37462" >Michael Rose of Indiegames.com chimes in</a>:</p>
<blockquote><p>[J]ust thought I should throw a few words in here. I&#8217;m one of the editors at Indiegames.com, and I received your email about Flytrap about a month ago. The email contained a few paragraphs about the game, and 3 screenshots.</p>
<p>After reading what you sent me, I then went to check out the game more. Your email didn&#8217;t supply a website, so I went hunting for one, and came up with nothing. You hadn&#8217;t even supplied a link to the Xbox Live Marketplace page for your game, which was a little odd given this is what you were trying to sell to me. After Googling it and finding the page, I was presented with a &#8216;Content not found&#8217; page on the Xbox.com site. Not a great start.</p>
<p>I then decided to hunt on Youtube for a video of your game, and yet again came up with nothing. Honestly, you are here complaining that no-one is giving coverage to your game, and yet the real problem is that you need to have a quick and very easy lesson in marketing. How is anyone meant to get excited about your game when all you give them is 3 measly screenshots which all look the same?</p>
<p>Unfortunately your view of gaming sites which cover indie titles has been skewed due to your feeling of rejection. This is completely understandable, but coming on here and spouting off about how your game hasn&#8217;t received the &#8216;deserved recognition&#8217; it needs is pretty childish. Maybe you should instead be trying to work out WHY your game hasn&#8217;t taken off how you would have liked. As I said before, marketing your game properly would be a very good start.</p></blockquote>
<p>Seems like case closed, right? Wrong. Adam posts a <a href="http://www.gamasutra.com/blogs/AdamCoate/2270/" >gracious thank-you to Michael</a>, and Michael points out <a href="http://www.devmag.org.za/articles/78-ZERO-BUDGET-INDIE-MARKETING-GUIDE/" >Rodain Joubert&#8217;s excellent indie game marketing guide</a>.</p>
<blockquote class="left" ><p>&#8220;Miyamoto never had to work for press like this.&#8221;</p></blockquote>
<p>Meanwhile, he&#8217;s been having a side argument with Brandon Sheffield, editor of Game Developer Magazine and writer for Gamasutra. Basically, Brandon <a href="http://www.gamasutra.com/blogs/BrandonSheffield/171/" >chastised Adam for his poor attitude</a>. <a href="http://www.gamasutra.com/blogs/AdamCoate/2270/" >Adam&#8217;s response</a> was &#8220;Well, it got your attention didn&#8217;t it?&#8221; Brandon responded saying that yes, it got his attention but now he has a negative view of Adam and his game. <a href="http://web.archive.org/web/20100712225107/http://www.gamasutra.com/view/feature/4213/pondering_indie_spirit_derek_yu_.php#comment37470" >Adam&#8217;s response</a> is simultaneously heartbreaking and legendarily self-delusional:</p>
<blockquote><p>I apologize for my negative first impression, but after having spent a year of my life struggling to survive while I create a game that even my girlfriend didn&#8217;t believe in (which changed once she saw how blind playtesters reacted to it), it&#8217;s a little disheartening to just be completely ignored by the world. <a href="http://justonemoregame.wordpress.com/2009/12/16/miyamoto-never-had-to-work-for-press-like-this/" >Miyamoto never had to work for press like this</a>.</p></blockquote>
<p>Really? He didn&#8217;t? As later commenters point out, Miyamoto worked on many many titles before he received any kind of personal recognition from the wider gaming audience. Furthermore, Miyamoto worked and has always worked for a large game company with an entire marketing division. So while he personally didn&#8217;t do much marketing for <em>Super Mario Bros.</em>, he had probably dozens of people doing it instead.</p>
<p>Later on in the thread, Adam <a href="http://web.archive.org/web/20100712225107/http://www.gamasutra.com/view/feature/4213/pondering_indie_spirit_derek_yu_.php#comment37486" >takes back his remarks about </a><em><a href="http://web.archive.org/web/20100712225107/http://www.gamasutra.com/view/feature/4213/pondering_indie_spirit_derek_yu_.php#comment37486" >Spelunky</a></em> and <a href="http://web.archive.org/web/20100712225107/http://www.gamasutra.com/view/feature/4213/pondering_indie_spirit_derek_yu_.php#comment37490" >admits that the Miyamoto comment was hilariously uninformed</a>.</p>
<p>Best of all, as a result of the thread, Michael Rose was prompted to write up <a href="http://www.gamasutra.com/blogs/MichaelRose/20091212/3798/The_Idiots_Guide_to_Marketing_Your_Indie_Game.php" >The Idiot&#8217;s Guide to Marketing Your Indie Game</a>. It&#8217;s full of very specific advice on how to contact game journalists about your game and what sort of email you should be writing them. It reminds me a lot of <a href="http://tinysubversions.com/2009/04/writing-a-resume-for-a-game-company/" >writing a resume for a game development job</a>: you need to stand out but also tailor it to your specific audience.</p>
<p>There&#8217;s a whole bunch more to the comments section. At one point <a href="http://web.archive.org/web/20100712225107/http://www.gamasutra.com/view/feature/4213/pondering_indie_spirit_derek_yu_.php#comment37611" >Adam decides to break out some armchair evolutionary psychology</a>, explaining that women love to shop and eat and consume while men like to destroy and <em>it&#8217;s just a fact people come on don&#8217;t you get it</em>. But that&#8217;s really more of a hilarious digression.</p>
<p>And finally, the title of this blog post comes from one of <a href="http://www.brandonnn.com/" >Brandon Boyer</a>&#8216;s two beautifully acerbic comments (<a href="http://web.archive.org/web/20100712225107/http://www.gamasutra.com/view/feature/4213/pondering_indie_spirit_derek_yu_.php#comment37738" >1</a>) (<a href="http://web.archive.org/web/20100712225107/http://www.gamasutra.com/view/feature/4213/pondering_indie_spirit_derek_yu_.php#comment37897" >2</a>) on the thread.</p>
]]></content:encoded>
			<wfw:commentRss>http://tinysubversions.com/2009/12/how-to-squander-your-15-minutes-by-repeatedly-shooting-yourself-in-both-feet-an-instruction-manual/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>Messing With Spelunky</title>
		<link>http://tinysubversions.com/2009/10/messing-with-spelunky/</link>
		<comments>http://tinysubversions.com/2009/10/messing-with-spelunky/#comments</comments>
		<pubDate>Sun, 18 Oct 2009 20:20:00 +0000</pubDate>
		<dc:creator>Darius Kazemi</dc:creator>
				<category><![CDATA[modding]]></category>
		<category><![CDATA[Spelunky]]></category>

		<guid isPermaLink="false">http://tinysubversions.com/?p=1177</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p></p><p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"  href="http://1.bp.blogspot.com/_WQk0YgqQA9Q/Stt4l5U8-YI/AAAAAAAAASg/cyZs7dO3QJs/s1600-h/scarabs.png" ><img border="0"  style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 293px;"  src="http://1.bp.blogspot.com/_WQk0YgqQA9Q/Stt4l5U8-YI/AAAAAAAAASg/cyZs7dO3QJs/s400/scarabs.png"  alt=""  id="BLOGGER_PHOTO_ID_5394037571145496962" /></a>
<div></div>
<div></div>
<p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"  href="http://1.bp.blogspot.com/_WQk0YgqQA9Q/Stt4gx1UESI/AAAAAAAAASY/xJ0F0ryNYCk/s1600-h/giantSpiders.png" ><img border="0"  style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 305px;"  src="http://1.bp.blogspot.com/_WQk0YgqQA9Q/Stt4gx1UESI/AAAAAAAAASY/xJ0F0ryNYCk/s400/giantSpiders.png"  alt=""  id="BLOGGER_PHOTO_ID_5394037483234398498" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://tinysubversions.com/2009/10/messing-with-spelunky/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Spelunky&#8217;s Procedural Space</title>
		<link>http://tinysubversions.com/2009/09/spelunkys-procedural-space/</link>
		<comments>http://tinysubversions.com/2009/09/spelunkys-procedural-space/#comments</comments>
		<pubDate>Tue, 29 Sep 2009 17:07:00 +0000</pubDate>
		<dc:creator>Darius Kazemi</dc:creator>
				<category><![CDATA[BoRT]]></category>
		<category><![CDATA[Spelunky]]></category>

		<guid isPermaLink="false">http://tinysubversions.com/?p=1174</guid>
		<description><![CDATA[NOTE: For a way more technical article about Spelunky, see my newer tutorial, Modding Spelunky&#8217;s Level Generator. The following is my first entry into Corvus Elrod&#8217;s Blogs of the Round Table. I&#8217;ve been meaning to participate in BoRT forever, and I&#8217;m pleased to finally get around to it. To make things interesting for myself, I [...]]]></description>
			<content:encoded><![CDATA[<p></p><p><strong>NOTE: </strong>For a <strong>way</strong> more technical article about Spelunky, see my newer tutorial, <a href="http://tinysubversions.com/2010/01/tutorial-modding-spelunkys-level-generator/" >Modding Spelunky&#8217;s Level Generator</a>.</p>
<p><em>The following is my first entry into Corvus Elrod&#8217;s Blogs of the Round Table. I&#8217;ve been meaning to participate in BoRT forever, and I&#8217;m pleased to finally get around to it. To make things interesting for myself, I decided at PAX that I would participate in every BoRT for the next year, and that I would write every single BoRT entry about </em>Spelunky<em>. Because I am that much of a fanboy.</em><br/>
<em><br/>
</em> <em>This may backfire.</em><br/>
<em><br/>
</em> <em><a href="http://corvus.zakelro.com/round-table/#0909" >This months&#8217; theme</a> &#8220;invites you to explore the ways games have represented the spatial nature of their storyworlds and what this does for the audience experience.&#8221;</em></p>
<h3>Room Generation</h3>
<p><em>Spelunky </em>takes place in a series of two-dimensional platform levels. Each level is divided into a 4&#215;4 grid of 16 rooms. Each room consists of 80 tiles, 10 tiles wide and 8 tiles high. In the source code, rooms are structured as 80-character strings. Here&#8217;s an example:</p>
<p>&#8220;00000000110060000L040000000P110000000L110000000L11000000001100000000111112222111&#8243;</p>
<p>If we add line breaks every ten characters, we can begin to see the way rooms are laid out:<br/>
<span style="font-family: 'courier new';" >0000000011</span><br/>
<span style="font-family: 'courier new';" >0060000L04</span><br/>
<span style="font-family: 'courier new';" >0000000P11</span><br/>
<span style="font-family: 'courier new';" >0000000L11</span><br/>
<span style="font-family: 'courier new';" >0000000L11</span><br/>
<span style="font-family: 'courier new';" >0000000011</span><br/>
<span style="font-family: 'courier new';" >0000000011</span><br/>
<span style="font-family: 'courier new';" >1112222111</span><br/>
<span style="font-family: 'courier new';" ><br/>
</span> &#8220;L&#8221; signifies a ladder. &#8220;P&#8221; signifies the ledge near the top of a ladder.  1&#8242;s and 2&#8242;s signify varying chances that a basic brick tile or a block tile will appear. That 6 floating in midair is essentially a trigger that says, &#8220;Put a series of random tiles here. Or perhaps nothing.&#8221; (It&#8217;s funny, if you look at the 10&#215;8 block of characters and squint your eyes, the game starts to look like <em>Rogue</em>, its most illustrious predecessor.)<span style="font-family: georgia;" ><br/>
</span></p>
<blockquote class="right" ><p>There are only about 50 basic room layouts for every tile set in the game.</p></blockquote>
<p>The experienced <em>Spelunky </em>player begins to notice and anticipate these blocks. Although there may be a slightly different layout each time thanks to the 6, I look at that block and I say, &#8220;Oh yes, that&#8217;s the ladder next to a vertical wall with a pushblock at the top of the ladder. I often see that on the ground floor of a level in the game&#8217;s first tile set.&#8221; My muscle memory is ready to traverse this room in about two seconds flat. Any given <em>Spelunky</em> level consists of 16 of these rooms. There are only about 50 basic room layouts for every tile set in the game. After 500 playthroughs, it is possible for a player to recall each one.</p>
<h3>Obstacle Generation</h3>
<p>But space in <em>Spelunky </em>is more than just a layout of ladders, walls, and blocks. Space is rudely interrupted with traps and monsters. Whereas the physical layout of each room is something like 80% hand crafted and 20% randomly generated, the layout of traps and monsters is 100% procedural, based on rules like:</p>
<blockquote><p>If we are in the first cave tileset, then for every brick tile that is not the ceiling of the level itself, and is not in a shop, and is not in the starting room, and is not on the bottom half of a room, check to see if we have a two by two block of empty tile spaces below this brick. If there is a two by two block of empty tile spaces, and we&#8217;re allowed to generate a Giant Spider in this level, and we have yet to generate a Giant Spider in this level, then there is a 1 in 40 chance that we generate a Giant Spider and some cobwebs right beneath this brick. If we do generate a Giant Spider, make sure not to generate another one in this level.</p></blockquote>
<p>The above works out to about 30 lines of code, simplified somewhat. The code for monster and trap placement is so thoroughly procedural and random that unlike the case of room layouts, no <em>Spelunky </em>player, no matter how experienced, can begin to anticipate the placement of these obstacles.</p>
<h3>Spelunky is a Series of Interesting Obstacles</h3>
<p>When we speak of <em>Spelunky </em>as a procedurally generated platformer with high replayability, we are speaking of the obstacle generation code far more than we are speaking of the room generation code. Yet when we look at the (excellent, brilliant, fascinating) <a href="http://forums.tigsource.com/index.php?topic=5174.0" ><span><span>TIGSource procedural generation thread</span></span></a>, the focus is on the generation of rooms and terrain. For the first time, I&#8217;m starting to think that they&#8217;re barking up the wrong tree. The space that they should be focused on generating is the space of obstacles, the topology of which is tied inextricably to the mechanics of the obstacles themselves.</p>
<p style="text-align: center;" >Please visit the Blogs of the Round Table&#8217;s <a title="Blogs of the Round Table"  href="http://corvus.zakelro.com/round-table/" >main hall</a> for links to all entries.</p>
]]></content:encoded>
			<wfw:commentRss>http://tinysubversions.com/2009/09/spelunkys-procedural-space/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Spelunky 1.0</title>
		<link>http://tinysubversions.com/2009/09/spelunky-1-0/</link>
		<comments>http://tinysubversions.com/2009/09/spelunky-1-0/#comments</comments>
		<pubDate>Wed, 02 Sep 2009 17:17:00 +0000</pubDate>
		<dc:creator>Darius Kazemi</dc:creator>
				<category><![CDATA[best game ever]]></category>
		<category><![CDATA[Spelunky]]></category>
		<category><![CDATA[xbla]]></category>

		<guid isPermaLink="false">http://tinysubversions.com/?p=1172</guid>
		<description><![CDATA[Since its original beta release in late December 2008, Spelunky has quickly become one of my favorite games of all time. Probably #2, right behind Jagged Alliance 2. Anyway, if you haven&#8217;t played Spelunky now is the best time yet to pick it up. As of last night, the game officially hit its 1.0 release, [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>Since its original beta release in late December 2008, <i>Spelunky </i>has quickly become one of my favorite games of all time. Probably #2, right behind <i>Jagged Alliance 2</i>. Anyway, if you haven&#8217;t played <i>Spelunky</i> now is the best time yet to pick it up. As of last night, the game officially hit its 1.0 release, along with the exciting announcement that there will be an XBLA version in 2010! So <a href="http://www.spelunkyworld.com/" >go grab the new version</a>.
<div></div>
<div>The PC version will remain free, and will be open-sourced in late 2009, at which point I will resurrect <a href="http://tinysubversions.blogspot.com/2009/06/game-maker-and-twitter-united-in.html" >SpelunkyTweet</a>!</div>
]]></content:encoded>
			<wfw:commentRss>http://tinysubversions.com/2009/09/spelunky-1-0/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Article on Spelunky in The Escapist</title>
		<link>http://tinysubversions.com/2009/07/article-on-spelunky-in-the-escapist/</link>
		<comments>http://tinysubversions.com/2009/07/article-on-spelunky-in-the-escapist/#comments</comments>
		<pubDate>Tue, 07 Jul 2009 15:31:00 +0000</pubDate>
		<dc:creator>Darius Kazemi</dc:creator>
				<category><![CDATA[best game ever]]></category>
		<category><![CDATA[Spelunky]]></category>

		<guid isPermaLink="false">http://tinysubversions.com/?p=1166</guid>
		<description><![CDATA[Anthony Burch wrote an article for this week&#8217;s The Escapist articulating why Spelunky is so great: By mixing the randomly generated levels native to roguelikes with a familiar 2-D perspective and intuitive, decidedly un-roguelike game mechanics, Spelunky becomes something completely new: a perpetually fresh, challenging experience that is as accessible as it is complex. Since [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>Anthony Burch wrote an article for this week&#8217;s The Escapist <a href="http://www.escapistmagazine.com/articles/view/issues/issue_209/6235-Infinite-Caves-Infinite-Stories" >articulating why <i>Spelunky</i> is so great</a>:<br/>
<blockquote>By mixing the randomly generated levels native to roguelikes with a familiar 2-D perspective and intuitive, decidedly un-roguelike game mechanics, Spelunky becomes something completely new: a perpetually fresh, challenging experience that is as accessible as it is complex. Since you navigate the environment via platforming, Spelunky&#8217;s procedurally generated maps actually impact your overall strategy more than almost any other game to use similar randomization. While you can easily conquer every randomized dungeon in a game like Diablo II through brute force and determination, Spelunky forces you to constantly make meaningful decisions in order to progress. Do you risk making a blind leap down a chasm, hoping that water rather than spikes await you at the bottom? Do you save your bombs for bosses, or do you use them to blow holes in the level topography and create a more direct route to the level exit? These are not binary, one-off decisions that exist independently from the gameplay &#8211; the entire process of playing Spelunky requires you to make new and interesting choices like these, over and over again.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://tinysubversions.com/2009/07/article-on-spelunky-in-the-escapist/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Games of My Life</title>
		<link>http://tinysubversions.com/2009/06/games-of-my-life/</link>
		<comments>http://tinysubversions.com/2009/06/games-of-my-life/#comments</comments>
		<pubDate>Sat, 27 Jun 2009 20:34:00 +0000</pubDate>
		<dc:creator>Darius Kazemi</dc:creator>
				<category><![CDATA[alpha centauri]]></category>
		<category><![CDATA[Amplitude]]></category>
		<category><![CDATA[best game ever]]></category>
		<category><![CDATA[Deus Ex]]></category>
		<category><![CDATA[fallout]]></category>
		<category><![CDATA[gta]]></category>
		<category><![CDATA[Jagged Alliance 2]]></category>
		<category><![CDATA[scorched earth]]></category>
		<category><![CDATA[Spelunky]]></category>

		<guid isPermaLink="false">http://tinysubversions.com/?p=1165</guid>
		<description><![CDATA[I&#8217;ve decided to copy Shane Liesegang and do a list of the 10 &#8220;most impactful&#8221; games, and try to find some trends in the games that I pick. Unordered 10 Impactful Games Jagged Alliance 2 Amplitude Deus Ex Spelunky Super Mario Bros 3 Fallout Maniac Mansion 2: Day of the Tentacle Grand Theft Auto 3 [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>I&#8217;ve decided to <a href="http://blog.shaneliesegang.com/2009/06/games-of-my-life/" >copy Shane Liesegang</a> and do a list of the 10 &#8220;most impactful&#8221; games, and try to find some trends in the games that I pick.
<div>
<h2>Unordered 10 Impactful Games</h2>
<ul>
<li><i><a href="http://tinysubversions.blogspot.com/search/label/jagged%20alliance" >Jagged Alliance 2</a></i></li>
<li><i><a href="http://tinysubversions.blogspot.com/search/label/amplitude" >Amplitude</a></i></li>
<li><i><a href="http://tinysubversions.blogspot.com/search/label/deus%20ex" >Deus Ex</a></i></li>
<li><i><a href="http://tinysubversions.blogspot.com/search/label/spelunky" >Spelunky</a></i></li>
<li><i>Super Mario Bros 3</i></li>
<li><i>Fallout</i></li>
<li><i>Maniac Mansion 2: Day of the Tentacle</i></li>
<li><i>Grand Theft Auto 3</i></li>
<li><i>Alpha Centauri</i></li>
<li><i>Scorched Earth</i></li>
</ul>
<div>I chose the games for this list by thinking of games that are personally &#8220;impactful&#8221; to me. They either changed the way I think about games, or changed the way I think about the world. Like Shane, I&#8217;m interested in finding any trends between these games, so I&#8217;m subjecting them to a set of metrics that might possibly be completely meaningless.</div>
<div></div>
<div>Note that I&#8217;m limiting it to video games here, otherwise I&#8217;d have backgammon on the list. But comparing video games to board games or to folk games is in many ways an apples-to-oranges thing, especially considering the comparisons that I want to use to examine them.</div>
<div></div>
<div>
<h2>Chronological Order</h2>
<ul>
<li>1988: <i>Super Mario Bros 3</i></li>
<li>1991: <i>Scorched Earth</i></li>
<li>1993: <i>Maniac Mansion: Day of the Tentacle</i></li>
<li>1997: <i>Fallout</i></li>
<li>1998: <i>Alpha Centauri</i></li>
<li>1999: <i>Jagged Alliance 2</i></li>
<li>2000: <i>Deus Ex</i></li>
<li>2001: <i>Grand Theft Auto 3</i></li>
<li>2003: <i>Amplitude</i></li>
<li>2009: <i>Spelunky</i></li>
</ul>
<div>It&#8217;s not surprising that while the list spans 21 years, half of the games I chose were made between 1997 and 2001. For me, those are the golden years of gaming. I&#8217;m also not surprised that there&#8217;s a big gap between 2003 and 2009. While there haven&#8217;t been a whole lot of AAA titles that affect me the way titles from the late &#8217;90s did, I even struggled to think of an indie game that really truly affected me in the way that <i>Fallout</i> or <i>JA2</i> did. <i>Spelunky</i> is the obvious exception, but while there have been many fantastic indie titles that I think about all the time, I think they&#8217;re often just too small in scope to really affect me the same way that the other games did.</div>
<div></div>
<div>Of course, now that we&#8217;re talking about scope, let&#8217;s look at play time.</div>
<div>
<h2>Play Time</h2>
</div>
<div>
<ul>
<li><i>Jagged Alliance 2</i>: 200+ hours</li>
<li><i>Amplitude</i>: 100-200 hours</li>
<li><i>Super Mario Bros 3</i>: 100-200 hours</li>
<li><i>Scorched Earth</i>: 100-200 hours</li>
<li><i>Deus Ex</i>: 80 hours</li>
<li><i>Grand Theft Auto 3</i>: 80 hours</li>
<li><i>Spelunky</i>: 50 hours playing, 25 hours <a href="http://tinysubversions.blogspot.com/2009/06/game-maker-and-twitter-united-in.html" >modding</a></li>
<li><i>Fallout</i>: 40 hours</li>
<li><i>Maniac Mansion 2: Day of the Tentacle</i>: 30 hours</li>
<li><i>Alpha Centauri</i>: 30 hours</li>
</ul>
<div>In this list I&#8217;m attempting to remember how many hours I spent with each game. This ties back into the whole indie games thing: no matter how much I like a game, it&#8217;s probably not going to change my life if I don&#8217;t spend a lot of time with it. So <i>Spelunky</i> averages about 3 minutes per play session, but I have spent as much time with it as I have with <i>GTA3</i>. Whereas <i>Passage</i> and <i><a href="http://gmc.yoyogames.com/index.php?showtopic=375097" >Execution</a></i> are very important games to me that changed the way I think abotu games, but somehow they don&#8217;t seem so impactful because I played them once or twice and felt like I was done with the experience.</div>
<div></div>
<div>Fun fact: I played through the <i>Jagged Alliance 2</i> demo about three nights a week for a year before the full game came out.</div>
<div>
<h2>Metacritic</h2>
<ul>
<li>97: <i>Grand Theft Auto 3</i></li>
<li>94: <i>Super Mario Bros 3</i></li>
<li>93: <i>Maniac Mansion: Day of the Tentacle</i></li>
<li>92: <i>Alpha Centauri</i></li>
<li>90: <i>Deus Ex</i></li>
<li>89: <i>Fallout</i></li>
<li>86: <i>Amplitude</i></li>
</ul>
<div>Some of the games did not have metacritic scores, and are not included. Some of these games had multiple SKUs, in which case I picked the highest score. It looks like the games that matter to me are also games that the critics love.</div>
<div>
<div>
<h2>Genres and Demographics</h2>
</div>
<div>
<ul>
<li><i>Jagged Alliance 2</i>: tactical combat RPG</li>
<li><i>Amplitude<span class="Apple-style-span"  style="font-style: normal; " >: rhythm action game</span></i></li>
<li><i>Super Mario Bros 3</i>: action platformer</li>
<li><i>Scorched Earth</i>: turn-based artillery</li>
<li><i>Deus Ex</i>: action shooter / RPG</li>
<li><i>Grand Theft Auto 3</i>: sandbox action</li>
<li><i>Spelunky</i>: procedural platformer</li>
<li><i>Fallout</i>: RPG</li>
<li><i>Maniac Mansion 2: Day of the Tentacle</i>: adventure</li>
<li><i>Alpha Centauri</i>: strategy simulation</li>
</ul>
<div>Various stats about the list:</div>
<div>
<ul>
<li>2 platformers</li>
<li>3 RPGs</li>
<li>4 turn-based games</li>
<li>1 first-person game</li>
<li>2 games where you navigate an avatar around a 3D space</li>
<li>5 action games (relying on reflexes to any degree)</li>
<li>9 American games, 1 Japanese game</li>
<li>2 games with puzzle elements</li>
<li>1 game where the puzzle elements are key to the experience</li>
<li>4 &#8220;open world&#8221; games, including Deus Ex</li>
<li>1 game that must be played multiple times through</li>
<li>3 strategy games</li>
<li>7 PC games (were primarily released for PC)</li>
<li>3 console games: 2 PS2, 1 NES</li>
<li>5 games that are continuing titles in a series</li>
<li>2 games that kicked off a series</li>
<li>3 games that stand alone</li>
<li>1 game that loses a lot of value on replay</li>
<li>6 games with strong story elements</li>
<li>4 games where the story is absolutely central to the game</li>
<li>3 games with multiplayer (<i>Deus Ex</i> had a patch but I don&#8217;t count it)</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<p></span></div>
]]></content:encoded>
			<wfw:commentRss>http://tinysubversions.com/2009/06/games-of-my-life/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>

