<?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>Chaos Garden &#187; PHP</title>
	<atom:link href="http://www.chaoseed.com/garden/category/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.chaoseed.com/garden</link>
	<description>Explorations into game design and creativity</description>
	<lastBuildDate>Thu, 15 Jul 2010 22:52:35 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Procedural Generation (the basics)</title>
		<link>http://www.chaoseed.com/garden/2010/04/21/procedural-generation-the-basics/</link>
		<comments>http://www.chaoseed.com/garden/2010/04/21/procedural-generation-the-basics/#comments</comments>
		<pubDate>Wed, 21 Apr 2010 05:27:31 +0000</pubDate>
		<dc:creator>JohnEvans</dc:creator>
				<category><![CDATA[Game Design]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[procedural generation]]></category>

		<guid isPermaLink="false">http://www.chaoseed.com/garden/?p=85</guid>
		<description><![CDATA[The basics of procedural generation.  With code!]]></description>
			<content:encoded><![CDATA[<p><strong>What is procedural generation?</strong></p>
<p>Computer games have a lot of data associated with them; level designs, monster characteristics, items, all sorts of stuff usually referred to as <strong>content</strong>.  Where does this content come from?  Usually the game designers create it, they make it up and polish it to ensure that it meets requirements.</p>
<p>Still, if all your content is &#8220;hand-made&#8221;, that means someone has to make every bit of it.  For some games it&#8217;s more convenient to have the content <em>automatically</em> generated; generated by a procedure.  The process used to create the content is therefore called <strong>procedural generation</strong>.</p>
<p>Some people will refer to &#8220;random&#8221; generation, but there are usually strong constraints on the content produced.</p>
<p><a title="Diablo, the game series (at Wikipedia)" href="http://en.wikipedia.org/wiki/Diablo_%28series%29">The Diablo series of games</a> uses a lot of procedural generation.  In Diablo 2, there are a certain number of levels set in the sewers under a desert town.  Those levels all use &#8220;desert sewer&#8221; graphics, but the layout is procedurally generation for each game.  The tunnel twists and turns are generated, then populated with monsters.  Enemies and treasure chests drop generated treasure hoards featuring magical items with randomly chosen properties.  And there are many more examples in the computer game world.</p>
<p>(I keep talking about games, but I&#8217;m sure procedural generation has applications in other fields.  I just can&#8217;t think of any off the top of my head.)</p>
<p><strong>How To</strong></p>
<p>I&#8217;m going to cover some basic techniques for procedurally generating content.  They won&#8217;t solve every problem, but they&#8217;ll form a good framework for learning more.</p>
<p>The problem</p>
<p>A while back I wrote <a title="Create Randomized Demon Descriptions (at Chaoseed)" href="http://chaoseed.com/demons1.html">a program to generate randomized &#8220;demon&#8221; descriptions</a>.  Inspired by Dungeons &amp; Dragons demons, it produces descriptions of creatures that appear to be assembled from various creatures:</p>
<blockquote><p>Ramalfal is a female demoness, of a quadreped shape, of generally a gray  color.  She has a woman&#8217;s head mounted on the body of a scorpion.</p></blockquote>
<p>For this post I&#8217;ll go through making a (simpler) version of this program.  I&#8217;ll provide some code in PHP.</p>
<p><strong>Pseudorandom seeds</strong></p>
<p>It&#8217;s nearly impossible to create <em>true</em> randomness in computer programs.  Fortunately, nowadays it&#8217;s easy to create randomness that&#8217;s &#8220;good enough&#8221;.  Most languages provide a facility for creating pseudorandom numbers.  Give the number generator a seed, and it will return a string of numbers.  More precisely, there&#8217;s usually a &#8220;seed&#8221; function and a &#8220;rand&#8221; function; after you seed the generator, you call the rand function repeatedly, and you receive a number each time.</p>
<p>Pseudorandom number generators have two useful properties (assuming they&#8217;re working correctly, of course):</p>
<ol>
<li>Each seed generates a different string of numbers.</li>
<li>A specific seed will generate the same string of numbers each time it is used.</li>
</ol>
<p>The point here is that a seed will generate a string of numbers—and thus it will generate the entire passel of content you&#8217;re creating.  In a sense, the content is &#8220;compressed&#8221; into one seed (which is itself just a number).  The end users can trade seeds that they find interesting.  You&#8217;ll notice that the original demon generator uses user-input seeds.</p>
<p>PHP provides the mt_rand() pseudorandom number generator.  You can seed it with the mt_srand() function, although the generator is automatically seeded when mt_rand() is called for the first time.  (One trick programmers use with pseudorandom number generators is to seed them with the current time&#8230;if you find yourself in need of a seed.)</p>
<p><strong>Modular arithmetic</strong></p>
<p>Modular arithmetic is a simple concept, but powerful and useful in certain areas of programming (like this one).  It all has to do with division.  Imagine you&#8217;re dividing two integers; the divisor goes into the dividend a certain number of times, and then often <strong>a bit is left over</strong>.  This amount, the remainder, is the whole point of modular arithmetic.</p>
<p>7 divided by 3 is 2 with a remainder of 1; thus, 7 mod 3 is 1.</p>
<p>321 mod 10 is 1.</p>
<p>It may be easiest to think of it as the face of a clock, disregarding AM or PM.  If the clock says 12:00, and then we wait for 16 hours, what does the clock say?  It says 4, because 16 mod 12 is 4.  Of course, on a clock we have 12, and in modular arithmetic we would use 0.  For modulus 12, we use the numbers 0 to 11, since those are the only possible remainders.</p>
<p>This is important because a lot of times the numbers returned by the random number generator are rather large.  Let&#8217;s say we want to generate the roll of a standard six-sided die, and mt_rand() returns 8714182.  What now?  Well, if we take that number modulus 6, we will get a number from 0 to 5.  Then we can add 1 to get a number from 1 to 6.  (Of course, mt_rand() will take parameters specifying the minimum and maximum number to return.)</p>
<p>Modular arithmetic can be used in a pinch to let you do without random number generators.  If we have an array of five entries, they&#8217;re numbered from 0 to 4.  If we calculate our seed mod 5, we&#8217;ll get an index into the array.  Most programming languages use % for modular arithmetic, like so:</p>
<p><code>$chosen = $array[$seed % 5];</code></p>
<p>In fact, in PHP we don&#8217;t even have to worry about the size of the array, we can just calculate it:</p>
<p><code>$chosen = $array[$seed % count($array)];</code></p>
<p>Relative Primality</p>
<p>Relative primality is another simple concept that can be quite useful in this area.  However, if you&#8217;re really scared off by math, this section is optional.</p>
<p>Two numbers are <strong>relatively prime</strong> if they have <strong>no divisors in common</strong>.</p>
<ul>
<li>15 = 3 * 5.  12 = 3 * 2 * 2.  15 and 12 are not relatively prime, because they&#8217;re both divisible by 3.</li>
<li>15 = 3 * 5.  14 = 2 * 7.  15 and 14 are relatively prime.</li>
</ul>
<p>Let&#8217;s say that instead of using a simple modulus you want to mix things up a bit.  One way to do this is to add a number to your seed, but that just adds a bit of an offset.  A better way is to multiply your seed by a number.  (Combining the methods works well too.)  The one thing to remember is that if you multiplay your seed by a number, the multiplier and the modulus <em>must</em> be relatively prime.</p>
<p>If they aren&#8217;t relatively prime, you&#8217;ll get repeats in your pattern.  Let&#8217;s say we want to ultimately take a modulus of 6; let&#8217;s look at every possible seed in turn; 0, 1, 2 and so on.  They&#8217;ll make a sequence that looks like this:</p>
<p>0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2&#8230;</p>
<p>Now let&#8217;s multiply our seeds by 4.  0, 1, 2 becomes 0, 4, 8, 12, 16, 20, 24&#8230;and we get this:</p>
<p>0, 4, 2, 0, 4, 2, 0&#8230;</p>
<p>Because 6 and 4 are not relatively prime, we get repeats in the pattern.  Some of our elements aren&#8217;t even being used!  Let&#8217;s try multiplying by 5 instead.  0, 5, 10, 15, 20, 25, 30 gives us:</p>
<p>0, 5, 4, 3, 2, 1, 0&#8230;</p>
<p>That pattern might not seem too odd, but notice that <em>every number is represented</em>.  That&#8217;s what&#8217;s really important.</p>
<p><strong>Rerolling</strong></p>
<p>At this point we can make a little program to illustrate our points.  Let&#8217;s think of demons in the form of the head of some creature placed on the body of some other creature.</p>
<p><code>$heads = array("a man", "a woman", "a bird", "a dragon", "an insect");<br />
$bodies = array("a man", "a woman", "a bird", "a dragon", "an insect", "an octopus");<br />
$head = $heads[mt_rand() % count($heads)];<br />
$body = $bodies[mt_rand() % count($bodies)];<br />
$desc = "the head of $head on the body of $body";</code></p>
<p>If we run this program a few times, we&#8217;ll get output like the following:</p>
<p>the head of the man on the body of a dragon</p>
<p>the head of a bird on the body of a woman</p>
<p>the head of an insect on the body of an insect</p>
<p>But wait—that last one seems a bit boring.  We&#8217;re trying to make really bizarre creatures here, so how do we fix that?  One way would be to make sure none of the entries in the heads array match the entries in the bodies array, but that solution has problems.</p>
<p>The best solution is to choose a head, then choose a body; then if the body is unacceptable, choose a <em>different</em> body.  (Or, just keep choosing bodies until we find one that works.)</p>
<p><code>$heads = array("a man", "a woman", "a bird", "a dragon", "an  insect");<br />
$bodies = array("a man", "a woman", "a bird", "a  dragon", "an insect", "an octopus");<br />
$head = $heads[mt_rand() %  count($heads)];<br />
do<br />
{<br />
$body = $bodies[mt_rand() % count($bodies)];<br />
}<br />
while ($body == $head);<br />
$desc  = "the head of $head on the body of $body";</code></p>
<p>(This is one of the few places where I routinely use do/while loops, as opposed to while or for loops.)</p>
<p>I call this technique &#8220;rerolling&#8221; because it&#8217;s like rolling dice to look up entries on a table.</p>
<p><strong>Massaging</strong></p>
<p>This is a slightly more advanced technique that can be useful in some situations.  The original demon generator produces names as well.  These names are assembled from randomly chosen syllables.  However, sometimes the combinations are a little awkward, like &#8220;Ioeththul&#8221;.</p>
<p>The way I dealt with this was to <em>massage</em> the data.  The program replaces awkward letter combinations with better ones.</p>
<ul>
<li>&#8220;io&#8221; at the beginning becomes &#8220;yo&#8221;</li>
<li>&#8220;thth&#8221; becomes &#8220;th&#8221;</li>
</ul>
<p>By these rules, our awkward name becomes the more palatable &#8220;Yothul&#8221;.</p>
<p>The great thing about this technique is that it can produce text that is more intricate than parts assembled together.  The drawback is figuring out appropriate text replacement rules; with the original demons program, I pored over output from it to find names that sounded too awkward.</p>
<p><strong>Emergent Properties</strong></p>
<p>In the same vein as massaging, randomly chosen elements could contribute to characteristics of the final product.  For example, different body parts could add to the demon&#8217;s &#8220;combat rating&#8221;.</p>
<p><code>$head_combat = array("a man" =&gt; 3, "a woman" =&gt; 3, "a bird" =&gt; 0, "a dragon" =&gt; 2, "an   insect" =&gt; 1);<br />
$body_combat = array("a man" =&gt; 1, "a woman" =&gt; 1, "a bird" =&gt; 2, "a  dragon" =&gt; 4, "an insect" =&gt; 3,  "an octopus" =&gt; 1);</code></p>
<p>(Human heads are smarter, thus they&#8217;re more lethal in combat. <img src='http://www.chaoseed.com/garden/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  )</p>
<p>So, after choosing all our parts, we can calculate stats for our demon.</p>
<p><code>$combat = $head_combat[$head] + $body_combat[$body];</code></p>
<p><strong>Culling</strong></p>
<p>Culling is rerolling taken a step further.  If we get to the end of an assemblage of parts and we decide we don&#8217;t like it, we can throw it out and start again.  It&#8217;s possible to do this instead of rerolling, but it&#8217;s best to start over as soon as you know you want to—and only change what&#8217;s necessary.</p>
<p>So why would we have to start over completely?  It would have to do with something that cares about the entire demon, like the combat statistic we just created.  Perhaps there&#8217;s an option on our new demon program that lets users ask for only demons with a certain combat statistic.</p>
<p>The simplest way to implement this is to take everything we&#8217;ve done so far and make it a function.  The main loop (&#8220;generate 100 demons&#8221;) calls the function to get a demon; if the combat statistic is appropriate, it adds the generated demon to the list&#8230;if not, it gets another one.</p>
<p>This approach may seem inefficient, but it has the advantage of being clear, straightforward and easily maintained.  (Just be sure to check that you&#8217;re not trying to create invalid content, like a demon with a combat statistic of 10!)  It would be difficult to write a program to make intelligent choices based on a target statistic&#8230;hardly impossible, of course, just difficult.</p>
<p><strong>In Conclusion</strong></p>
<p>I believe that designing an interesting procedural generation can be a challenge, but <em>implementing</em> it is not that hard.  I hope this post has helped you agree with me!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chaoseed.com/garden/2010/04/21/procedural-generation-the-basics/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP: The GETPOST trick</title>
		<link>http://www.chaoseed.com/garden/2010/04/12/php-the-getpost-trick/</link>
		<comments>http://www.chaoseed.com/garden/2010/04/12/php-the-getpost-trick/#comments</comments>
		<pubDate>Tue, 13 Apr 2010 01:11:10 +0000</pubDate>
		<dc:creator>JohnEvans</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[get]]></category>
		<category><![CDATA[post]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.chaoseed.com/garden/?p=68</guid>
		<description><![CDATA[A PHP trick for treating both GET and POST requests the same when you're processing submitted information.]]></description>
			<content:encoded><![CDATA[<p>With PHP, you often want to process input from forms.  Sometimes GET forms are appropriate, sometimes POST.  But which of those you use is a decision for the input side; when you&#8217;re processing the form information, do you really care if it&#8217;s from GET or POST?  I&#8217;ve found that, while I sometimes want to have the same page accept either GET or POST, I never care <em>which</em> it is.  (If it matters, I include some other parameter to show which action the user is performing.)</p>
<p>Therefore, it would be nice if there were a way to treat the input as &#8220;just an array&#8221; without caring if it&#8217;s GET or POST.  Fortunately, there <em>is</em> a way, a simple one at that.</p>
<pre>$getpost = array_merge((array) $_GET, (array) $_POST);</pre>
<p>This will create an array, <strong>$getpost</strong>, that contains every key and value from both $_GET and $_POST.  It will work even if the arrays are null (assuming you&#8217;re running a recent version of PHP, that is, PHP 5).  Now you can use $getpost to access your submitted form elements without worrying which type of request it was.  There are just a couple of caveats.</p>
<ol>
<li>If your keys are numeric, they may get renumbered.  I don&#8217;t know if it&#8217;s even possible to have form elements with numeric names (and even if it&#8217;s possible, it&#8217;s not a good idea).</li>
<li>If both $_GET and $_POST each have a key with the <em>same name</em>, the latter ($_POST in this case) will be used and the former will be forgotten.  (But is it even possible to have both $_GET and $_POST in one request?)</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.chaoseed.com/garden/2010/04/12/php-the-getpost-trick/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>NecroFodder!</title>
		<link>http://www.chaoseed.com/garden/2008/11/30/necrofodder/</link>
		<comments>http://www.chaoseed.com/garden/2008/11/30/necrofodder/#comments</comments>
		<pubDate>Sun, 30 Nov 2008 23:13:10 +0000</pubDate>
		<dc:creator>JohnEvans</dc:creator>
				<category><![CDATA[Game Design]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web-Based Games]]></category>
		<category><![CDATA[competition]]></category>
		<category><![CDATA[games]]></category>
		<category><![CDATA[necrofodder]]></category>
		<category><![CDATA[tigsource]]></category>

		<guid isPermaLink="false">http://www.chaoseed.com/garden/?p=29</guid>
		<description><![CDATA[As hinted at in an earlier post, I&#8217;ve created a new web-based game: NecroFodder!  It&#8217;s intended to be quick-playing but with some strategy involved as well.  Go check it out!  (It was created for the TIGSource Commonplace Book Competition.) In other news&#8230;I&#8217;ve been getting a huge number of spam comments on this blog.  Fortunately, the [...]]]></description>
			<content:encoded><![CDATA[<p>As hinted at in an earlier post, I&#8217;ve created a new web-based game: <a title="NecroFodder" href="http://chaoseed.com/necro">NecroFodder</a>!  It&#8217;s intended to be quick-playing but with some strategy involved as well.  Go check it out!  (It was created for the <a title="TIGSource Commonplace Book Competition" href="http://tigsource.com/articles/2008/10/17/tigcompo-commonplace-book">TIGSource Commonplace Book Competition</a>.)</p>
<p>In other news&#8230;I&#8217;ve been getting a huge number of spam comments on this blog.  Fortunately, the WordPress software makes it easy to deal with them, so you guys never see them&#8230;But it still greatly puzzles me. O_o</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chaoseed.com/garden/2008/11/30/necrofodder/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaScript</title>
		<link>http://www.chaoseed.com/garden/2008/11/10/javascript/</link>
		<comments>http://www.chaoseed.com/garden/2008/11/10/javascript/#comments</comments>
		<pubDate>Tue, 11 Nov 2008 03:22:22 +0000</pubDate>
		<dc:creator>JohnEvans</dc:creator>
				<category><![CDATA[Events]]></category>
		<category><![CDATA[Game Design]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web-Based Games]]></category>
		<category><![CDATA[competition]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[necrofodder]]></category>
		<category><![CDATA[tigsource]]></category>

		<guid isPermaLink="false">http://www.chaoseed.com/garden/?p=27</guid>
		<description><![CDATA[Today I looked into learning JavaScript.  Basically it&#8217;s a weakly-typed declarative/functional language with a couple object-oriented features for good measure, much in the line of PHP or Perl.  The interesting part, though, is the &#8220;HTML DOM&#8221;, a set of objects that allows JavaScript to access and manipulate the web page it&#8217;s a part of.  I [...]]]></description>
			<content:encoded><![CDATA[<p>Today I looked into learning JavaScript.  Basically it&#8217;s a weakly-typed declarative/functional language with a couple object-oriented features for good measure, much in the line of PHP or Perl.  The interesting part, though, is the &#8220;HTML DOM&#8221;, a set of objects that allows JavaScript to access and manipulate the web page it&#8217;s a part of.  I went into this project looking to learn automatic form validation, and I&#8217;ve figured that out.  Even that much may allow me to add new features to my web-based games.</p>
<p>Speaking of web-based games, I had an idea for another little project for <a title="TIGSource Commonplace Book Competition" href="http://forums.tigsource.com/index.php?topic=3286.0">the TIGSource Commonplace Book Competition</a>.  I&#8217;m calling it &#8220;NecroFodder&#8221;.  We&#8217;ll see if anything comes of it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chaoseed.com/garden/2008/11/10/javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Recent Project Work</title>
		<link>http://www.chaoseed.com/garden/2008/10/27/recent-project-work/</link>
		<comments>http://www.chaoseed.com/garden/2008/10/27/recent-project-work/#comments</comments>
		<pubDate>Mon, 27 Oct 2008 09:48:57 +0000</pubDate>
		<dc:creator>JohnEvans</dc:creator>
				<category><![CDATA[Events]]></category>
		<category><![CDATA[Fiction Writing]]></category>
		<category><![CDATA[Game Design]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Secret Projects]]></category>
		<category><![CDATA[args]]></category>
		<category><![CDATA[competition]]></category>
		<category><![CDATA[fiction]]></category>
		<category><![CDATA[halloween]]></category>
		<category><![CDATA[inform]]></category>
		<category><![CDATA[Interactive Fiction]]></category>
		<category><![CDATA[secret project 1]]></category>
		<category><![CDATA[secret project 2]]></category>
		<category><![CDATA[tigsource]]></category>
		<category><![CDATA[writing]]></category>

		<guid isPermaLink="false">http://www.chaoseed.com/garden/?p=25</guid>
		<description><![CDATA[So, recently I completed writing a long&#8230;well, I guess you&#8217;d call it a short story, or maybe even a chapter of a novella. And now that that&#8217;s out of the way, I can get on with doing other cool stuff. (It had sort of been weighing on my mind for a while.) I&#8217;m doing more [...]]]></description>
			<content:encoded><![CDATA[<p>So, recently I completed writing a long&#8230;well, I guess you&#8217;d call it a short story, or maybe even a chapter of a novella. And now that that&#8217;s out of the way, I can get on with doing other cool stuff. (It had sort of been weighing on my mind for a while.)</p>
<p>I&#8217;m doing more PHP work on secret projects, and I&#8217;m also working in <a title="Inform" href="http://inform-fiction.org">Inform</a> on a project for the <a title="The TIGSource Commonplace Book Competition" href="http://tigsource.com/articles/2008/10/17/tigcompo-commonplace-book">TIGSource Commonplace Book Competition</a>. (I&#8217;m actually working in Inform 6; it&#8217;s more programmer-oriented than Inform 7, but hey, I&#8217;m a programmer! And it&#8217;s what I learned. Maybe someday I&#8217;ll learn 7.) I bet I&#8217;ll even be able to finish this one for Halloween.</p>
<p>Oh, yes, Halloween. I always want to have something&#8230;<em>special</em> happen for Halloween. We&#8217;ll see what I can <em>*ahem*</em> dig up.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chaoseed.com/garden/2008/10/27/recent-project-work/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Secret Project 2, Nethack</title>
		<link>http://www.chaoseed.com/garden/2008/07/06/secret-project-2-nethack/</link>
		<comments>http://www.chaoseed.com/garden/2008/07/06/secret-project-2-nethack/#comments</comments>
		<pubDate>Sun, 06 Jul 2008 06:31:52 +0000</pubDate>
		<dc:creator>JohnEvans</dc:creator>
				<category><![CDATA[Game Design]]></category>
		<category><![CDATA[PC Games]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Secret Projects]]></category>
		<category><![CDATA[Web-Based Games]]></category>
		<category><![CDATA[building]]></category>
		<category><![CDATA[dwarf fortress]]></category>
		<category><![CDATA[nethack]]></category>
		<category><![CDATA[secret project 2]]></category>

		<guid isPermaLink="false">http://www.chaoseed.com/garden/?p=19</guid>
		<description><![CDATA[So&#8230;more work on, er, Secret Project 2. Yep. Today I had a thought. Dwarf Fortress is kind of a roguelike, isn&#8217;t it? I like its emphasis on construction. And Nethack is basically open source. Hmmm&#8230;]]></description>
			<content:encoded><![CDATA[<p>So&#8230;more work on, er, Secret Project 2. Yep.</p>
<p>Today I had a thought. <a title="Dwarf Fortress" href="http://www.bay12games.com/dwarves/">Dwarf Fortress</a> is kind of a roguelike, isn&#8217;t it? I like its emphasis on construction. And <a title="Nethack" href="http://nethack.org/">Nethack</a> is basically <a title="Nethack License" href="http://nethack.org/common/license.html">open source</a>. Hmmm&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chaoseed.com/garden/2008/07/06/secret-project-2-nethack/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Critique of MyMiniCity; Also, cool PHP bricolage</title>
		<link>http://www.chaoseed.com/garden/2008/06/13/a-critique-of-myminicity-also-cool-php-bricolage/</link>
		<comments>http://www.chaoseed.com/garden/2008/06/13/a-critique-of-myminicity-also-cool-php-bricolage/#comments</comments>
		<pubDate>Fri, 13 Jun 2008 06:30:17 +0000</pubDate>
		<dc:creator>JohnEvans</dc:creator>
				<category><![CDATA[Game Critique]]></category>
		<category><![CDATA[Game Design]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web-Based Games]]></category>
		<category><![CDATA[bricolage]]></category>
		<category><![CDATA[miniville]]></category>
		<category><![CDATA[motion-twin]]></category>
		<category><![CDATA[myminicity]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[procedural generation]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://www.chaoseed.com/garden/?p=10</guid>
		<description><![CDATA[So, if you&#8217;re not familiar with MyMiniCity, you might want to check it out. I think it&#8217;s a rather clever idea. The basic &#8220;play&#8221; of MyMiniCity goes as follows. Create a city. This gives you a subdomain, like http://cobweb.myminicity.com (Full disclosure: It&#8217;s a city I started). Each city page has a neat little Flash map [...]]]></description>
			<content:encoded><![CDATA[<p>So, if you&#8217;re not familiar with <a title="MyMiniCity" href="http://myminicity.com">MyMiniCity</a>, you might want to check it out. I think it&#8217;s a rather clever idea.</p>
<p>The basic &#8220;play&#8221; of MyMiniCity goes as follows.</p>
<ul>
<li>Create a city. This gives you a subdomain, like <a title="Cobweb Castle - MyMiniCity" href="http://cobweb.myminicity.com">http://cobweb.myminicity.com</a> (Full disclosure: It&#8217;s a city I started). Each city page has a neat little Flash map of the city in isometric perspective, procedurally generated based on the city&#8217;s stats.</li>
<li>Use the various URLs to improve aspects of your city. Going to the &#8220;bare&#8221; URL will increase its population. Once your population passes certain milestones, you can improve different aspects. For example, when you reach 50 inhabitants you can improve industry, using a URL like this: <a title="Cobweb Castle - MyMiniCity - Industry" href="http://cobweb.myminicity.com/ind">http://cobweb.myminicity.com/ind</a></li>
<li>The first interesting thing is that the &#8220;improvements&#8221; need to come in a certain order. As your city&#8217;s population grows, it requires industry, security, etc.. If you don&#8217;t have enough industry, your unemployment rate will be high, and people will eventually leave your city to look for jobs elsewhere (decreasing population). If there&#8217;s low security, there&#8217;s high crime, and businesses leave. I don&#8217;t know all the relationships yet, but the point is that if you blindly go to the &#8220;base&#8221; URL over and over to increase population, you&#8217;ll eventually hit a point where it just doesn&#8217;t work. (Of course, there are city statistics that will tell you how far off you are from your targets, warning you when you&#8217;re a few points away from danger.)</li>
<li>The other really interesting thing is that <strong>anyone</strong> can visit these URLs, but you they only have an effect if they&#8217;re the first person to visit that city from that IP address on that day. (Given that <a title="Motion-Twin" href="http://motion-twin.com">Motion-Twin</a> is in France, the day &#8220;resets&#8221; at around 6PM eastern US time.)</li>
</ul>
<p>This website visiting &#8220;mechanic&#8221; is unique as far as I know. (Well, there&#8217;s <a title="Graaaagh - Eat Brains" href="http://kevan.org/brainfaq.html">Graaaagh</a> and its derivatives, but the &#8220;one IP every 24 hours&#8221; is a wrinkle I haven&#8217;t seen elsewhere.) This has a few interesting consequences.</p>
<ul>
<li>First, you want to recruit people to visit your city&#8217;s link.</li>
<li> That is, visit it <em>every day</em>.</li>
<li>However, you don&#8217;t want people blindly visiting the population link. You have to organize them somehow so that they go to industry, or security, or environment&#8230;whatever your city most needs at that particular time. And this need could possibly change <em>with every visit by anyone</em>.</li>
<li>The final really interesting thing about MyMiniCity is that <strong>there are no passwords or other way to have &#8220;ownership&#8221; of a city</strong>. When you visit &#8220;your&#8221; city with one of the improvement URLs, you&#8217;re just like any random person on the internet clicking on a city link.</li>
</ul>
<p>Now this surprised me when I first realized it. &#8220;Why can&#8217;t I log in and do special owner-only actions?&#8221; The truth is that there are no owner-only actions. The only actions available in the game are available to anyone. This is basically accomplished by removing choice from the game; either you get your city to develop well, or you don&#8217;t. Sometimes there are times when you&#8217;d say &#8220;Oh, I shouldn&#8217;t have done that, I should have done something else instead&#8221;. However, there are <em>no</em> times when you say &#8220;Hey, I wanted to do something else because I wanted to try out a different alternative!&#8221;. There are really no other alternatives, just forward or not-forward.</p>
<p>(Actually, I have heard that it&#8217;s possible to somehow &#8220;attack&#8221; someone&#8217;s city and drive their population down, but I don&#8217;t know how that works. I suspect it only works on really huge cities, anyway.)</p>
<p>So, because there are no alternatives, there are no real choices&#8230;So it doesn&#8217;t matter if everyone else can do the same set of things to your city. I say &#8220;no real choices&#8221;, but what I mean is that all the choices are more like skill tests; you can choose among different options, but they are definitely &#8220;right&#8221; or &#8220;wrong&#8221;, there are no valid alternate strategies.</p>
<p>Some of you may be thinking &#8220;Well, I&#8217;d just organize a website with a bunch of friends recruiting people to click on these links&#8221;. And that&#8217;s just what people have done. I found a couple sites, just out of curiosity, but I didn&#8217;t feel like exploring them very much (Google will show you, I&#8217;m sure). One important aspect of this<br />
&#8220;link recruiting&#8221; is that you need a way to generate the <em>appropriate</em> link for people to visit. You might think that this is a confusing matter of caching the results shown on the page.</p>
<p>However, Motion-Twin has provided a feature to facilitate this very calculation and other bits of bricolage. If you append &#8220;xml&#8221; to your city URL, like this:</p>
<p><a title="Cobweb Castle - MyMiniCity - XML" href="http://cobweb.myminicity.com/xml">http://cobweb.myminicity.com/xml</a></p>
<p>&#8230;you will see an XML page describing your city&#8217;s stats. It&#8217;s important to note that visiting this page has <em>no</em> effect on the city, not changing the stats nor using up the daily visit. It&#8217;s simply a bit of information that you can use to learn about a city. (Besides the &#8220;link calculation&#8221; facility, I can imagine someone writing, say, a <a title="Facebook: Developers" href="http://developers.facebook.com">Facebook app</a> that says &#8220;I&#8217;ve got a city with these stats! Click on it to do stuff!&#8221;.)</p>
<p>So, I&#8217;ve written my own <a title="PHP" href="http://php.net">PHP</a> script to perform this calculation.</p>
<p><a title="Chaoseed Miniauto v.2" href="http://www.chaoseed.com/miniaut2.php">http://www.chaoseed.com/miniaut2.php</a></p>
<p>It should be easy to use. As the &#8220;documentation&#8221; says, you can give it a parameter to make a URL you can bookmark and visit every day:</p>
<p><a title="Chaoseed Miniauto v.2 - Cobweb Castle" href="http://www.chaoseed.com/miniaut2.php?queryname=cobweb">http://www.chaoseed.com/miniaut2.php?queryname=cobweb</a></p>
<p>If you&#8217;re interested in learning how I did it, I&#8217;ve got the source of the script here.</p>
<p><a title="Chaoseed Miniauto v.2 - Source (PHP)" href="http://www.chaoseed.com/miniaut2.txt">http://www.chaoseed.com/miniaut2.txt</a></p>
<p>You can consider this &#8220;open source&#8221;, I don&#8217;t really care what happens to the code. It&#8217;s so simple, and lots of other people have written stuff like this already&#8230;If you can find a way to sell it for money, more power to you. I&#8217;m just posting it here because I&#8217;m proud of learning how PHP works, the script has got some nice heredocs and bracket syntax in quoted strings.</p>
<p>And one other thing about this script&#8230;I&#8217;ve segregated all the MyMiniCity-specific data into one area. It would be easy to write a script that took a different set of data but did similar calculations. &#8220;garrison&#8221; instead of &#8220;security&#8221;, perhaps. You could almost make it into a library. Of course, that would require another web-based game similar to MyMiniCity&#8230;</p>
<p><strong>Edit June 15th</strong>: It turns out that the &#8220;original&#8221; version of MyMiniCity is <a title="MiniVille" href="http://miniville.fr">Miniville</a>. It seems to be exactly the same thing, only in French and with a slightly different ranking system. (You site your city within a province of France, rather than a country in the world.)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chaoseed.com/garden/2008/06/13/a-critique-of-myminicity-also-cool-php-bricolage/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
